From 401e8172b8187d101f072fd88a09686471bd35d2 Mon Sep 17 00:00:00 2001 From: Matthew James Briggs Date: Wed, 16 Sep 2026 21:12:22 +0200 Subject: [PATCH 1/8] feat: report non-fatal import diagnostics The generated core parsers repair values silently: an unknown enum literal falls back to the first variant, numbers are clamped into range, unreadable text becomes a default, and a missing lyric-language/@xml:lang becomes "und". Carry a ParseContext through every generated parser and report those repairs with their XML path. Value types gain a parse overload that says whether the text was invalid or adjusted, so valid alternate spellings are not reported. MusicXml::fromFile and fromStream take an optional Diagnostics that the same collector can then pass to getScore. Parsing produces the same document either way. --- CMakeLists.txt | 10 +- gen/cpp/templates/attr_parse_expr.tmpl | 2 +- gen/cpp/templates/attributes_parse.tmpl | 1 + gen/cpp/templates/attrs.cpp.tmpl | 14 +- gen/cpp/templates/attrs.h.tmpl | 6 + gen/cpp/templates/choice.cpp.tmpl | 14 +- gen/cpp/templates/choice.h.tmpl | 4 + gen/cpp/templates/choice_boxed.cpp.tmpl | 8 +- gen/cpp/templates/choice_boxed.h.tmpl | 4 + gen/cpp/templates/composite.cpp.tmpl | 13 +- gen/cpp/templates/composite.h.tmpl | 6 + gen/cpp/templates/derived.cpp.tmpl | 8 +- gen/cpp/templates/derived.h.tmpl | 4 + gen/cpp/templates/document.cpp.tmpl | 8 +- gen/cpp/templates/document.h.tmpl | 4 + gen/cpp/templates/empty.cpp.tmpl | 14 +- gen/cpp/templates/empty.h.tmpl | 6 + gen/cpp/templates/enum.cpp.tmpl | 8 +- gen/cpp/templates/enum.h.tmpl | 5 + gen/cpp/templates/field_parse_expr.tmpl | 2 +- gen/cpp/templates/fields_parse.tmpl | 12 +- gen/cpp/templates/group.cpp.tmpl | 6 + gen/cpp/templates/group.h.tmpl | 4 + gen/cpp/templates/number.cpp.tmpl | 39 +++-- gen/cpp/templates/number.h.tmpl | 4 + gen/cpp/templates/string.cpp.tmpl | 7 + gen/cpp/templates/string.h.tmpl | 5 + gen/cpp/templates/union.cpp.tmpl | 24 +++ gen/cpp/templates/union.h.tmpl | 5 + gen/cpp/templates/value_class.cpp.tmpl | 15 +- gen/cpp/templates/value_class.h.tmpl | 6 + src/include/mx/api/Diagnostics.h | 6 +- src/include/mx/api/MusicXml.h | 9 ++ src/private/mx/api/MusicXml.cpp | 42 ++++- src/private/mx/core/Lexical.h | 9 ++ src/private/mx/core/ParseContext.cpp | 77 +++++++++ src/private/mx/core/ParseContext.h | 86 ++++++++++ src/private/mx/core/generated/AboveBelow.cpp | 8 +- src/private/mx/core/generated/AboveBelow.h | 5 + src/private/mx/core/generated/Accidental.cpp | 45 ++++-- src/private/mx/core/generated/Accidental.h | 6 + .../mx/core/generated/AccidentalMark.cpp | 43 +++-- .../mx/core/generated/AccidentalMark.h | 6 + .../mx/core/generated/AccidentalText.cpp | 57 ++++--- .../mx/core/generated/AccidentalText.h | 6 + .../mx/core/generated/AccidentalValue.cpp | 8 +- .../mx/core/generated/AccidentalValue.h | 5 + src/private/mx/core/generated/Accord.cpp | 17 +- src/private/mx/core/generated/Accord.h | 6 + .../mx/core/generated/AccordionMiddle.cpp | 25 ++- .../mx/core/generated/AccordionMiddle.h | 5 + .../core/generated/AccordionRegistration.cpp | 41 +++-- .../mx/core/generated/AccordionRegistration.h | 6 + .../mx/core/generated/AllMarginsGroup.cpp | 12 +- .../mx/core/generated/AllMarginsGroup.h | 4 + src/private/mx/core/generated/Appearance.cpp | 23 ++- src/private/mx/core/generated/Appearance.h | 6 + src/private/mx/core/generated/Arpeggiate.cpp | 32 ++-- src/private/mx/core/generated/Arpeggiate.h | 6 + src/private/mx/core/generated/Arrow.cpp | 37 +++-- src/private/mx/core/generated/Arrow.h | 6 + src/private/mx/core/generated/ArrowChoice.cpp | 10 +- src/private/mx/core/generated/ArrowChoice.h | 4 + .../mx/core/generated/ArrowChoiceGroup.cpp | 12 +- .../mx/core/generated/ArrowChoiceGroup.h | 4 + .../mx/core/generated/ArrowDirection.cpp | 8 +- .../mx/core/generated/ArrowDirection.h | 5 + src/private/mx/core/generated/ArrowStyle.cpp | 8 +- src/private/mx/core/generated/ArrowStyle.h | 5 + .../mx/core/generated/Articulations.cpp | 15 +- src/private/mx/core/generated/Articulations.h | 6 + .../mx/core/generated/ArticulationsChoice.cpp | 40 +++-- .../mx/core/generated/ArticulationsChoice.h | 4 + src/private/mx/core/generated/Assess.cpp | 18 ++- src/private/mx/core/generated/Assess.h | 6 + src/private/mx/core/generated/Attributes.cpp | 37 +++-- src/private/mx/core/generated/Attributes.h | 6 + .../mx/core/generated/AttributesChoice.cpp | 10 +- .../mx/core/generated/AttributesChoice.h | 4 + src/private/mx/core/generated/Backup.cpp | 17 +- src/private/mx/core/generated/Backup.h | 6 + .../mx/core/generated/BackwardForward.cpp | 8 +- .../mx/core/generated/BackwardForward.h | 5 + src/private/mx/core/generated/BarStyle.cpp | 8 +- src/private/mx/core/generated/BarStyle.h | 5 + .../mx/core/generated/BarStyleColor.cpp | 17 +- src/private/mx/core/generated/BarStyleColor.h | 6 + src/private/mx/core/generated/Barline.cpp | 33 ++-- src/private/mx/core/generated/Barline.h | 6 + src/private/mx/core/generated/Barre.cpp | 18 ++- src/private/mx/core/generated/Barre.h | 6 + src/private/mx/core/generated/Bass.cpp | 21 ++- src/private/mx/core/generated/Bass.h | 6 + src/private/mx/core/generated/BassStep.cpp | 33 ++-- src/private/mx/core/generated/BassStep.h | 6 + src/private/mx/core/generated/Beam.cpp | 23 ++- src/private/mx/core/generated/Beam.h | 6 + src/private/mx/core/generated/BeamLevel.cpp | 25 ++- src/private/mx/core/generated/BeamLevel.h | 5 + src/private/mx/core/generated/BeamValue.cpp | 8 +- src/private/mx/core/generated/BeamValue.h | 5 + src/private/mx/core/generated/BeatRepeat.cpp | 21 ++- src/private/mx/core/generated/BeatRepeat.h | 6 + .../mx/core/generated/BeatUnitGroup.cpp | 10 +- src/private/mx/core/generated/BeatUnitGroup.h | 4 + .../mx/core/generated/BeatUnitTied.cpp | 15 +- src/private/mx/core/generated/BeatUnitTied.h | 6 + src/private/mx/core/generated/Beater.cpp | 17 +- src/private/mx/core/generated/Beater.h | 6 + src/private/mx/core/generated/BeaterValue.cpp | 8 +- src/private/mx/core/generated/BeaterValue.h | 5 + src/private/mx/core/generated/Bend.cpp | 47 +++--- src/private/mx/core/generated/Bend.h | 6 + src/private/mx/core/generated/BendChoice.cpp | 10 +- src/private/mx/core/generated/BendChoice.h | 4 + src/private/mx/core/generated/BendShape.cpp | 8 +- src/private/mx/core/generated/BendShape.h | 5 + src/private/mx/core/generated/Bookmark.cpp | 16 +- src/private/mx/core/generated/Bookmark.h | 6 + src/private/mx/core/generated/Bracket.cpp | 38 +++-- src/private/mx/core/generated/Bracket.h | 6 + src/private/mx/core/generated/BreathMark.cpp | 35 ++-- src/private/mx/core/generated/BreathMark.h | 6 + .../mx/core/generated/BreathMarkValue.cpp | 8 +- .../mx/core/generated/BreathMarkValue.h | 5 + src/private/mx/core/generated/CSSFontSize.cpp | 8 +- src/private/mx/core/generated/CSSFontSize.h | 5 + src/private/mx/core/generated/Caesura.cpp | 35 ++-- src/private/mx/core/generated/Caesura.h | 6 + .../mx/core/generated/CaesuraValue.cpp | 8 +- src/private/mx/core/generated/CaesuraValue.h | 5 + src/private/mx/core/generated/Cancel.cpp | 17 +- src/private/mx/core/generated/Cancel.h | 6 + .../mx/core/generated/CancelLocation.cpp | 8 +- .../mx/core/generated/CancelLocation.h | 5 + .../mx/core/generated/CircularArrow.cpp | 8 +- src/private/mx/core/generated/CircularArrow.h | 5 + src/private/mx/core/generated/Clef.cpp | 43 +++-- src/private/mx/core/generated/Clef.h | 6 + src/private/mx/core/generated/ClefGroup.cpp | 12 +- src/private/mx/core/generated/ClefGroup.h | 4 + src/private/mx/core/generated/ClefSign.cpp | 8 +- src/private/mx/core/generated/ClefSign.h | 5 + src/private/mx/core/generated/Coda.cpp | 38 +++-- src/private/mx/core/generated/Coda.h | 6 + src/private/mx/core/generated/Credit.cpp | 21 ++- src/private/mx/core/generated/Credit.h | 6 + .../mx/core/generated/CreditChoice.cpp | 10 +- src/private/mx/core/generated/CreditChoice.h | 4 + .../mx/core/generated/CreditChoiceGroup.cpp | 10 +- .../mx/core/generated/CreditChoiceGroup.h | 4 + .../generated/CreditChoiceGroupChoice.cpp | 11 +- .../core/generated/CreditChoiceGroupChoice.h | 5 + .../core/generated/CreditChoiceGroupGroup.cpp | 13 +- .../core/generated/CreditChoiceGroupGroup.h | 5 + .../CreditChoiceGroupGroupChoice.cpp | 11 +- .../generated/CreditChoiceGroupGroupChoice.h | 5 + .../mx/core/generated/CueNoteGroup.cpp | 12 +- src/private/mx/core/generated/CueNoteGroup.h | 4 + src/private/mx/core/generated/Dashes.cpp | 32 ++-- src/private/mx/core/generated/Dashes.h | 6 + src/private/mx/core/generated/Defaults.cpp | 29 ++-- src/private/mx/core/generated/Defaults.h | 6 + src/private/mx/core/generated/Degree.cpp | 21 ++- src/private/mx/core/generated/Degree.h | 6 + src/private/mx/core/generated/DegreeAlter.cpp | 35 ++-- src/private/mx/core/generated/DegreeAlter.h | 6 + .../mx/core/generated/DegreeSymbolValue.cpp | 8 +- .../mx/core/generated/DegreeSymbolValue.h | 5 + src/private/mx/core/generated/DegreeType.cpp | 33 ++-- src/private/mx/core/generated/DegreeType.h | 6 + .../mx/core/generated/DegreeTypeValue.cpp | 8 +- .../mx/core/generated/DegreeTypeValue.h | 5 + src/private/mx/core/generated/DegreeValue.cpp | 35 ++-- src/private/mx/core/generated/DegreeValue.h | 6 + src/private/mx/core/generated/Direction.cpp | 33 ++-- src/private/mx/core/generated/Direction.h | 6 + .../mx/core/generated/DirectionType.cpp | 15 +- src/private/mx/core/generated/DirectionType.h | 6 + .../mx/core/generated/DirectionTypeChoice.cpp | 64 ++++---- .../mx/core/generated/DirectionTypeChoice.h | 4 + .../generated/DirectionTypeChoiceChoice.cpp | 11 +- .../generated/DirectionTypeChoiceChoice.h | 5 + src/private/mx/core/generated/Directive.cpp | 31 ++-- src/private/mx/core/generated/Directive.h | 6 + .../core/generated/DisplayStepOctaveGroup.cpp | 11 +- .../core/generated/DisplayStepOctaveGroup.h | 5 + src/private/mx/core/generated/Distance.cpp | 17 +- src/private/mx/core/generated/Distance.h | 6 + .../mx/core/generated/DistanceType.cpp | 7 + src/private/mx/core/generated/DistanceType.h | 5 + src/private/mx/core/generated/Divisions.cpp | 25 ++- src/private/mx/core/generated/Divisions.h | 4 + src/private/mx/core/generated/Document.cpp | 10 +- src/private/mx/core/generated/Document.h | 4 + src/private/mx/core/generated/Double.cpp | 16 +- src/private/mx/core/generated/Double.h | 6 + src/private/mx/core/generated/Dynamics.cpp | 47 +++--- src/private/mx/core/generated/Dynamics.h | 6 + .../mx/core/generated/DynamicsChoice.cpp | 60 +++---- .../mx/core/generated/DynamicsChoice.h | 4 + .../mx/core/generated/EditorialGroup.cpp | 10 +- .../mx/core/generated/EditorialGroup.h | 4 + .../EditorialVoiceDirectionGroup.cpp | 11 +- .../generated/EditorialVoiceDirectionGroup.h | 5 + .../mx/core/generated/EditorialVoiceGroup.cpp | 10 +- .../mx/core/generated/EditorialVoiceGroup.h | 4 + src/private/mx/core/generated/Effect.cpp | 17 +- src/private/mx/core/generated/Effect.h | 6 + src/private/mx/core/generated/EffectValue.cpp | 8 +- src/private/mx/core/generated/EffectValue.h | 5 + src/private/mx/core/generated/Elision.cpp | 25 ++- src/private/mx/core/generated/Elision.h | 6 + .../core/generated/ElisionSyllabicGroup.cpp | 10 +- .../mx/core/generated/ElisionSyllabicGroup.h | 4 + src/private/mx/core/generated/Empty.cpp | 14 +- src/private/mx/core/generated/Empty.h | 6 + src/private/mx/core/generated/EmptyFont.cpp | 22 ++- src/private/mx/core/generated/EmptyFont.h | 6 + src/private/mx/core/generated/EmptyLine.cpp | 44 +++-- src/private/mx/core/generated/EmptyLine.h | 6 + .../mx/core/generated/EmptyPlacement.cpp | 34 ++-- .../mx/core/generated/EmptyPlacement.h | 6 + .../mx/core/generated/EmptyPlacementSmufl.cpp | 36 +++-- .../mx/core/generated/EmptyPlacementSmufl.h | 6 + .../generated/EmptyPrintObjectStyleAlign.cpp | 39 +++-- .../generated/EmptyPrintObjectStyleAlign.h | 7 + .../core/generated/EmptyPrintStyleAlignID.cpp | 36 +++-- .../core/generated/EmptyPrintStyleAlignID.h | 6 + .../mx/core/generated/EmptyTrillSound.cpp | 48 +++--- .../mx/core/generated/EmptyTrillSound.h | 6 + .../mx/core/generated/EnclosureShape.cpp | 8 +- .../mx/core/generated/EnclosureShape.h | 5 + src/private/mx/core/generated/Encoding.cpp | 15 +- src/private/mx/core/generated/Encoding.h | 6 + .../mx/core/generated/EncodingChoice.cpp | 12 +- .../mx/core/generated/EncodingChoice.h | 4 + src/private/mx/core/generated/Ending.cpp | 45 ++++-- src/private/mx/core/generated/Ending.h | 6 + src/private/mx/core/generated/Extend.cpp | 26 ++- src/private/mx/core/generated/Extend.h | 6 + src/private/mx/core/generated/Fan.cpp | 8 +- src/private/mx/core/generated/Fan.h | 5 + src/private/mx/core/generated/Feature.cpp | 13 +- src/private/mx/core/generated/Feature.h | 6 + src/private/mx/core/generated/Fermata.cpp | 35 ++-- src/private/mx/core/generated/Fermata.h | 6 + .../mx/core/generated/FermataShape.cpp | 8 +- src/private/mx/core/generated/FermataShape.h | 5 + src/private/mx/core/generated/Fifths.cpp | 25 ++- src/private/mx/core/generated/Fifths.h | 5 + src/private/mx/core/generated/Figure.cpp | 23 ++- src/private/mx/core/generated/Figure.h | 6 + src/private/mx/core/generated/FiguredBass.cpp | 55 ++++--- src/private/mx/core/generated/FiguredBass.h | 6 + src/private/mx/core/generated/Fingering.cpp | 37 +++-- src/private/mx/core/generated/Fingering.h | 6 + src/private/mx/core/generated/FirstFret.cpp | 17 +- src/private/mx/core/generated/FirstFret.h | 6 + src/private/mx/core/generated/FontSize.cpp | 8 + src/private/mx/core/generated/FontSize.h | 5 + src/private/mx/core/generated/FontStyle.cpp | 8 +- src/private/mx/core/generated/FontStyle.h | 5 + src/private/mx/core/generated/FontWeight.cpp | 8 +- src/private/mx/core/generated/FontWeight.h | 5 + src/private/mx/core/generated/ForPart.cpp | 19 ++- src/private/mx/core/generated/ForPart.h | 6 + .../mx/core/generated/FormattedSymbolID.cpp | 55 ++++--- .../mx/core/generated/FormattedSymbolID.h | 6 + .../mx/core/generated/FormattedText.cpp | 53 +++--- src/private/mx/core/generated/FormattedText.h | 6 + .../mx/core/generated/FormattedTextID.cpp | 53 +++--- .../mx/core/generated/FormattedTextID.h | 6 + src/private/mx/core/generated/Forward.cpp | 19 ++- src/private/mx/core/generated/Forward.h | 6 + src/private/mx/core/generated/Frame.cpp | 41 +++-- src/private/mx/core/generated/Frame.h | 6 + src/private/mx/core/generated/FrameNote.cpp | 21 ++- src/private/mx/core/generated/FrameNote.h | 6 + src/private/mx/core/generated/Fret.cpp | 25 ++- src/private/mx/core/generated/Fret.h | 6 + .../mx/core/generated/FullNoteGroup.cpp | 10 +- src/private/mx/core/generated/FullNoteGroup.h | 4 + .../mx/core/generated/FullNoteGroupChoice.cpp | 12 +- .../mx/core/generated/FullNoteGroupChoice.h | 4 + src/private/mx/core/generated/Glass.cpp | 17 +- src/private/mx/core/generated/Glass.h | 6 + src/private/mx/core/generated/GlassValue.cpp | 8 +- src/private/mx/core/generated/GlassValue.h | 5 + src/private/mx/core/generated/Glissando.cpp | 41 +++-- src/private/mx/core/generated/Glissando.h | 6 + src/private/mx/core/generated/Glyph.cpp | 17 +- src/private/mx/core/generated/Glyph.h | 6 + src/private/mx/core/generated/GlyphType.cpp | 7 + src/private/mx/core/generated/GlyphType.h | 5 + src/private/mx/core/generated/Grace.cpp | 22 ++- src/private/mx/core/generated/Grace.h | 6 + .../mx/core/generated/GraceCueNoteGroup.cpp | 10 +- .../mx/core/generated/GraceCueNoteGroup.h | 4 + .../core/generated/GraceNormalNoteGroup.cpp | 10 +- .../mx/core/generated/GraceNormalNoteGroup.h | 4 + .../mx/core/generated/GraceNoteChoice.cpp | 10 +- .../mx/core/generated/GraceNoteChoice.h | 4 + .../mx/core/generated/GraceNoteGroup.cpp | 10 +- .../mx/core/generated/GraceNoteGroup.h | 4 + .../mx/core/generated/GroupBarline.cpp | 17 +- src/private/mx/core/generated/GroupBarline.h | 6 + .../mx/core/generated/GroupBarlineValue.cpp | 8 +- .../mx/core/generated/GroupBarlineValue.h | 5 + src/private/mx/core/generated/GroupName.cpp | 33 ++-- src/private/mx/core/generated/GroupName.h | 6 + src/private/mx/core/generated/GroupSymbol.cpp | 25 ++- src/private/mx/core/generated/GroupSymbol.h | 6 + .../mx/core/generated/GroupSymbolValue.cpp | 8 +- .../mx/core/generated/GroupSymbolValue.h | 5 + src/private/mx/core/generated/Grouping.cpp | 17 +- src/private/mx/core/generated/Grouping.h | 6 + .../mx/core/generated/HammerOnPullOff.cpp | 37 +++-- .../mx/core/generated/HammerOnPullOff.h | 6 + src/private/mx/core/generated/Handbell.cpp | 35 ++-- src/private/mx/core/generated/Handbell.h | 6 + .../mx/core/generated/HandbellValue.cpp | 8 +- src/private/mx/core/generated/HandbellValue.h | 5 + .../mx/core/generated/HarmonClosed.cpp | 17 +- src/private/mx/core/generated/HarmonClosed.h | 6 + .../core/generated/HarmonClosedLocation.cpp | 8 +- .../mx/core/generated/HarmonClosedLocation.h | 5 + .../mx/core/generated/HarmonClosedValue.cpp | 8 +- .../mx/core/generated/HarmonClosedValue.h | 5 + src/private/mx/core/generated/HarmonMute.cpp | 35 ++-- src/private/mx/core/generated/HarmonMute.h | 6 + src/private/mx/core/generated/Harmonic.cpp | 39 +++-- src/private/mx/core/generated/Harmonic.h | 6 + .../mx/core/generated/HarmonicChoice.cpp | 10 +- .../mx/core/generated/HarmonicChoice.h | 4 + .../mx/core/generated/HarmonicChoice2.cpp | 12 +- .../mx/core/generated/HarmonicChoice2.h | 4 + src/private/mx/core/generated/Harmony.cpp | 55 ++++--- src/private/mx/core/generated/Harmony.h | 6 + .../mx/core/generated/HarmonyAlter.cpp | 37 +++-- src/private/mx/core/generated/HarmonyAlter.h | 6 + .../mx/core/generated/HarmonyArrangement.cpp | 8 +- .../mx/core/generated/HarmonyArrangement.h | 5 + .../mx/core/generated/HarmonyChordGroup.cpp | 16 +- .../mx/core/generated/HarmonyChordGroup.h | 4 + .../generated/HarmonyChordGroupChoice.cpp | 13 +- .../core/generated/HarmonyChordGroupChoice.h | 5 + src/private/mx/core/generated/HarmonyType.cpp | 8 +- src/private/mx/core/generated/HarmonyType.h | 5 + src/private/mx/core/generated/HarpPedals.cpp | 39 +++-- src/private/mx/core/generated/HarpPedals.h | 6 + src/private/mx/core/generated/HeelToe.cpp | 30 ++-- src/private/mx/core/generated/HeelToe.h | 4 + src/private/mx/core/generated/Hole.cpp | 35 ++-- src/private/mx/core/generated/Hole.h | 6 + src/private/mx/core/generated/HoleClosed.cpp | 17 +- src/private/mx/core/generated/HoleClosed.h | 6 + .../mx/core/generated/HoleClosedLocation.cpp | 8 +- .../mx/core/generated/HoleClosedLocation.h | 5 + .../mx/core/generated/HoleClosedValue.cpp | 8 +- .../mx/core/generated/HoleClosedValue.h | 5 + .../mx/core/generated/HorizontalTurn.cpp | 50 +++--- .../mx/core/generated/HorizontalTurn.h | 6 + .../mx/core/generated/Identification.cpp | 23 ++- .../mx/core/generated/Identification.h | 6 + src/private/mx/core/generated/Image.cpp | 30 ++-- src/private/mx/core/generated/Image.h | 6 + src/private/mx/core/generated/Instrument.cpp | 14 +- src/private/mx/core/generated/Instrument.h | 6 + .../mx/core/generated/InstrumentChange.cpp | 15 +- .../mx/core/generated/InstrumentChange.h | 6 + .../mx/core/generated/InstrumentLink.cpp | 14 +- .../mx/core/generated/InstrumentLink.h | 6 + .../mx/core/generated/InstrumentSound.cpp | 8 + .../mx/core/generated/InstrumentSound.h | 5 + .../mx/core/generated/Interchangeable.cpp | 23 ++- .../mx/core/generated/Interchangeable.h | 6 + src/private/mx/core/generated/Inversion.cpp | 33 ++-- src/private/mx/core/generated/Inversion.h | 6 + src/private/mx/core/generated/Key.cpp | 39 +++-- src/private/mx/core/generated/Key.h | 6 + .../mx/core/generated/KeyAccidental.cpp | 17 +- src/private/mx/core/generated/KeyAccidental.h | 6 + src/private/mx/core/generated/KeyChoice.cpp | 10 +- src/private/mx/core/generated/KeyChoice.h | 4 + src/private/mx/core/generated/KeyOctave.cpp | 19 ++- src/private/mx/core/generated/KeyOctave.h | 6 + src/private/mx/core/generated/Kind.cpp | 45 ++++-- src/private/mx/core/generated/Kind.h | 6 + src/private/mx/core/generated/KindValue.cpp | 8 +- src/private/mx/core/generated/KindValue.h | 5 + src/private/mx/core/generated/LayoutGroup.cpp | 12 +- src/private/mx/core/generated/LayoutGroup.h | 4 + .../mx/core/generated/LeftCenterRight.cpp | 8 +- .../mx/core/generated/LeftCenterRight.h | 5 + src/private/mx/core/generated/LeftRight.cpp | 8 +- src/private/mx/core/generated/LeftRight.h | 5 + .../core/generated/LeftRightMarginsGroup.cpp | 10 +- .../mx/core/generated/LeftRightMarginsGroup.h | 5 + src/private/mx/core/generated/Level.cpp | 23 ++- src/private/mx/core/generated/Level.h | 6 + src/private/mx/core/generated/LineDetail.cpp | 24 ++- src/private/mx/core/generated/LineDetail.h | 6 + src/private/mx/core/generated/LineEnd.cpp | 8 +- src/private/mx/core/generated/LineEnd.h | 5 + src/private/mx/core/generated/LineLength.cpp | 8 +- src/private/mx/core/generated/LineLength.h | 5 + src/private/mx/core/generated/LineShape.cpp | 8 +- src/private/mx/core/generated/LineShape.h | 5 + src/private/mx/core/generated/LineType.cpp | 8 +- src/private/mx/core/generated/LineType.h | 5 + src/private/mx/core/generated/LineWidth.cpp | 17 +- src/private/mx/core/generated/LineWidth.h | 6 + .../mx/core/generated/LineWidthType.cpp | 7 + src/private/mx/core/generated/LineWidthType.h | 5 + src/private/mx/core/generated/Link.cpp | 24 ++- src/private/mx/core/generated/Link.h | 6 + src/private/mx/core/generated/Listen.cpp | 17 +- src/private/mx/core/generated/Listen.h | 6 + .../mx/core/generated/ListenChoice.cpp | 12 +- src/private/mx/core/generated/ListenChoice.h | 4 + src/private/mx/core/generated/Listening.cpp | 19 ++- src/private/mx/core/generated/Listening.h | 6 + .../mx/core/generated/ListeningChoice.cpp | 10 +- .../mx/core/generated/ListeningChoice.h | 4 + src/private/mx/core/generated/Lyric.cpp | 39 +++-- src/private/mx/core/generated/Lyric.h | 6 + src/private/mx/core/generated/LyricChoice.cpp | 14 +- src/private/mx/core/generated/LyricChoice.h | 4 + src/private/mx/core/generated/LyricFont.cpp | 22 ++- src/private/mx/core/generated/LyricFont.h | 6 + .../mx/core/generated/LyricLanguage.cpp | 15 +- src/private/mx/core/generated/LyricLanguage.h | 6 + .../mx/core/generated/LyricSyllableGroup.cpp | 10 +- .../mx/core/generated/LyricSyllableGroup.h | 4 + .../mx/core/generated/LyricTextGroup.cpp | 14 +- .../mx/core/generated/LyricTextGroup.h | 4 + src/private/mx/core/generated/MIDI128.cpp | 25 ++- src/private/mx/core/generated/MIDI128.h | 5 + src/private/mx/core/generated/MIDI16.cpp | 25 ++- src/private/mx/core/generated/MIDI16.h | 5 + src/private/mx/core/generated/MIDI16384.cpp | 25 ++- src/private/mx/core/generated/MIDI16384.h | 5 + src/private/mx/core/generated/MIDIDevice.cpp | 15 +- src/private/mx/core/generated/MIDIDevice.h | 6 + .../mx/core/generated/MIDIInstrument.cpp | 27 +++- .../mx/core/generated/MIDIInstrument.h | 6 + src/private/mx/core/generated/MarginType.cpp | 8 +- src/private/mx/core/generated/MarginType.h | 5 + .../mx/core/generated/MeasureLayout.cpp | 15 +- src/private/mx/core/generated/MeasureLayout.h | 6 + .../mx/core/generated/MeasureNumbering.cpp | 45 ++++-- .../mx/core/generated/MeasureNumbering.h | 6 + .../core/generated/MeasureNumberingValue.cpp | 8 +- .../mx/core/generated/MeasureNumberingValue.h | 5 + .../mx/core/generated/MeasureRepeat.cpp | 19 ++- src/private/mx/core/generated/MeasureRepeat.h | 6 + .../mx/core/generated/MeasureStyle.cpp | 27 +++- src/private/mx/core/generated/MeasureStyle.h | 6 + .../mx/core/generated/MeasureStyleChoice.cpp | 14 +- .../mx/core/generated/MeasureStyleChoice.h | 4 + src/private/mx/core/generated/MeasureText.cpp | 7 + src/private/mx/core/generated/MeasureText.h | 5 + src/private/mx/core/generated/Membrane.cpp | 17 +- src/private/mx/core/generated/Membrane.h | 6 + .../mx/core/generated/MembraneValue.cpp | 8 +- src/private/mx/core/generated/MembraneValue.h | 5 + src/private/mx/core/generated/Metal.cpp | 17 +- src/private/mx/core/generated/Metal.h | 6 + src/private/mx/core/generated/MetalValue.cpp | 8 +- src/private/mx/core/generated/MetalValue.h | 5 + src/private/mx/core/generated/Metronome.cpp | 43 +++-- src/private/mx/core/generated/Metronome.h | 6 + .../mx/core/generated/MetronomeBeam.cpp | 17 +- src/private/mx/core/generated/MetronomeBeam.h | 6 + .../mx/core/generated/MetronomeChoice.cpp | 10 +- .../mx/core/generated/MetronomeChoice.h | 4 + .../core/generated/MetronomeChoiceGroup.cpp | 12 +- .../mx/core/generated/MetronomeChoiceGroup.h | 4 + .../core/generated/MetronomeChoiceGroup2.cpp | 14 +- .../mx/core/generated/MetronomeChoiceGroup2.h | 5 + .../generated/MetronomeChoiceGroup2Group.cpp | 11 +- .../generated/MetronomeChoiceGroup2Group.h | 5 + .../generated/MetronomeChoiceGroupChoice.cpp | 11 +- .../generated/MetronomeChoiceGroupChoice.h | 5 + .../MetronomeChoiceGroupChoiceGroup.cpp | 11 +- .../MetronomeChoiceGroupChoiceGroup.h | 5 + .../mx/core/generated/MetronomeNote.cpp | 23 ++- src/private/mx/core/generated/MetronomeNote.h | 6 + .../mx/core/generated/MetronomeTied.cpp | 16 +- src/private/mx/core/generated/MetronomeTied.h | 6 + .../mx/core/generated/MetronomeTuplet.cpp | 14 +- .../mx/core/generated/MetronomeTuplet.h | 4 + src/private/mx/core/generated/Millimeters.cpp | 25 ++- src/private/mx/core/generated/Millimeters.h | 4 + .../mx/core/generated/Milliseconds.cpp | 25 ++- src/private/mx/core/generated/Milliseconds.h | 5 + .../mx/core/generated/Miscellaneous.cpp | 15 +- src/private/mx/core/generated/Miscellaneous.h | 6 + .../mx/core/generated/MiscellaneousField.cpp | 13 +- .../mx/core/generated/MiscellaneousField.h | 6 + src/private/mx/core/generated/Mode.cpp | 7 + src/private/mx/core/generated/Mode.h | 5 + src/private/mx/core/generated/Mordent.cpp | 48 +++--- src/private/mx/core/generated/Mordent.h | 4 + .../mx/core/generated/MultipleRest.cpp | 17 +- src/private/mx/core/generated/MultipleRest.h | 6 + .../mx/core/generated/MusicDataChoice.cpp | 34 ++-- .../mx/core/generated/MusicDataChoice.h | 4 + src/private/mx/core/generated/Mute.cpp | 8 +- src/private/mx/core/generated/Mute.h | 5 + src/private/mx/core/generated/NameDisplay.cpp | 17 +- src/private/mx/core/generated/NameDisplay.h | 6 + .../mx/core/generated/NameDisplayChoice.cpp | 10 +- .../mx/core/generated/NameDisplayChoice.h | 4 + .../mx/core/generated/NonArpeggiate.cpp | 30 ++-- src/private/mx/core/generated/NonArpeggiate.h | 6 + .../mx/core/generated/NonNegativeDecimal.cpp | 25 ++- .../mx/core/generated/NonNegativeDecimal.h | 4 + .../core/generated/NonTraditionalKeyGroup.cpp | 13 +- .../core/generated/NonTraditionalKeyGroup.h | 5 + .../mx/core/generated/NormalNoteGroup.cpp | 12 +- .../mx/core/generated/NormalNoteGroup.h | 4 + src/private/mx/core/generated/Notations.cpp | 19 ++- src/private/mx/core/generated/Notations.h | 6 + .../mx/core/generated/NotationsChoice.cpp | 34 ++-- .../mx/core/generated/NotationsChoice.h | 4 + src/private/mx/core/generated/Note.cpp | 85 +++++----- src/private/mx/core/generated/Note.h | 6 + src/private/mx/core/generated/NoteChoice.cpp | 12 +- src/private/mx/core/generated/NoteChoice.h | 4 + src/private/mx/core/generated/NoteSize.cpp | 17 +- src/private/mx/core/generated/NoteSize.h | 6 + .../mx/core/generated/NoteSizeType.cpp | 8 +- src/private/mx/core/generated/NoteSizeType.h | 5 + src/private/mx/core/generated/NoteType.cpp | 17 +- src/private/mx/core/generated/NoteType.h | 6 + .../mx/core/generated/NoteTypeValue.cpp | 8 +- src/private/mx/core/generated/NoteTypeValue.h | 5 + src/private/mx/core/generated/Notehead.cpp | 31 ++-- src/private/mx/core/generated/Notehead.h | 6 + .../mx/core/generated/NoteheadText.cpp | 17 +- src/private/mx/core/generated/NoteheadText.h | 6 + .../mx/core/generated/NoteheadTextChoice.cpp | 10 +- .../mx/core/generated/NoteheadTextChoice.h | 4 + .../mx/core/generated/NoteheadValue.cpp | 8 +- src/private/mx/core/generated/NoteheadValue.h | 5 + src/private/mx/core/generated/NumberLevel.cpp | 25 ++- src/private/mx/core/generated/NumberLevel.h | 5 + .../mx/core/generated/NumberOfLines.cpp | 25 ++- src/private/mx/core/generated/NumberOfLines.h | 5 + .../mx/core/generated/NumberOrNormal.cpp | 8 + .../mx/core/generated/NumberOrNormal.h | 5 + src/private/mx/core/generated/Numeral.cpp | 19 ++- src/private/mx/core/generated/Numeral.h | 6 + src/private/mx/core/generated/NumeralKey.cpp | 19 ++- src/private/mx/core/generated/NumeralKey.h | 6 + src/private/mx/core/generated/NumeralMode.cpp | 8 +- src/private/mx/core/generated/NumeralMode.h | 5 + src/private/mx/core/generated/NumeralRoot.cpp | 33 ++-- src/private/mx/core/generated/NumeralRoot.h | 6 + .../mx/core/generated/NumeralValue.cpp | 25 ++- src/private/mx/core/generated/NumeralValue.h | 5 + src/private/mx/core/generated/Octave.cpp | 25 ++- src/private/mx/core/generated/Octave.h | 5 + src/private/mx/core/generated/OctaveShift.cpp | 42 +++-- src/private/mx/core/generated/OctaveShift.h | 6 + src/private/mx/core/generated/Offset.cpp | 17 +- src/private/mx/core/generated/Offset.h | 6 + src/private/mx/core/generated/OnOff.cpp | 8 +- src/private/mx/core/generated/OnOff.h | 5 + src/private/mx/core/generated/Opus.cpp | 14 +- src/private/mx/core/generated/Opus.h | 6 + src/private/mx/core/generated/Ornaments.cpp | 15 +- src/private/mx/core/generated/Ornaments.h | 6 + .../mx/core/generated/OrnamentsGroup.cpp | 10 +- .../mx/core/generated/OrnamentsGroup.h | 4 + .../core/generated/OrnamentsGroupChoice.cpp | 36 +++-- .../mx/core/generated/OrnamentsGroupChoice.h | 4 + .../mx/core/generated/OtherAppearance.cpp | 13 +- .../mx/core/generated/OtherAppearance.h | 6 + .../mx/core/generated/OtherDirection.cpp | 39 +++-- .../mx/core/generated/OtherDirection.h | 6 + .../mx/core/generated/OtherListening.cpp | 15 +- .../mx/core/generated/OtherListening.h | 6 + .../mx/core/generated/OtherNotation.cpp | 41 +++-- src/private/mx/core/generated/OtherNotation.h | 6 + .../mx/core/generated/OtherPlacementText.cpp | 35 ++-- .../mx/core/generated/OtherPlacementText.h | 6 + src/private/mx/core/generated/OtherPlay.cpp | 13 +- src/private/mx/core/generated/OtherPlay.h | 6 + src/private/mx/core/generated/OtherText.cpp | 15 +- src/private/mx/core/generated/OtherText.h | 6 + src/private/mx/core/generated/OverUnder.cpp | 8 +- src/private/mx/core/generated/OverUnder.h | 5 + src/private/mx/core/generated/PageLayout.cpp | 17 +- src/private/mx/core/generated/PageLayout.h | 6 + .../mx/core/generated/PageLayoutGroup.cpp | 10 +- .../mx/core/generated/PageLayoutGroup.h | 4 + src/private/mx/core/generated/PageMargins.cpp | 17 +- src/private/mx/core/generated/PageMargins.h | 6 + src/private/mx/core/generated/PartClef.cpp | 15 +- src/private/mx/core/generated/PartClef.h | 6 + src/private/mx/core/generated/PartGroup.cpp | 31 ++-- src/private/mx/core/generated/PartGroup.h | 6 + src/private/mx/core/generated/PartLink.cpp | 15 +- src/private/mx/core/generated/PartLink.h | 6 + src/private/mx/core/generated/PartList.cpp | 19 ++- src/private/mx/core/generated/PartList.h | 6 + .../mx/core/generated/PartListChoice.cpp | 10 +- .../mx/core/generated/PartListChoice.h | 4 + src/private/mx/core/generated/PartName.cpp | 35 ++-- src/private/mx/core/generated/PartName.h | 6 + src/private/mx/core/generated/PartSymbol.cpp | 29 ++-- src/private/mx/core/generated/PartSymbol.h | 6 + .../mx/core/generated/PartTranspose.cpp | 15 +- src/private/mx/core/generated/PartTranspose.h | 6 + .../mx/core/generated/PartwiseMeasure.cpp | 23 ++- .../mx/core/generated/PartwiseMeasure.h | 6 + .../mx/core/generated/PartwisePart.cpp | 17 +- src/private/mx/core/generated/PartwisePart.h | 6 + src/private/mx/core/generated/Pedal.cpp | 46 ++++-- src/private/mx/core/generated/Pedal.h | 6 + src/private/mx/core/generated/PedalTuning.cpp | 17 +- src/private/mx/core/generated/PedalTuning.h | 6 + src/private/mx/core/generated/PedalType.cpp | 8 +- src/private/mx/core/generated/PedalType.h | 5 + src/private/mx/core/generated/PerMinute.cpp | 21 ++- src/private/mx/core/generated/PerMinute.h | 6 + src/private/mx/core/generated/Percent.cpp | 25 ++- src/private/mx/core/generated/Percent.h | 4 + src/private/mx/core/generated/Percussion.cpp | 39 +++-- src/private/mx/core/generated/Percussion.h | 6 + .../mx/core/generated/PercussionChoice.cpp | 28 ++-- .../mx/core/generated/PercussionChoice.h | 4 + src/private/mx/core/generated/Pitch.cpp | 19 ++- src/private/mx/core/generated/Pitch.h | 6 + src/private/mx/core/generated/Pitched.cpp | 17 +- src/private/mx/core/generated/Pitched.h | 6 + .../mx/core/generated/PitchedValue.cpp | 8 +- src/private/mx/core/generated/PitchedValue.h | 5 + .../mx/core/generated/PlacementText.cpp | 33 ++-- src/private/mx/core/generated/PlacementText.h | 6 + src/private/mx/core/generated/Play.cpp | 15 +- src/private/mx/core/generated/Play.h | 6 + src/private/mx/core/generated/PlayChoice.cpp | 12 +- src/private/mx/core/generated/PlayChoice.h | 4 + src/private/mx/core/generated/Player.cpp | 13 +- src/private/mx/core/generated/Player.h | 6 + .../mx/core/generated/PositiveDivisions.cpp | 25 ++- .../mx/core/generated/PositiveDivisions.h | 4 + .../core/generated/PositiveIntegerOrEmpty.cpp | 12 ++ .../core/generated/PositiveIntegerOrEmpty.h | 6 + .../mx/core/generated/PrincipalVoice.cpp | 39 +++-- .../mx/core/generated/PrincipalVoice.h | 6 + .../core/generated/PrincipalVoiceSymbol.cpp | 8 +- .../mx/core/generated/PrincipalVoiceSymbol.h | 5 + src/private/mx/core/generated/Print.cpp | 31 ++-- src/private/mx/core/generated/Print.h | 6 + src/private/mx/core/generated/Release.cpp | 10 +- src/private/mx/core/generated/Release.h | 4 + src/private/mx/core/generated/Repeat.cpp | 22 ++- src/private/mx/core/generated/Repeat.h | 6 + src/private/mx/core/generated/Rest.cpp | 17 +- src/private/mx/core/generated/Rest.h | 6 + .../mx/core/generated/RightLeftMiddle.cpp | 8 +- .../mx/core/generated/RightLeftMiddle.h | 5 + src/private/mx/core/generated/Root.cpp | 17 +- src/private/mx/core/generated/Root.h | 6 + src/private/mx/core/generated/RootStep.cpp | 33 ++-- src/private/mx/core/generated/RootStep.h | 6 + .../mx/core/generated/RotationDegrees.cpp | 25 ++- .../mx/core/generated/RotationDegrees.h | 4 + src/private/mx/core/generated/Scaling.cpp | 17 +- src/private/mx/core/generated/Scaling.h | 6 + src/private/mx/core/generated/Scordatura.cpp | 17 +- src/private/mx/core/generated/Scordatura.h | 6 + .../mx/core/generated/ScoreHeaderGroup.cpp | 16 +- .../mx/core/generated/ScoreHeaderGroup.h | 4 + .../mx/core/generated/ScoreInstrument.cpp | 15 +- .../mx/core/generated/ScoreInstrument.h | 6 + src/private/mx/core/generated/ScorePart.cpp | 31 ++-- src/private/mx/core/generated/ScorePart.h | 6 + .../mx/core/generated/ScorePartMIDIGroup.cpp | 10 +- .../mx/core/generated/ScorePartMIDIGroup.h | 4 + .../mx/core/generated/ScorePartwise.cpp | 19 ++- src/private/mx/core/generated/ScorePartwise.h | 6 + .../mx/core/generated/ScoreTimewise.cpp | 19 ++- src/private/mx/core/generated/ScoreTimewise.h | 6 + src/private/mx/core/generated/Segno.cpp | 38 +++-- src/private/mx/core/generated/Segno.h | 6 + src/private/mx/core/generated/SemiPitched.cpp | 8 +- src/private/mx/core/generated/SemiPitched.h | 5 + src/private/mx/core/generated/Semitones.cpp | 25 ++- src/private/mx/core/generated/Semitones.h | 4 + src/private/mx/core/generated/ShowFrets.cpp | 8 +- src/private/mx/core/generated/ShowFrets.h | 5 + src/private/mx/core/generated/ShowTuplet.cpp | 8 +- src/private/mx/core/generated/ShowTuplet.h | 5 + src/private/mx/core/generated/Slash.cpp | 21 ++- src/private/mx/core/generated/Slash.h | 6 + src/private/mx/core/generated/SlashGroup.cpp | 8 +- src/private/mx/core/generated/SlashGroup.h | 4 + .../mx/core/generated/SlashGroupGroup.cpp | 10 +- .../mx/core/generated/SlashGroupGroup.h | 4 + src/private/mx/core/generated/Slide.cpp | 49 +++--- src/private/mx/core/generated/Slide.h | 6 + src/private/mx/core/generated/Slur.cpp | 50 +++--- src/private/mx/core/generated/Slur.h | 6 + src/private/mx/core/generated/Sound.cpp | 43 +++-- src/private/mx/core/generated/Sound.h | 6 + src/private/mx/core/generated/SoundGroup.cpp | 14 +- src/private/mx/core/generated/SoundGroup.h | 4 + src/private/mx/core/generated/SoundID.cpp | 8 +- src/private/mx/core/generated/SoundID.h | 5 + .../mx/core/generated/StaffDetails.cpp | 31 ++-- src/private/mx/core/generated/StaffDetails.h | 6 + .../mx/core/generated/StaffDetailsGroup.cpp | 10 +- .../mx/core/generated/StaffDetailsGroup.h | 4 + src/private/mx/core/generated/StaffDivide.cpp | 38 +++-- src/private/mx/core/generated/StaffDivide.h | 6 + .../mx/core/generated/StaffDivideSymbol.cpp | 8 +- .../mx/core/generated/StaffDivideSymbol.h | 5 + src/private/mx/core/generated/StaffLayout.cpp | 17 +- src/private/mx/core/generated/StaffLayout.h | 6 + src/private/mx/core/generated/StaffLine.cpp | 25 ++- src/private/mx/core/generated/StaffLine.h | 5 + .../mx/core/generated/StaffLinePosition.cpp | 25 ++- .../mx/core/generated/StaffLinePosition.h | 5 + src/private/mx/core/generated/StaffNumber.cpp | 25 ++- src/private/mx/core/generated/StaffNumber.h | 5 + src/private/mx/core/generated/StaffSize.cpp | 17 +- src/private/mx/core/generated/StaffSize.h | 6 + src/private/mx/core/generated/StaffTuning.cpp | 17 +- src/private/mx/core/generated/StaffTuning.h | 6 + src/private/mx/core/generated/StaffType.cpp | 8 +- src/private/mx/core/generated/StaffType.h | 5 + src/private/mx/core/generated/StartNote.cpp | 8 +- src/private/mx/core/generated/StartNote.h | 5 + src/private/mx/core/generated/StartStop.cpp | 8 +- src/private/mx/core/generated/StartStop.h | 5 + .../mx/core/generated/StartStopContinue.cpp | 8 +- .../mx/core/generated/StartStopContinue.h | 5 + .../core/generated/StartStopDiscontinue.cpp | 8 +- .../mx/core/generated/StartStopDiscontinue.h | 5 + .../mx/core/generated/StartStopSingle.cpp | 8 +- .../mx/core/generated/StartStopSingle.h | 5 + src/private/mx/core/generated/Stem.cpp | 25 ++- src/private/mx/core/generated/Stem.h | 6 + src/private/mx/core/generated/StemValue.cpp | 8 +- src/private/mx/core/generated/StemValue.h | 5 + src/private/mx/core/generated/Step.cpp | 8 +- src/private/mx/core/generated/Step.h | 5 + src/private/mx/core/generated/Stick.cpp | 23 ++- src/private/mx/core/generated/Stick.h | 6 + .../mx/core/generated/StickLocation.cpp | 8 +- src/private/mx/core/generated/StickLocation.h | 5 + .../mx/core/generated/StickMaterial.cpp | 8 +- src/private/mx/core/generated/StickMaterial.h | 5 + src/private/mx/core/generated/StickType.cpp | 8 +- src/private/mx/core/generated/StickType.h | 5 + src/private/mx/core/generated/String.cpp | 35 ++-- src/private/mx/core/generated/String.h | 6 + src/private/mx/core/generated/StringMute.cpp | 38 +++-- src/private/mx/core/generated/StringMute.h | 6 + .../mx/core/generated/StringNumber.cpp | 25 ++- src/private/mx/core/generated/StringNumber.h | 5 + .../mx/core/generated/StrongAccent.cpp | 30 ++-- src/private/mx/core/generated/StrongAccent.h | 4 + src/private/mx/core/generated/StyleText.cpp | 31 ++-- src/private/mx/core/generated/StyleText.h | 6 + src/private/mx/core/generated/Supports.cpp | 16 +- src/private/mx/core/generated/Supports.h | 6 + src/private/mx/core/generated/Swing.cpp | 15 +- src/private/mx/core/generated/Swing.h | 6 + src/private/mx/core/generated/SwingChoice.cpp | 10 +- src/private/mx/core/generated/SwingChoice.h | 4 + .../mx/core/generated/SwingChoiceGroup.cpp | 12 +- .../mx/core/generated/SwingChoiceGroup.h | 4 + .../mx/core/generated/SwingTypeValue.cpp | 8 +- .../mx/core/generated/SwingTypeValue.h | 5 + src/private/mx/core/generated/Syllabic.cpp | 8 +- src/private/mx/core/generated/Syllabic.h | 5 + src/private/mx/core/generated/SymbolSize.cpp | 8 +- src/private/mx/core/generated/SymbolSize.h | 5 + src/private/mx/core/generated/Sync.cpp | 20 ++- src/private/mx/core/generated/Sync.h | 6 + src/private/mx/core/generated/SyncType.cpp | 8 +- src/private/mx/core/generated/SyncType.h | 5 + .../mx/core/generated/SystemDividers.cpp | 17 +- .../mx/core/generated/SystemDividers.h | 6 + .../mx/core/generated/SystemLayout.cpp | 21 ++- src/private/mx/core/generated/SystemLayout.h | 6 + .../mx/core/generated/SystemMargins.cpp | 15 +- src/private/mx/core/generated/SystemMargins.h | 6 + .../mx/core/generated/SystemRelation.cpp | 8 +- .../mx/core/generated/SystemRelation.h | 5 + .../core/generated/SystemRelationNumber.cpp | 8 +- .../mx/core/generated/SystemRelationNumber.h | 5 + src/private/mx/core/generated/Tap.cpp | 35 ++-- src/private/mx/core/generated/Tap.h | 6 + src/private/mx/core/generated/TapHand.cpp | 8 +- src/private/mx/core/generated/TapHand.h | 5 + src/private/mx/core/generated/Technical.cpp | 15 +- src/private/mx/core/generated/Technical.h | 6 + .../mx/core/generated/TechnicalChoice.cpp | 68 ++++---- .../mx/core/generated/TechnicalChoice.h | 4 + src/private/mx/core/generated/Tenths.cpp | 25 ++- src/private/mx/core/generated/Tenths.h | 4 + .../mx/core/generated/TextDirection.cpp | 8 +- src/private/mx/core/generated/TextDirection.h | 5 + .../mx/core/generated/TextElementData.cpp | 35 ++-- .../mx/core/generated/TextElementData.h | 6 + src/private/mx/core/generated/Tie.cpp | 18 ++- src/private/mx/core/generated/Tie.h | 6 + src/private/mx/core/generated/Tied.cpp | 50 +++--- src/private/mx/core/generated/Tied.h | 6 + src/private/mx/core/generated/TiedType.cpp | 8 +- src/private/mx/core/generated/TiedType.h | 5 + src/private/mx/core/generated/Time.cpp | 45 ++++-- src/private/mx/core/generated/Time.h | 6 + src/private/mx/core/generated/TimeChoice.cpp | 8 +- src/private/mx/core/generated/TimeChoice.h | 4 + .../mx/core/generated/TimeChoiceGroup.cpp | 12 +- .../mx/core/generated/TimeChoiceGroup.h | 4 + .../mx/core/generated/TimeModification.cpp | 19 ++- .../mx/core/generated/TimeModification.h | 6 + .../core/generated/TimeModificationGroup.cpp | 10 +- .../mx/core/generated/TimeModificationGroup.h | 5 + .../mx/core/generated/TimeRelation.cpp | 8 +- src/private/mx/core/generated/TimeRelation.h | 5 + .../mx/core/generated/TimeSeparator.cpp | 8 +- src/private/mx/core/generated/TimeSeparator.h | 5 + .../mx/core/generated/TimeSignatureGroup.cpp | 6 + .../mx/core/generated/TimeSignatureGroup.h | 4 + src/private/mx/core/generated/TimeSymbol.cpp | 8 +- src/private/mx/core/generated/TimeSymbol.h | 5 + .../mx/core/generated/TimewiseMeasure.cpp | 25 ++- .../mx/core/generated/TimewiseMeasure.h | 6 + .../mx/core/generated/TimewisePart.cpp | 15 +- src/private/mx/core/generated/TimewisePart.h | 6 + src/private/mx/core/generated/Timpani.cpp | 16 +- src/private/mx/core/generated/Timpani.h | 6 + .../mx/core/generated/TipDirection.cpp | 8 +- src/private/mx/core/generated/TipDirection.h | 5 + src/private/mx/core/generated/TopBottom.cpp | 8 +- src/private/mx/core/generated/TopBottom.h | 5 + .../mx/core/generated/TraditionalKeyGroup.cpp | 12 +- .../mx/core/generated/TraditionalKeyGroup.h | 4 + src/private/mx/core/generated/Transpose.cpp | 17 +- src/private/mx/core/generated/Transpose.h | 6 + .../mx/core/generated/TransposeGroup.cpp | 14 +- .../mx/core/generated/TransposeGroup.h | 4 + src/private/mx/core/generated/Tremolo.cpp | 39 +++-- src/private/mx/core/generated/Tremolo.h | 6 + .../mx/core/generated/TremoloMarks.cpp | 25 ++- src/private/mx/core/generated/TremoloMarks.h | 5 + src/private/mx/core/generated/TremoloType.cpp | 8 +- src/private/mx/core/generated/TremoloType.h | 5 + src/private/mx/core/generated/TrillBeats.cpp | 25 ++- src/private/mx/core/generated/TrillBeats.h | 4 + src/private/mx/core/generated/TrillStep.cpp | 8 +- src/private/mx/core/generated/TrillStep.h | 5 + src/private/mx/core/generated/TuningGroup.cpp | 12 +- src/private/mx/core/generated/TuningGroup.h | 4 + src/private/mx/core/generated/Tuplet.cpp | 39 +++-- src/private/mx/core/generated/Tuplet.h | 6 + src/private/mx/core/generated/TupletDot.cpp | 24 ++- src/private/mx/core/generated/TupletDot.h | 6 + .../mx/core/generated/TupletNumber.cpp | 25 ++- src/private/mx/core/generated/TupletNumber.h | 6 + .../mx/core/generated/TupletPortion.cpp | 19 ++- src/private/mx/core/generated/TupletPortion.h | 6 + src/private/mx/core/generated/TupletType.cpp | 25 ++- src/private/mx/core/generated/TupletType.h | 6 + src/private/mx/core/generated/TwoNoteTurn.cpp | 8 +- src/private/mx/core/generated/TwoNoteTurn.h | 5 + src/private/mx/core/generated/TypedText.cpp | 13 +- src/private/mx/core/generated/TypedText.h | 6 + src/private/mx/core/generated/Unpitched.cpp | 15 +- src/private/mx/core/generated/Unpitched.h | 6 + src/private/mx/core/generated/UpDown.cpp | 8 +- src/private/mx/core/generated/UpDown.h | 5 + .../mx/core/generated/UpDownStopContinue.cpp | 8 +- .../mx/core/generated/UpDownStopContinue.h | 5 + .../mx/core/generated/UprightInverted.cpp | 8 +- .../mx/core/generated/UprightInverted.h | 5 + src/private/mx/core/generated/Valign.cpp | 8 +- src/private/mx/core/generated/Valign.h | 5 + src/private/mx/core/generated/ValignImage.cpp | 8 +- src/private/mx/core/generated/ValignImage.h | 5 + .../mx/core/generated/VirtualInstrument.cpp | 13 +- .../mx/core/generated/VirtualInstrument.h | 6 + .../generated/VirtualInstrumentDataGroup.cpp | 13 +- .../generated/VirtualInstrumentDataGroup.h | 5 + .../VirtualInstrumentDataGroupChoice.cpp | 11 +- .../VirtualInstrumentDataGroupChoice.h | 5 + src/private/mx/core/generated/Wait.cpp | 16 +- src/private/mx/core/generated/Wait.h | 6 + src/private/mx/core/generated/WavyLine.cpp | 46 ++++-- src/private/mx/core/generated/WavyLine.h | 6 + src/private/mx/core/generated/Wedge.cpp | 38 +++-- src/private/mx/core/generated/Wedge.h | 6 + src/private/mx/core/generated/WedgeType.cpp | 8 +- src/private/mx/core/generated/WedgeType.h | 5 + src/private/mx/core/generated/Winged.cpp | 8 +- src/private/mx/core/generated/Winged.h | 5 + src/private/mx/core/generated/Wood.cpp | 17 +- src/private/mx/core/generated/Wood.h | 6 + src/private/mx/core/generated/WoodValue.cpp | 8 +- src/private/mx/core/generated/WoodValue.h | 5 + src/private/mx/core/generated/Work.cpp | 15 +- src/private/mx/core/generated/Work.h | 6 + src/private/mx/core/generated/YesNo.cpp | 8 +- src/private/mx/core/generated/YesNo.h | 5 + src/private/mx/core/generated/YesNoNumber.cpp | 8 + src/private/mx/core/generated/YesNoNumber.h | 5 + src/private/mx/examples/Read.cpp | 10 +- src/private/mxtest/api/DiagnosticsTest.cpp | 132 +++++++++++++-- .../mxtest/core/ImportDiagnosticsTest.cpp | 153 ++++++++++++++++++ 920 files changed, 9457 insertions(+), 2429 deletions(-) create mode 100644 src/private/mx/core/ParseContext.cpp create mode 100644 src/private/mx/core/ParseContext.h create mode 100644 src/private/mxtest/core/ImportDiagnosticsTest.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 0fe8a77c7..fea9730e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,10 +58,10 @@ if(NOT TARGET pugixml) endif() # mx_core: the generated C++ typed model plus its hand-written runtime -# (Decimal, Result, Error, Lexical, Token, NameToken, OneOrMore, Xml). The -# generated per-type sources live in src/private/mx/core/generated/ (their -# own directory, so generator-owned code is recognizable at a glance) and -# arrive via sources.cmake (emitted by `python3 -m gen gen/cpp/config.toml`). +# (Decimal, Result, Error, Lexical, ParseContext, Token, NameToken, OneOrMore, +# Xml). The generated per-type sources live in src/private/mx/core/generated/ +# (their own directory, so generator-owned code is recognizable at a glance) +# and arrive via sources.cmake (emitted by `python3 -m gen gen/cpp/config.toml`). set(MX_CORE_RUNTIME_SOURCES ${PRIVATE_DIR}/mx/core/Attribution.cpp ${PRIVATE_DIR}/mx/core/Attribution.h @@ -73,6 +73,8 @@ set(MX_CORE_RUNTIME_SOURCES ${PRIVATE_DIR}/mx/core/NameToken.cpp ${PRIVATE_DIR}/mx/core/NameToken.h ${PRIVATE_DIR}/mx/core/OneOrMore.h + ${PRIVATE_DIR}/mx/core/ParseContext.cpp + ${PRIVATE_DIR}/mx/core/ParseContext.h ${PRIVATE_DIR}/mx/core/Result.h ${PRIVATE_DIR}/mx/core/Token.cpp ${PRIVATE_DIR}/mx/core/Token.h diff --git a/gen/cpp/templates/attr_parse_expr.tmpl b/gen/cpp/templates/attr_parse_expr.tmpl index d1bcbed36..c9159ef2d 100644 --- a/gen/cpp/templates/attr_parse_expr.tmpl +++ b/gen/cpp/templates/attr_parse_expr.tmpl @@ -1 +1 @@ -{{#type_ref.is_value}}{{type_ref.ident}}::parse(a.value()){{/type_ref.is_value}}{{#type_ref.name_token}}{{type_ref.ident}}::parse(a.value()){{/type_ref.name_token}}{{#type_ref.is_primitive_string}}{{^type_ref.name_token}}std::string{a.value()}{{/type_ref.name_token}}{{/type_ref.is_primitive_string}}{{#type_ref.is_primitive_integer}}parseInt(a.value()){{/type_ref.is_primitive_integer}}{{#type_ref.is_primitive_decimal}}Decimal::parse(a.value()){{/type_ref.is_primitive_decimal}} \ No newline at end of file +{{#type_ref.is_value}}parseValue<{{type_ref.ident}}>(a.value(), context, el, {{name.wire_q}}){{/type_ref.is_value}}{{#type_ref.name_token}}{{type_ref.ident}}::parse(a.value()){{/type_ref.name_token}}{{#type_ref.is_primitive_string}}{{^type_ref.name_token}}std::string{a.value()}{{/type_ref.name_token}}{{/type_ref.is_primitive_string}}{{#type_ref.is_primitive_integer}}parseIntegerValue(a.value(), context, el, {{name.wire_q}}){{/type_ref.is_primitive_integer}}{{#type_ref.is_primitive_decimal}}parseDecimalValue(a.value(), context, el, {{name.wire_q}}){{/type_ref.is_primitive_decimal}} \ No newline at end of file diff --git a/gen/cpp/templates/attributes_parse.tmpl b/gen/cpp/templates/attributes_parse.tmpl index 3c54b15ad..8b1ad7e85 100644 --- a/gen/cpp/templates/attributes_parse.tmpl +++ b/gen/cpp/templates/attributes_parse.tmpl @@ -34,6 +34,7 @@ {{#import_default}} // Configured import repair (plan ยง2.4): inject the default. out.set{{name.pascal}}({{>attr_default_expr}}); + reportAttributeDefaulted(context, el, {{name.wire_q}}, {{import_default_q}}); {{/import_default}} {{^import_default}} throwMissingAttribute(el, {{name.wire_q}}); diff --git a/gen/cpp/templates/attrs.cpp.tmpl b/gen/cpp/templates/attrs.cpp.tmpl index 682c910d2..437568e77 100644 --- a/gen/cpp/templates/attrs.cpp.tmpl +++ b/gen/cpp/templates/attrs.cpp.tmpl @@ -3,6 +3,7 @@ #include "mx/core/generated/{{name.pascal}}.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -12,16 +13,27 @@ namespace {{vars.namespace}} {{>attributes_impl}} {{ident}} parse{{ident}}(pugi::xml_node el) +{ + return parse{{ident}}(el, ParseContext{}); +} + +{{ident}} parse{{ident}}(pugi::xml_node el, const ParseContext &context) { {{ident}} out; {{>attributes_parse}} - parse{{ident}}Content(out, el); + parse{{ident}}Content(out, el, context); return out; } void parse{{ident}}Content({{ident}} &out, pugi::xml_node el) +{ + parse{{ident}}Content(out, el, ParseContext{}); +} + +void parse{{ident}}Content({{ident}} &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/gen/cpp/templates/attrs.h.tmpl b/gen/cpp/templates/attrs.h.tmpl index 5b0feb2a1..7cfeb7e96 100644 --- a/gen/cpp/templates/attrs.h.tmpl +++ b/gen/cpp/templates/attrs.h.tmpl @@ -24,6 +24,8 @@ class xml_node; namespace {{vars.namespace}} { +class ParseContext; + {{#doc_lines}} /// {{value}} {{/doc_lines}} @@ -39,8 +41,12 @@ private: {{ident}} parse{{ident}}(pugi::xml_node el); +{{ident}} parse{{ident}}(pugi::xml_node el, const ParseContext &context); + void parse{{ident}}Content({{ident}} &out, pugi::xml_node el); +void parse{{ident}}Content({{ident}} &out, pugi::xml_node el, const ParseContext &context); + void serialize{{ident}}(const {{ident}} &v, pugi::xml_node parent, const char *tag); void serialize{{ident}}Content(const {{ident}} &v, pugi::xml_node el); diff --git a/gen/cpp/templates/choice.cpp.tmpl b/gen/cpp/templates/choice.cpp.tmpl index 3b7584467..7801762e9 100644 --- a/gen/cpp/templates/choice.cpp.tmpl +++ b/gen/cpp/templates/choice.cpp.tmpl @@ -3,6 +3,7 @@ #include "mx/core/generated/{{name.pascal}}.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -27,6 +28,11 @@ namespace {{vars.namespace}} {{/alternatives}} {{ident}} parse{{ident}}(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parse{{ident}}(el, cursor, ParseContext{}); +} + +{{ident}} parse{{ident}}(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { {{#alternatives}} if ({{>field_first_match}}) @@ -60,21 +66,21 @@ namespace {{vars.namespace}} {{/is_element}} {{^is_element}} {{#is_required}} - return {{type.ident}}::{{ident}}(parse{{type_ref.ident}}(el, cursor)); + return {{type.ident}}::{{ident}}(parse{{type_ref.ident}}(el, cursor, context)); {{/is_required}} {{#is_vector}} {{#min1}} - OneOrMore<{{type_ref.ident}}> items{parse{{type_ref.ident}}(el, cursor)}; + OneOrMore<{{type_ref.ident}}> items{parse{{type_ref.ident}}(el, cursor, context)}; while ({{>field_first_match}}) { - items.add(parse{{type_ref.ident}}(el, cursor)); + items.add(parse{{type_ref.ident}}(el, cursor, context)); } {{/min1}} {{^min1}} std::vector<{{type_ref.ident}}> items; while ({{>field_first_match}}) { - items.push_back(parse{{type_ref.ident}}(el, cursor)); + items.push_back(parse{{type_ref.ident}}(el, cursor, context)); } {{/min1}} return {{type.ident}}::{{ident}}(std::move(items)); diff --git a/gen/cpp/templates/choice.h.tmpl b/gen/cpp/templates/choice.h.tmpl index 69200ef2e..124846b13 100644 --- a/gen/cpp/templates/choice.h.tmpl +++ b/gen/cpp/templates/choice.h.tmpl @@ -25,6 +25,8 @@ class xml_node; namespace {{vars.namespace}} { +class ParseContext; + {{#doc_lines}} /// {{value}} {{/doc_lines}} @@ -89,6 +91,8 @@ private: /// the enclosing element, for error paths. {{ident}} parse{{ident}}(pugi::xml_node el, pugi::xml_node &cursor); +{{ident}} parse{{ident}}(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serialize{{ident}}(const {{ident}} &v, pugi::xml_node el); } // namespace {{vars.namespace}} diff --git a/gen/cpp/templates/choice_boxed.cpp.tmpl b/gen/cpp/templates/choice_boxed.cpp.tmpl index 7b1063a93..78eba435b 100644 --- a/gen/cpp/templates/choice_boxed.cpp.tmpl +++ b/gen/cpp/templates/choice_boxed.cpp.tmpl @@ -2,6 +2,7 @@ #include "mx/core/generated/{{name.pascal}}.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -55,11 +56,16 @@ bool {{ident}}::operator==(const {{ident}} &other) const {{/alternatives}} {{ident}} parse{{ident}}(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parse{{ident}}(el, cursor, ParseContext{}); +} + +{{ident}} parse{{ident}}(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { {{#alternatives}} if (cursorIs(cursor, {{tag_q}})) { - {{type_ref.ident}} value = parse{{type_ref.ident}}(cursor); + {{type_ref.ident}} value = parse{{type_ref.ident}}(cursor, context); cursor = nextElement(cursor); return {{type.ident}}::{{ident}}(std::move(value)); } diff --git a/gen/cpp/templates/choice_boxed.h.tmpl b/gen/cpp/templates/choice_boxed.h.tmpl index 14e333b15..a639d64d4 100644 --- a/gen/cpp/templates/choice_boxed.h.tmpl +++ b/gen/cpp/templates/choice_boxed.h.tmpl @@ -18,6 +18,8 @@ class xml_node; namespace {{vars.namespace}} { +class ParseContext; + {{#doc_lines}} /// {{value}} {{/doc_lines}} @@ -91,6 +93,8 @@ private: /// the enclosing element, for error paths. {{ident}} parse{{ident}}(pugi::xml_node el, pugi::xml_node &cursor); +{{ident}} parse{{ident}}(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serialize{{ident}}(const {{ident}} &v, pugi::xml_node el); } // namespace {{vars.namespace}} diff --git a/gen/cpp/templates/composite.cpp.tmpl b/gen/cpp/templates/composite.cpp.tmpl index 29f85c195..a98eaa364 100644 --- a/gen/cpp/templates/composite.cpp.tmpl +++ b/gen/cpp/templates/composite.cpp.tmpl @@ -3,6 +3,7 @@ #include "mx/core/generated/{{name.pascal}}.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -13,14 +14,24 @@ namespace {{vars.namespace}} {{>attributes_impl}} {{>fields_impl}} {{ident}} parse{{ident}}(pugi::xml_node el) +{ + return parse{{ident}}(el, ParseContext{}); +} + +{{ident}} parse{{ident}}(pugi::xml_node el, const ParseContext &context) { {{ident}} out; {{>attributes_parse}} - parse{{ident}}Content(out, el); + parse{{ident}}Content(out, el, context); return out; } void parse{{ident}}Content({{ident}} &out, pugi::xml_node el) +{ + parse{{ident}}Content(out, el, ParseContext{}); +} + +void parse{{ident}}Content({{ident}} &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); {{>fields_parse}} diff --git a/gen/cpp/templates/composite.h.tmpl b/gen/cpp/templates/composite.h.tmpl index feaa84f37..4e1dee3f6 100644 --- a/gen/cpp/templates/composite.h.tmpl +++ b/gen/cpp/templates/composite.h.tmpl @@ -32,6 +32,8 @@ class xml_node; namespace {{vars.namespace}} { +class ParseContext; + {{#doc_lines}} /// {{value}} {{/doc_lines}} @@ -51,8 +53,12 @@ private: {{ident}} parse{{ident}}(pugi::xml_node el); +{{ident}} parse{{ident}}(pugi::xml_node el, const ParseContext &context); + void parse{{ident}}Content({{ident}} &out, pugi::xml_node el); +void parse{{ident}}Content({{ident}} &out, pugi::xml_node el, const ParseContext &context); + void serialize{{ident}}(const {{ident}} &v, pugi::xml_node parent, const char *tag); void serialize{{ident}}Content(const {{ident}} &v, pugi::xml_node el); diff --git a/gen/cpp/templates/derived.cpp.tmpl b/gen/cpp/templates/derived.cpp.tmpl index 600c05924..5833a06bf 100644 --- a/gen/cpp/templates/derived.cpp.tmpl +++ b/gen/cpp/templates/derived.cpp.tmpl @@ -3,6 +3,7 @@ #include "mx/core/generated/{{name.pascal}}.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -12,10 +13,15 @@ namespace {{vars.namespace}} {{>attributes_impl}} {{ident}} parse{{ident}}(pugi::xml_node el) +{ + return parse{{ident}}(el, ParseContext{}); +} + +{{ident}} parse{{ident}}(pugi::xml_node el, const ParseContext &context) { {{ident}} out; {{>attributes_parse}} - parse{{base.ident}}Content(out, el); + parse{{base.ident}}Content(out, el, context); return out; } diff --git a/gen/cpp/templates/derived.h.tmpl b/gen/cpp/templates/derived.h.tmpl index ddc72c1b2..41e2098b1 100644 --- a/gen/cpp/templates/derived.h.tmpl +++ b/gen/cpp/templates/derived.h.tmpl @@ -24,6 +24,8 @@ class xml_node; namespace {{vars.namespace}} { +class ParseContext; + {{#doc_lines}} /// {{value}} {{/doc_lines}} @@ -41,6 +43,8 @@ private: {{ident}} parse{{ident}}(pugi::xml_node el); +{{ident}} parse{{ident}}(pugi::xml_node el, const ParseContext &context); + void serialize{{ident}}(const {{ident}} &v, pugi::xml_node parent, const char *tag); } // namespace {{vars.namespace}} diff --git a/gen/cpp/templates/document.cpp.tmpl b/gen/cpp/templates/document.cpp.tmpl index f2208595a..fef513779 100644 --- a/gen/cpp/templates/document.cpp.tmpl +++ b/gen/cpp/templates/document.cpp.tmpl @@ -4,6 +4,7 @@ #include "mx/core/Error.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/generated/Version.h" #include "mx/core/Xml.h" @@ -14,6 +15,11 @@ namespace {{vars.namespace}} { Result parse(const pugi::xml_document &doc) +{ + return parse(doc, ParseContext{}); +} + +Result parse(const pugi::xml_document &doc, const ParseContext &context) { try { @@ -42,7 +48,7 @@ Result parse(const pugi::xml_document &doc) {{#roots}} {{#is_first}}if{{/is_first}}{{^is_first}}else if{{/is_first}} (tag == {{name.wire_q}}) { - d = Document{parse{{ident}}(root)}; + d = Document{parse{{ident}}(root, context)}; } {{/roots}} else diff --git a/gen/cpp/templates/document.h.tmpl b/gen/cpp/templates/document.h.tmpl index a9cbf2003..9ff4024cb 100644 --- a/gen/cpp/templates/document.h.tmpl +++ b/gen/cpp/templates/document.h.tmpl @@ -20,6 +20,8 @@ class xml_document; namespace {{vars.namespace}} { +class ParseContext; + /// A namespace declaration preserved verbatim from the parsed root element /// (xmlns, xmlns:xlink, ...): document plumbing, not schema data, but /// round-trip parity requires writing it back. @@ -92,6 +94,8 @@ private: /// SupportedMusicXMLVersion is rejected with unsupportedVersion. Result parse(const pugi::xml_document &doc); +Result parse(const pugi::xml_document &doc, const ParseContext &context); + /// Total for every Document (ยง1.1 guarantees validity): writes the XML /// declaration, the matching DOCTYPE, the preserved root namespace /// declarations, and the typed tree. diff --git a/gen/cpp/templates/empty.cpp.tmpl b/gen/cpp/templates/empty.cpp.tmpl index 47fff5d3f..562ee3380 100644 --- a/gen/cpp/templates/empty.cpp.tmpl +++ b/gen/cpp/templates/empty.cpp.tmpl @@ -2,12 +2,18 @@ #include "mx/core/generated/{{name.pascal}}.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" namespace {{vars.namespace}} { {{ident}} parse{{ident}}(pugi::xml_node el) +{ + return parse{{ident}}(el, ParseContext{}); +} + +{{ident}} parse{{ident}}(pugi::xml_node el, const ParseContext &context) { {{ident}} out; for (pugi::xml_attribute a : el.attributes()) @@ -19,13 +25,19 @@ namespace {{vars.namespace}} } throwUnknownAttribute(el, a.name()); } - parse{{ident}}Content(out, el); + parse{{ident}}Content(out, el, context); return out; } void parse{{ident}}Content({{ident}} &out, pugi::xml_node el) +{ + parse{{ident}}Content(out, el, ParseContext{}); +} + +void parse{{ident}}Content({{ident}} &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/gen/cpp/templates/empty.h.tmpl b/gen/cpp/templates/empty.h.tmpl index f5b392a12..e67ac3bff 100644 --- a/gen/cpp/templates/empty.h.tmpl +++ b/gen/cpp/templates/empty.h.tmpl @@ -10,6 +10,8 @@ class xml_node; namespace {{vars.namespace}} { +class ParseContext; + {{#doc_lines}} /// {{value}} {{/doc_lines}} @@ -24,8 +26,12 @@ public: {{ident}} parse{{ident}}(pugi::xml_node el); +{{ident}} parse{{ident}}(pugi::xml_node el, const ParseContext &context); + void parse{{ident}}Content({{ident}} &out, pugi::xml_node el); +void parse{{ident}}Content({{ident}} &out, pugi::xml_node el, const ParseContext &context); + void serialize{{ident}}(const {{ident}} &v, pugi::xml_node parent, const char *tag); void serialize{{ident}}Content(const {{ident}} &v, pugi::xml_node el); diff --git a/gen/cpp/templates/enum.cpp.tmpl b/gen/cpp/templates/enum.cpp.tmpl index 1b7254392..504fe4b5e 100644 --- a/gen/cpp/templates/enum.cpp.tmpl +++ b/gen/cpp/templates/enum.cpp.tmpl @@ -40,9 +40,15 @@ bool {{ident}}::tryParse(std::string_view text, {{ident}} &out) noexcept } {{ident}} {{ident}}::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +{{ident}} {{ident}}::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { {{ident}} v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/gen/cpp/templates/enum.h.tmpl b/gen/cpp/templates/enum.h.tmpl index bd3fdb8b0..6f063eee9 100644 --- a/gen/cpp/templates/enum.h.tmpl +++ b/gen/cpp/templates/enum.h.tmpl @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace {{vars.namespace}} @@ -44,6 +46,9 @@ public: /// (the import leniency policy; never produces an invalid value). static {{ident}} parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static {{ident}} parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const {{ident}} &other) const noexcept = default; private: diff --git a/gen/cpp/templates/field_parse_expr.tmpl b/gen/cpp/templates/field_parse_expr.tmpl index b98874cf8..19d9ee648 100644 --- a/gen/cpp/templates/field_parse_expr.tmpl +++ b/gen/cpp/templates/field_parse_expr.tmpl @@ -1 +1 @@ -{{#type_ref.is_complex}}parse{{type_ref.ident}}(cursor){{/type_ref.is_complex}}{{#type_ref.is_value}}{{type_ref.ident}}::parse(childText(cursor)){{/type_ref.is_value}}{{#type_ref.is_primitive_string}}std::string{childText(cursor)}{{/type_ref.is_primitive_string}}{{#type_ref.is_primitive_integer}}parseInt(childText(cursor)){{/type_ref.is_primitive_integer}}{{#type_ref.is_primitive_decimal}}Decimal::parse(childText(cursor)){{/type_ref.is_primitive_decimal}} \ No newline at end of file +{{#type_ref.is_complex}}parse{{type_ref.ident}}(cursor, context){{/type_ref.is_complex}}{{#type_ref.is_value}}parseValue<{{type_ref.ident}}>(childText(cursor), context, cursor, nullptr){{/type_ref.is_value}}{{#type_ref.is_primitive_string}}std::string{childText(cursor)}{{/type_ref.is_primitive_string}}{{#type_ref.is_primitive_integer}}parseIntegerValue(childText(cursor), context, cursor, nullptr){{/type_ref.is_primitive_integer}}{{#type_ref.is_primitive_decimal}}parseDecimalValue(childText(cursor), context, cursor, nullptr){{/type_ref.is_primitive_decimal}} \ No newline at end of file diff --git a/gen/cpp/templates/fields_parse.tmpl b/gen/cpp/templates/fields_parse.tmpl index 9c95d5aee..e064ae866 100644 --- a/gen/cpp/templates/fields_parse.tmpl +++ b/gen/cpp/templates/fields_parse.tmpl @@ -15,7 +15,7 @@ if (cursorIs(cursor, {{tag_q}})) { {{#presence}} - parse{{type_ref.ident}}(cursor); + parse{{type_ref.ident}}(cursor, context); out.set{{name.pascal}}(true); {{/presence}} {{^presence}} @@ -59,7 +59,7 @@ {{#is_required}} if ({{>field_first_match}}) { - out.set{{name.pascal}}(parse{{type_ref.ident}}(el, cursor)); + out.set{{name.pascal}}(parse{{type_ref.ident}}(el, cursor, context)); } {{^nullable}} else @@ -71,7 +71,7 @@ {{#is_optional}} if ({{>field_first_match}}) { - out.set{{name.pascal}}(parse{{type_ref.ident}}(el, cursor)); + out.set{{name.pascal}}(parse{{type_ref.ident}}(el, cursor, context)); } {{/is_optional}} {{#is_vector}} @@ -80,16 +80,16 @@ { throwMissingElement(el, {{#first}}{{#is_first}}{{value_q}}{{/is_first}}{{/first}}); } - out.set{{name.pascal}}(OneOrMore<{{type_ref.ident}}>{parse{{type_ref.ident}}(el, cursor)}); + out.set{{name.pascal}}(OneOrMore<{{type_ref.ident}}>{parse{{type_ref.ident}}(el, cursor, context)}); while ({{>field_first_match}}) { - out.add{{name.pascal}}(parse{{type_ref.ident}}(el, cursor)); + out.add{{name.pascal}}(parse{{type_ref.ident}}(el, cursor, context)); } {{/min1}} {{^min1}} while ({{>field_first_match}}) { - out.add{{name.pascal}}(parse{{type_ref.ident}}(el, cursor)); + out.add{{name.pascal}}(parse{{type_ref.ident}}(el, cursor, context)); } {{/min1}} {{/is_vector}} diff --git a/gen/cpp/templates/group.cpp.tmpl b/gen/cpp/templates/group.cpp.tmpl index 63f3c1ffc..3e99197f9 100644 --- a/gen/cpp/templates/group.cpp.tmpl +++ b/gen/cpp/templates/group.cpp.tmpl @@ -3,6 +3,7 @@ #include "mx/core/generated/{{name.pascal}}.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -12,6 +13,11 @@ namespace {{vars.namespace}} {{>fields_impl}} {{ident}} parse{{ident}}(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parse{{ident}}(el, cursor, ParseContext{}); +} + +{{ident}} parse{{ident}}(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { {{ident}} out; {{>fields_parse}} diff --git a/gen/cpp/templates/group.h.tmpl b/gen/cpp/templates/group.h.tmpl index 04e4e19b6..1dbae5925 100644 --- a/gen/cpp/templates/group.h.tmpl +++ b/gen/cpp/templates/group.h.tmpl @@ -28,6 +28,8 @@ class xml_node; namespace {{vars.namespace}} { +class ParseContext; + {{#doc_lines}} /// {{value}} {{/doc_lines}} @@ -48,6 +50,8 @@ private: /// is the enclosing element, for error paths. {{ident}} parse{{ident}}(pugi::xml_node el, pugi::xml_node &cursor); +{{ident}} parse{{ident}}(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serialize{{ident}}(const {{ident}} &v, pugi::xml_node el); } // namespace {{vars.namespace}} diff --git a/gen/cpp/templates/number.cpp.tmpl b/gen/cpp/templates/number.cpp.tmpl index b08d6cb82..2eec2c57e 100644 --- a/gen/cpp/templates/number.cpp.tmpl +++ b/gen/cpp/templates/number.cpp.tmpl @@ -53,30 +53,39 @@ std::string {{ident}}::toString() const bool {{ident}}::tryParse(std::string_view text, {{ident}} &out) { -{{#is_decimal}} - Decimal v; - if (!Decimal::tryParse(text, v)) + ValueParseOutcome outcome = ValueParseOutcome::valid; + {{ident}} parsed = parse(text, outcome); + if (outcome == ValueParseOutcome::invalid) { return false; } - out = {{ident}}{std::move(v)}; + out = std::move(parsed); + return true; +} + +{{ident}} {{ident}}::parse(std::string_view text) +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +{{ident}} {{ident}}::parse(std::string_view text, ValueParseOutcome &outcome) +{ +{{#is_decimal}} + Decimal v; + if (!Decimal::tryParse(text, v)) {{/is_decimal}} {{#is_integer}} int v{}; if (!tryParseInt(text, v)) +{{/is_integer}} { - return false; + outcome = ValueParseOutcome::invalid; + return {{ident}}{}; } - out = {{ident}}{v}; -{{/is_integer}} - return true; -} - -{{ident}} {{ident}}::parse(std::string_view text) -{ - {{ident}} v; - tryParse(text, v); - return v; + {{ident}} out{v}; + outcome = out.value() == v ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; } } // namespace {{vars.namespace}} diff --git a/gen/cpp/templates/number.h.tmpl b/gen/cpp/templates/number.h.tmpl index 6d7111d82..6d821926f 100644 --- a/gen/cpp/templates/number.h.tmpl +++ b/gen/cpp/templates/number.h.tmpl @@ -5,6 +5,7 @@ {{#is_decimal}} #include "mx/core/Decimal.h" {{/is_decimal}} +#include "mx/core/Lexical.h" #include #include @@ -49,6 +50,9 @@ public: /// Lenient: non-numeric text yields the clamped zero. static {{ident}} parse(std::string_view text); + /// Lenient, and says whether the text was non-numeric or clamped. + static {{ident}} parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const {{ident}} &other) const noexcept = default; private: diff --git a/gen/cpp/templates/string.cpp.tmpl b/gen/cpp/templates/string.cpp.tmpl index 9334f53c7..d015907ea 100644 --- a/gen/cpp/templates/string.cpp.tmpl +++ b/gen/cpp/templates/string.cpp.tmpl @@ -46,4 +46,11 @@ bool {{ident}}::tryParse(std::string_view text, {{ident}} &out) return {{ident}}{std::string{text}}; } +{{ident}} {{ident}}::parse(std::string_view text, ValueParseOutcome &outcome) +{ + {{ident}} out{std::string{text}}; + outcome = out.value() == text ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; +} + } // namespace {{vars.namespace}} diff --git a/gen/cpp/templates/string.h.tmpl b/gen/cpp/templates/string.h.tmpl index f792b77ac..c759b0aa7 100644 --- a/gen/cpp/templates/string.h.tmpl +++ b/gen/cpp/templates/string.h.tmpl @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -37,6 +39,9 @@ public: static {{ident}} parse(std::string_view text); + /// Says whether the text had to be repaired. + static {{ident}} parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const {{ident}} &other) const noexcept = default; private: diff --git a/gen/cpp/templates/union.cpp.tmpl b/gen/cpp/templates/union.cpp.tmpl index e53e6d439..18f962cfb 100644 --- a/gen/cpp/templates/union.cpp.tmpl +++ b/gen/cpp/templates/union.cpp.tmpl @@ -169,12 +169,36 @@ bool {{ident}}::tryParse(std::string_view text, {{ident}} &out) } {{ident}} {{ident}}::parse(std::string_view text) +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +{{ident}} {{ident}}::parse(std::string_view text, ValueParseOutcome &outcome) { {{ident}} out; if (tryParse(text, out)) { + outcome = ValueParseOutcome::valid; +{{#cases}} +{{#has_clamp}} +{{#is_primitive_integer}} + if (int raw{}; out.is{{name.pascal}}() && tryParseInt(text, raw) && out.as{{name.pascal}}() != raw) + { + outcome = ValueParseOutcome::adjusted; + } +{{/is_primitive_integer}} +{{#is_primitive_decimal}} + if (Decimal raw; out.is{{name.pascal}}() && Decimal::tryParse(text, raw) && out.as{{name.pascal}}() != raw) + { + outcome = ValueParseOutcome::adjusted; + } +{{/is_primitive_decimal}} +{{/has_clamp}} +{{/cases}} return out; } + outcome = ValueParseOutcome::invalid; {{#cases}} {{#is_first}} {{#is_literal}} diff --git a/gen/cpp/templates/union.h.tmpl b/gen/cpp/templates/union.h.tmpl index 4d511bfb9..29456aec7 100644 --- a/gen/cpp/templates/union.h.tmpl +++ b/gen/cpp/templates/union.h.tmpl @@ -10,6 +10,7 @@ #include "mx/core/Decimal.h" {{/is_primitive_decimal}} {{/cases}} +#include "mx/core/Lexical.h" #include #include @@ -86,6 +87,10 @@ public: /// parse (never produces an invalid value). static {{ident}} parse(std::string_view text); + /// Lenient, and says whether no member matched or a matched number was + /// clamped. + static {{ident}} parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const {{ident}} &other) const = default; private: diff --git a/gen/cpp/templates/value_class.cpp.tmpl b/gen/cpp/templates/value_class.cpp.tmpl index e96f060cd..64a7a76ad 100644 --- a/gen/cpp/templates/value_class.cpp.tmpl +++ b/gen/cpp/templates/value_class.cpp.tmpl @@ -3,6 +3,7 @@ #include "mx/core/generated/{{name.pascal}}.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -24,17 +25,27 @@ void {{type.ident}}::set{{name.pascal}}({{type_ref.ident}} value) {{/value}} {{ident}} parse{{ident}}(pugi::xml_node el) +{ + return parse{{ident}}(el, ParseContext{}); +} + +{{ident}} parse{{ident}}(pugi::xml_node el, const ParseContext &context) { {{ident}} out; {{>attributes_parse}} - parse{{ident}}Content(out, el); + parse{{ident}}Content(out, el, context); return out; } void parse{{ident}}Content({{ident}} &out, pugi::xml_node el) +{ + parse{{ident}}Content(out, el, ParseContext{}); +} + +void parse{{ident}}Content({{ident}} &out, pugi::xml_node el, const ParseContext &context) { {{#value}} - out.set{{name.pascal}}({{#type_ref.is_value}}{{type_ref.ident}}::parse(childText(el)){{/type_ref.is_value}}{{#type_ref.is_primitive_string}}std::string{childText(el)}{{/type_ref.is_primitive_string}}{{#type_ref.is_primitive_integer}}parseInt(childText(el)){{/type_ref.is_primitive_integer}}{{#type_ref.is_primitive_decimal}}Decimal::parse(childText(el)){{/type_ref.is_primitive_decimal}}); + out.set{{name.pascal}}({{#type_ref.is_value}}parseValue<{{type_ref.ident}}>(childText(el), context, el, nullptr){{/type_ref.is_value}}{{#type_ref.is_primitive_string}}std::string{childText(el)}{{/type_ref.is_primitive_string}}{{#type_ref.is_primitive_integer}}parseIntegerValue(childText(el), context, el, nullptr){{/type_ref.is_primitive_integer}}{{#type_ref.is_primitive_decimal}}parseDecimalValue(childText(el), context, el, nullptr){{/type_ref.is_primitive_decimal}}); {{/value}} if (firstElement(el)) { diff --git a/gen/cpp/templates/value_class.h.tmpl b/gen/cpp/templates/value_class.h.tmpl index 2b943cea4..7360d959e 100644 --- a/gen/cpp/templates/value_class.h.tmpl +++ b/gen/cpp/templates/value_class.h.tmpl @@ -24,6 +24,8 @@ class xml_node; namespace {{vars.namespace}} { +class ParseContext; + {{#doc_lines}} /// {{value}} {{/doc_lines}} @@ -46,8 +48,12 @@ private: {{ident}} parse{{ident}}(pugi::xml_node el); +{{ident}} parse{{ident}}(pugi::xml_node el, const ParseContext &context); + void parse{{ident}}Content({{ident}} &out, pugi::xml_node el); +void parse{{ident}}Content({{ident}} &out, pugi::xml_node el, const ParseContext &context); + void serialize{{ident}}(const {{ident}} &v, pugi::xml_node parent, const char *tag); void serialize{{ident}}Content(const {{ident}} &v, pugi::xml_node el); diff --git a/src/include/mx/api/Diagnostics.h b/src/include/mx/api/Diagnostics.h index a10063fdb..e4a001bd8 100644 --- a/src/include/mx/api/Diagnostics.h +++ b/src/include/mx/api/Diagnostics.h @@ -26,8 +26,10 @@ enum class Severity // The recoverable decision reported by a diagnostic. enum class DiagnosticCode { - valueAdjusted, // a value was changed to one that MusicXML can represent - unmatchedSpanner // a spanner endpoint had no matching endpoint + valueAdjusted, // a value was changed to one that MusicXML can represent + unmatchedSpanner, // a spanner endpoint had no matching endpoint + invalidValue, // a value could not be read, so a default was used + missingValueDefaulted // a required value was missing, so a default was used }; // A non-fatal problem noticed while producing a score or MusicXML document. diff --git a/src/include/mx/api/MusicXml.h b/src/include/mx/api/MusicXml.h index 83959582f..a3c9c7b68 100644 --- a/src/include/mx/api/MusicXml.h +++ b/src/include/mx/api/MusicXml.h @@ -29,10 +29,19 @@ class MusicXml // represented by an error result. static Result fromFile(const std::string &filePath); + // Parses a MusicXML file and reports values that had to be repaired to + // be read, such as an unknown note type or an octave above 9. The same + // Diagnostics can be passed on to getScore to collect both in one place. + static Result fromFile(const std::string &filePath, Diagnostics &diagnostics); + // Parses a MusicXML document from a character stream. Logical errors and // caught exceptions are represented by an error result. static Result fromStream(std::istream &stream); + // Parses a MusicXML document from a character stream and reports values + // that had to be repaired to be read. + static Result fromStream(std::istream &stream, Diagnostics &diagnostics); + MusicXml(const MusicXml &other) = delete; MusicXml &operator=(const MusicXml &other) = delete; MusicXml(MusicXml &&other); diff --git a/src/private/mx/api/MusicXml.cpp b/src/private/mx/api/MusicXml.cpp index d230b4bec..777402ec3 100644 --- a/src/private/mx/api/MusicXml.cpp +++ b/src/private/mx/api/MusicXml.cpp @@ -5,6 +5,7 @@ #include "mx/api/MusicXml.h" #include "mx/core/Attribution.h" #include "mx/core/Error.h" +#include "mx/core/ParseContext.h" #include "mx/core/generated/Document.h" #include "mx/impl/ScoreConversions.h" #include "mx/impl/ScoreReader.h" @@ -75,6 +76,31 @@ ApiError mirrorToApiError(const core::Error &error) return ApiError{mirrorToApiResultCode(error.code), location, error.message}; } +DiagnosticCode mirrorToApiDiagnosticCode(core::DiagnosticCode code) +{ + switch (code) + { + case core::DiagnosticCode::invalidValue: + return DiagnosticCode::invalidValue; + case core::DiagnosticCode::valueAdjusted: + return DiagnosticCode::valueAdjusted; + case core::DiagnosticCode::missingValueDefaulted: + return DiagnosticCode::missingValueDefaulted; + } + return DiagnosticCode::invalidValue; +} + +// Every import repair leaves a usable document, so each one is a warning. +core::ParseContext parseContextReportingTo(Diagnostics &diagnostics) +{ + return core::ParseContext{[&diagnostics](const core::Diagnostic &diagnostic) { + Location location; + location.xmlPath = diagnostic.path; + diagnostics.add(Diagnostic{Severity::warning, mirrorToApiDiagnosticCode(diagnostic.code), std::move(location), + diagnostic.message}); + }}; +} + // Builds the error for a caught exception. Call it inside a catch block only: // current_exception() keeps the exception alive in `cause`, so a caller can // look at it or throw it again. Most entry points repeat the same three @@ -145,6 +171,12 @@ MusicXml::~MusicXml() } Result MusicXml::fromFile(const std::string &filePath) +{ + Diagnostics diagnostics; + return fromFile(filePath, diagnostics); +} + +Result MusicXml::fromFile(const std::string &filePath, Diagnostics &diagnostics) { try { @@ -171,7 +203,7 @@ Result MusicXml::fromFile(const std::string &filePath) return ApiError{ResultCode::xmlSyntaxError, location, loaded.description()}; } - auto parsed = core::parse(xdoc); + auto parsed = core::parse(xdoc, parseContextReportingTo(diagnostics)); if (!parsed) { return mirrorToApiError(parsed.error()); @@ -194,6 +226,12 @@ Result MusicXml::fromFile(const std::string &filePath) } Result MusicXml::fromStream(std::istream &stream) +{ + Diagnostics diagnostics; + return fromStream(stream, diagnostics); +} + +Result MusicXml::fromStream(std::istream &stream, Diagnostics &diagnostics) { try { @@ -206,7 +244,7 @@ Result MusicXml::fromStream(std::istream &stream) return ApiError{ResultCode::xmlSyntaxError, location, loaded.description()}; } - auto parsed = core::parse(xdoc); + auto parsed = core::parse(xdoc, parseContextReportingTo(diagnostics)); if (!parsed) { return mirrorToApiError(parsed.error()); diff --git a/src/private/mx/core/Lexical.h b/src/private/mx/core/Lexical.h index 5e92e2446..cda64f422 100644 --- a/src/private/mx/core/Lexical.h +++ b/src/private/mx/core/Lexical.h @@ -18,6 +18,15 @@ namespace mx::core // nothing else). The lenient flavors return 0 on garbage โ€” the import // leniency policy (plan ยง2.4); range clamping happens in the caller. +/// What a lenient value parse did with its input. Import diagnostics are +/// built from this; the parsed value is the same whatever the outcome says. +enum class ValueParseOutcome +{ + valid, // the text was already a valid value + invalid, // the text could not be read, so a default was used + adjusted, // the text was readable but was changed to a valid value +}; + /// The input minus leading/trailing XML whitespace. std::string_view trimWhitespace(std::string_view text); diff --git a/src/private/mx/core/ParseContext.cpp b/src/private/mx/core/ParseContext.cpp new file mode 100644 index 000000000..54b715125 --- /dev/null +++ b/src/private/mx/core/ParseContext.cpp @@ -0,0 +1,77 @@ +// MusicXML Class Library +// Copyright (c) by Matthew James Briggs +// Distributed under the MIT License + +#include "mx/core/ParseContext.h" + +#include "mx/core/Xml.h" + +#include + +namespace mx::core +{ + +ParseContext::ParseContext(DiagnosticHandler handler) : m_handler{std::move(handler)} +{ +} + +void ParseContext::report(Diagnostic diagnostic) const +{ + if (m_handler) + { + m_handler(diagnostic); + } +} + +void reportValueRepair(const ParseContext &context, ValueParseOutcome outcome, pugi::xml_node el, const char *attribute, + std::string_view text, std::string_view replacement) +{ + const bool invalid = outcome == ValueParseOutcome::invalid; + std::string message = invalid ? "invalid value \"" : "value \""; + message += text; + message += "\""; + if (attribute) + { + message += " in attribute \""; + message += attribute; + message += "\""; + } + message += invalid ? "; using \"" : " adjusted to \""; + message += replacement; + message += "\""; + context.report(Diagnostic{invalid ? DiagnosticCode::invalidValue : DiagnosticCode::valueAdjusted, nodePath(el), + std::move(message)}); +} + +void reportAttributeDefaulted(const ParseContext &context, pugi::xml_node el, const char *attribute, + std::string_view value) +{ + std::string message = "missing attribute \""; + message += attribute; + message += "\"; using \""; + message += value; + message += "\""; + context.report(Diagnostic{DiagnosticCode::missingValueDefaulted, nodePath(el), std::move(message)}); +} + +int parseIntegerValue(std::string_view text, const ParseContext &context, pugi::xml_node el, const char *attribute) +{ + int value = 0; + if (!tryParseInt(text, value)) + { + reportValueRepair(context, ValueParseOutcome::invalid, el, attribute, text, formatInt(value)); + } + return value; +} + +Decimal parseDecimalValue(std::string_view text, const ParseContext &context, pugi::xml_node el, const char *attribute) +{ + Decimal value; + if (!Decimal::tryParse(text, value)) + { + reportValueRepair(context, ValueParseOutcome::invalid, el, attribute, text, value.toString()); + } + return value; +} + +} // namespace mx::core diff --git a/src/private/mx/core/ParseContext.h b/src/private/mx/core/ParseContext.h new file mode 100644 index 000000000..499f52bf2 --- /dev/null +++ b/src/private/mx/core/ParseContext.h @@ -0,0 +1,86 @@ +// MusicXML Class Library +// Copyright (c) by Matthew James Briggs +// Distributed under the MIT License + +// Hand-written runtime for the generated mx::core model; never regenerated. + +#pragma once + +#include "mx/core/Decimal.h" +#include "mx/core/Lexical.h" + +#include "pugixml.hpp" + +#include +#include +#include + +namespace mx::core +{ + +/// The repairs the lenient parsers make on import. The parsed document is +/// still valid; a diagnostic tells the caller what was changed. +enum class DiagnosticCode +{ + invalidValue, + valueAdjusted, + missingValueDefaulted, +}; + +struct Diagnostic +{ + DiagnosticCode code; + std::string path; // e.g. /score-partwise/part[1]/measure[3]/note[2] + std::string message; +}; + +using DiagnosticHandler = std::function; + +/// Passed down through the generated parsers so they can report repairs. A +/// default-constructed context discards every report. +class ParseContext +{ + public: + ParseContext() = default; + explicit ParseContext(DiagnosticHandler handler); + + void report(Diagnostic diagnostic) const; + + private: + DiagnosticHandler m_handler; +}; + +/// Reports that the text of `el`, or of its `attribute` when that is not +/// null, was replaced by `replacement`. +void reportValueRepair(const ParseContext &context, ValueParseOutcome outcome, pugi::xml_node el, const char *attribute, + std::string_view text, std::string_view replacement); + +void reportAttributeDefaulted(const ParseContext &context, pugi::xml_node el, const char *attribute, + std::string_view value); + +/// The lenient parse of a value type, reporting any repair it made. A type +/// without an outcome-reporting parse is parsed silently. +template +T parseValue(std::string_view text, const ParseContext &context, pugi::xml_node el, const char *attribute) +{ + if constexpr (requires(std::string_view s, ValueParseOutcome &o) { T::parse(s, o); }) + { + ValueParseOutcome outcome = ValueParseOutcome::valid; + T value = T::parse(text, outcome); + if (outcome != ValueParseOutcome::valid) + { + reportValueRepair(context, outcome, el, attribute, text, std::string{value.toString()}); + } + return value; + } + else + { + return T::parse(text); + } +} + +int parseIntegerValue(std::string_view text, const ParseContext &context, pugi::xml_node el, const char *attribute); + +Decimal parseDecimalValue(std::string_view text, const ParseContext &context, pugi::xml_node el, const char *attribute); + +} // namespace mx::core diff --git a/src/private/mx/core/generated/AboveBelow.cpp b/src/private/mx/core/generated/AboveBelow.cpp index 9997528cc..227737071 100644 --- a/src/private/mx/core/generated/AboveBelow.cpp +++ b/src/private/mx/core/generated/AboveBelow.cpp @@ -42,9 +42,15 @@ bool AboveBelow::tryParse(std::string_view text, AboveBelow &out) noexcept } AboveBelow AboveBelow::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +AboveBelow AboveBelow::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { AboveBelow v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/AboveBelow.h b/src/private/mx/core/generated/AboveBelow.h index f963ddd02..4f2426ae9 100644 --- a/src/private/mx/core/generated/AboveBelow.h +++ b/src/private/mx/core/generated/AboveBelow.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -41,6 +43,9 @@ class AboveBelow final /// (the import leniency policy; never produces an invalid value). static AboveBelow parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static AboveBelow parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const AboveBelow &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Accidental.cpp b/src/private/mx/core/generated/Accidental.cpp index a02255477..627d9eb50 100644 --- a/src/private/mx/core/generated/Accidental.cpp +++ b/src/private/mx/core/generated/Accidental.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Accidental.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -171,6 +172,11 @@ void Accidental::setValue(AccidentalValue value) } Accidental parseAccidental(pugi::xml_node el) +{ + return parseAccidental(el, ParseContext{}); +} + +Accidental parseAccidental(pugi::xml_node el, const ParseContext &context) { Accidental out; for (pugi::xml_attribute a : el.attributes()) @@ -182,76 +188,81 @@ Accidental parseAccidental(pugi::xml_node el) } if (aname == "cautionary") { - out.setCautionary(YesNo::parse(a.value())); + out.setCautionary(parseValue(a.value(), context, el, "cautionary")); } else if (aname == "editorial") { - out.setEditorial(YesNo::parse(a.value())); + out.setEditorial(parseValue(a.value(), context, el, "editorial")); } else if (aname == "smufl") { - out.setSmufl(SmuflAccidentalGlyphName::parse(a.value())); + out.setSmufl(parseValue(a.value(), context, el, "smufl")); } else if (aname == "parentheses") { - out.setParentheses(YesNo::parse(a.value())); + out.setParentheses(parseValue(a.value(), context, el, "parentheses")); } else if (aname == "bracket") { - out.setBracket(YesNo::parse(a.value())); + out.setBracket(parseValue(a.value(), context, el, "bracket")); } else if (aname == "size") { - out.setSize(SymbolSize::parse(a.value())); + out.setSize(parseValue(a.value(), context, el, "size")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else { throwUnknownAttribute(el, a.name()); } } - parseAccidentalContent(out, el); + parseAccidentalContent(out, el, context); return out; } void parseAccidentalContent(Accidental &out, pugi::xml_node el) { - out.setValue(AccidentalValue::parse(childText(el))); + parseAccidentalContent(out, el, ParseContext{}); +} + +void parseAccidentalContent(Accidental &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Accidental.h b/src/private/mx/core/generated/Accidental.h index 46ba0411f..7e3d48486 100644 --- a/src/private/mx/core/generated/Accidental.h +++ b/src/private/mx/core/generated/Accidental.h @@ -24,6 +24,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The accidental type represents actual notated accidentals. Editorial and cautionary indications /// are indicated by attributes. Values for these attributes are "no" if not present. Specific /// graphic display such as parentheses, brackets, and size are controlled by the level-display @@ -86,8 +88,12 @@ class Accidental final Accidental parseAccidental(pugi::xml_node el); +Accidental parseAccidental(pugi::xml_node el, const ParseContext &context); + void parseAccidentalContent(Accidental &out, pugi::xml_node el); +void parseAccidentalContent(Accidental &out, pugi::xml_node el, const ParseContext &context); + void serializeAccidental(const Accidental &v, pugi::xml_node parent, const char *tag); void serializeAccidentalContent(const Accidental &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/AccidentalMark.cpp b/src/private/mx/core/generated/AccidentalMark.cpp index f8e3a3d9d..d4169f862 100644 --- a/src/private/mx/core/generated/AccidentalMark.cpp +++ b/src/private/mx/core/generated/AccidentalMark.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/AccidentalMark.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -171,6 +172,11 @@ void AccidentalMark::setValue(AccidentalValue value) } AccidentalMark parseAccidentalMark(pugi::xml_node el) +{ + return parseAccidentalMark(el, ParseContext{}); +} + +AccidentalMark parseAccidentalMark(pugi::xml_node el, const ParseContext &context) { AccidentalMark out; for (pugi::xml_attribute a : el.attributes()) @@ -182,59 +188,59 @@ AccidentalMark parseAccidentalMark(pugi::xml_node el) } if (aname == "smufl") { - out.setSmufl(SmuflAccidentalGlyphName::parse(a.value())); + out.setSmufl(parseValue(a.value(), context, el, "smufl")); } else if (aname == "parentheses") { - out.setParentheses(YesNo::parse(a.value())); + out.setParentheses(parseValue(a.value(), context, el, "parentheses")); } else if (aname == "bracket") { - out.setBracket(YesNo::parse(a.value())); + out.setBracket(parseValue(a.value(), context, el, "bracket")); } else if (aname == "size") { - out.setSize(SymbolSize::parse(a.value())); + out.setSize(parseValue(a.value(), context, el, "size")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else if (aname == "id") { @@ -245,13 +251,18 @@ AccidentalMark parseAccidentalMark(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseAccidentalMarkContent(out, el); + parseAccidentalMarkContent(out, el, context); return out; } void parseAccidentalMarkContent(AccidentalMark &out, pugi::xml_node el) { - out.setValue(AccidentalValue::parse(childText(el))); + parseAccidentalMarkContent(out, el, ParseContext{}); +} + +void parseAccidentalMarkContent(AccidentalMark &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/AccidentalMark.h b/src/private/mx/core/generated/AccidentalMark.h index 6c5338130..c8f2dd66f 100644 --- a/src/private/mx/core/generated/AccidentalMark.h +++ b/src/private/mx/core/generated/AccidentalMark.h @@ -27,6 +27,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// An accidental-mark can be used as a separate notation or as part of an ornament. When used in an /// ornament, position and placement are relative to the ornament, not relative to the note. class AccidentalMark final @@ -87,8 +89,12 @@ class AccidentalMark final AccidentalMark parseAccidentalMark(pugi::xml_node el); +AccidentalMark parseAccidentalMark(pugi::xml_node el, const ParseContext &context); + void parseAccidentalMarkContent(AccidentalMark &out, pugi::xml_node el); +void parseAccidentalMarkContent(AccidentalMark &out, pugi::xml_node el, const ParseContext &context); + void serializeAccidentalMark(const AccidentalMark &v, pugi::xml_node parent, const char *tag); void serializeAccidentalMarkContent(const AccidentalMark &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/AccidentalText.cpp b/src/private/mx/core/generated/AccidentalText.cpp index 44adff9a2..545f510f8 100644 --- a/src/private/mx/core/generated/AccidentalText.cpp +++ b/src/private/mx/core/generated/AccidentalText.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/AccidentalText.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -251,6 +252,11 @@ void AccidentalText::setValue(AccidentalValue value) } AccidentalText parseAccidentalText(pugi::xml_node el) +{ + return parseAccidentalText(el, ParseContext{}); +} + +AccidentalText parseAccidentalText(pugi::xml_node el, const ParseContext &context) { AccidentalText out; for (pugi::xml_attribute a : el.attributes()) @@ -262,7 +268,7 @@ AccidentalText parseAccidentalText(pugi::xml_node el) } if (aname == "smufl") { - out.setSmufl(SmuflAccidentalGlyphName::parse(a.value())); + out.setSmufl(parseValue(a.value(), context, el, "smufl")); } else if (aname == "xml:lang") { @@ -274,96 +280,101 @@ AccidentalText parseAccidentalText(pugi::xml_node el) } else if (aname == "justify") { - out.setJustify(LeftCenterRight::parse(a.value())); + out.setJustify(parseValue(a.value(), context, el, "justify")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "halign") { - out.setHalign(LeftCenterRight::parse(a.value())); + out.setHalign(parseValue(a.value(), context, el, "halign")); } else if (aname == "valign") { - out.setValign(Valign::parse(a.value())); + out.setValign(parseValue(a.value(), context, el, "valign")); } else if (aname == "underline") { - out.setUnderline(NumberOfLines::parse(a.value())); + out.setUnderline(parseValue(a.value(), context, el, "underline")); } else if (aname == "overline") { - out.setOverline(NumberOfLines::parse(a.value())); + out.setOverline(parseValue(a.value(), context, el, "overline")); } else if (aname == "line-through") { - out.setLineThrough(NumberOfLines::parse(a.value())); + out.setLineThrough(parseValue(a.value(), context, el, "line-through")); } else if (aname == "rotation") { - out.setRotation(RotationDegrees::parse(a.value())); + out.setRotation(parseValue(a.value(), context, el, "rotation")); } else if (aname == "letter-spacing") { - out.setLetterSpacing(NumberOrNormal::parse(a.value())); + out.setLetterSpacing(parseValue(a.value(), context, el, "letter-spacing")); } else if (aname == "line-height") { - out.setLineHeight(NumberOrNormal::parse(a.value())); + out.setLineHeight(parseValue(a.value(), context, el, "line-height")); } else if (aname == "dir") { - out.setDir(TextDirection::parse(a.value())); + out.setDir(parseValue(a.value(), context, el, "dir")); } else if (aname == "enclosure") { - out.setEnclosure(EnclosureShape::parse(a.value())); + out.setEnclosure(parseValue(a.value(), context, el, "enclosure")); } else { throwUnknownAttribute(el, a.name()); } } - parseAccidentalTextContent(out, el); + parseAccidentalTextContent(out, el, context); return out; } void parseAccidentalTextContent(AccidentalText &out, pugi::xml_node el) { - out.setValue(AccidentalValue::parse(childText(el))); + parseAccidentalTextContent(out, el, ParseContext{}); +} + +void parseAccidentalTextContent(AccidentalText &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/AccidentalText.h b/src/private/mx/core/generated/AccidentalText.h index 19934a7db..f1329b181 100644 --- a/src/private/mx/core/generated/AccidentalText.h +++ b/src/private/mx/core/generated/AccidentalText.h @@ -29,6 +29,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The accidental-text type represents an element with an accidental value and text-formatting /// attributes. class AccidentalText final @@ -113,8 +115,12 @@ class AccidentalText final AccidentalText parseAccidentalText(pugi::xml_node el); +AccidentalText parseAccidentalText(pugi::xml_node el, const ParseContext &context); + void parseAccidentalTextContent(AccidentalText &out, pugi::xml_node el); +void parseAccidentalTextContent(AccidentalText &out, pugi::xml_node el, const ParseContext &context); + void serializeAccidentalText(const AccidentalText &v, pugi::xml_node parent, const char *tag); void serializeAccidentalTextContent(const AccidentalText &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/AccidentalValue.cpp b/src/private/mx/core/generated/AccidentalValue.cpp index 08eea51b2..713b461bc 100644 --- a/src/private/mx/core/generated/AccidentalValue.cpp +++ b/src/private/mx/core/generated/AccidentalValue.cpp @@ -276,9 +276,15 @@ bool AccidentalValue::tryParse(std::string_view text, AccidentalValue &out) noex } AccidentalValue AccidentalValue::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +AccidentalValue AccidentalValue::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { AccidentalValue v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/AccidentalValue.h b/src/private/mx/core/generated/AccidentalValue.h index a7b6c6748..e89d21f80 100644 --- a/src/private/mx/core/generated/AccidentalValue.h +++ b/src/private/mx/core/generated/AccidentalValue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -128,6 +130,9 @@ class AccidentalValue final /// (the import leniency policy; never produces an invalid value). static AccidentalValue parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static AccidentalValue parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const AccidentalValue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Accord.cpp b/src/private/mx/core/generated/Accord.cpp index 059974d57..0ac13bb18 100644 --- a/src/private/mx/core/generated/Accord.cpp +++ b/src/private/mx/core/generated/Accord.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Accord.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void Accord::setTuning(TuningGroup value) } Accord parseAccord(pugi::xml_node el) +{ + return parseAccord(el, ParseContext{}); +} + +Accord parseAccord(pugi::xml_node el, const ParseContext &context) { Accord out; for (pugi::xml_attribute a : el.attributes()) @@ -42,23 +48,28 @@ Accord parseAccord(pugi::xml_node el) } if (aname == "string") { - out.setString(StringNumber::parse(a.value())); + out.setString(parseValue(a.value(), context, el, "string")); } else { throwUnknownAttribute(el, a.name()); } } - parseAccordContent(out, el); + parseAccordContent(out, el, context); return out; } void parseAccordContent(Accord &out, pugi::xml_node el) +{ + parseAccordContent(out, el, ParseContext{}); +} + +void parseAccordContent(Accord &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "tuning-step"))) { - out.setTuning(parseTuningGroup(el, cursor)); + out.setTuning(parseTuningGroup(el, cursor, context)); } else { diff --git a/src/private/mx/core/generated/Accord.h b/src/private/mx/core/generated/Accord.h index 0f13c4e14..dc868aa65 100644 --- a/src/private/mx/core/generated/Accord.h +++ b/src/private/mx/core/generated/Accord.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The accord type represents the tuning of a single string in the scordatura element. It uses the /// same group of elements as the staff-tuning element. Strings are numbered from high to low. /// Content fields mirror the schema grammar in declaration order; the @@ -38,8 +40,12 @@ class Accord final Accord parseAccord(pugi::xml_node el); +Accord parseAccord(pugi::xml_node el, const ParseContext &context); + void parseAccordContent(Accord &out, pugi::xml_node el); +void parseAccordContent(Accord &out, pugi::xml_node el, const ParseContext &context); + void serializeAccord(const Accord &v, pugi::xml_node parent, const char *tag); void serializeAccordContent(const Accord &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/AccordionMiddle.cpp b/src/private/mx/core/generated/AccordionMiddle.cpp index 03c0dde6d..618d74275 100644 --- a/src/private/mx/core/generated/AccordionMiddle.cpp +++ b/src/private/mx/core/generated/AccordionMiddle.cpp @@ -42,20 +42,33 @@ std::string AccordionMiddle::toString() const bool AccordionMiddle::tryParse(std::string_view text, AccordionMiddle &out) { - int v{}; - if (!tryParseInt(text, v)) + ValueParseOutcome outcome = ValueParseOutcome::valid; + AccordionMiddle parsed = parse(text, outcome); + if (outcome == ValueParseOutcome::invalid) { return false; } - out = AccordionMiddle{v}; + out = std::move(parsed); return true; } AccordionMiddle AccordionMiddle::parse(std::string_view text) { - AccordionMiddle v; - tryParse(text, v); - return v; + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +AccordionMiddle AccordionMiddle::parse(std::string_view text, ValueParseOutcome &outcome) +{ + int v{}; + if (!tryParseInt(text, v)) + { + outcome = ValueParseOutcome::invalid; + return AccordionMiddle{}; + } + AccordionMiddle out{v}; + outcome = out.value() == v ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; } } // namespace mx::core diff --git a/src/private/mx/core/generated/AccordionMiddle.h b/src/private/mx/core/generated/AccordionMiddle.h index 83e0ae95e..87faf5d34 100644 --- a/src/private/mx/core/generated/AccordionMiddle.h +++ b/src/private/mx/core/generated/AccordionMiddle.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -37,6 +39,9 @@ class AccordionMiddle final /// Lenient: non-numeric text yields the clamped zero. static AccordionMiddle parse(std::string_view text); + /// Lenient, and says whether the text was non-numeric or clamped. + static AccordionMiddle parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const AccordionMiddle &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/AccordionRegistration.cpp b/src/private/mx/core/generated/AccordionRegistration.cpp index f3f25f5af..86f99b6f2 100644 --- a/src/private/mx/core/generated/AccordionRegistration.cpp +++ b/src/private/mx/core/generated/AccordionRegistration.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/AccordionRegistration.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -161,6 +162,11 @@ void AccordionRegistration::setAccordionLow(bool value) noexcept } AccordionRegistration parseAccordionRegistration(pugi::xml_node el) +{ + return parseAccordionRegistration(el, ParseContext{}); +} + +AccordionRegistration parseAccordionRegistration(pugi::xml_node el, const ParseContext &context) { AccordionRegistration out; for (pugi::xml_attribute a : el.attributes()) @@ -172,47 +178,47 @@ AccordionRegistration parseAccordionRegistration(pugi::xml_node el) } if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "halign") { - out.setHalign(LeftCenterRight::parse(a.value())); + out.setHalign(parseValue(a.value(), context, el, "halign")); } else if (aname == "valign") { - out.setValign(Valign::parse(a.value())); + out.setValign(parseValue(a.value(), context, el, "valign")); } else if (aname == "id") { @@ -223,27 +229,32 @@ AccordionRegistration parseAccordionRegistration(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseAccordionRegistrationContent(out, el); + parseAccordionRegistrationContent(out, el, context); return out; } void parseAccordionRegistrationContent(AccordionRegistration &out, pugi::xml_node el) +{ + parseAccordionRegistrationContent(out, el, ParseContext{}); +} + +void parseAccordionRegistrationContent(AccordionRegistration &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "accordion-high")) { - parseEmpty(cursor); + parseEmpty(cursor, context); out.setAccordionHigh(true); cursor = nextElement(cursor); } if (cursorIs(cursor, "accordion-middle")) { - out.setAccordionMiddle(AccordionMiddle::parse(childText(cursor))); + out.setAccordionMiddle(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (cursorIs(cursor, "accordion-low")) { - parseEmpty(cursor); + parseEmpty(cursor, context); out.setAccordionLow(true); cursor = nextElement(cursor); } diff --git a/src/private/mx/core/generated/AccordionRegistration.h b/src/private/mx/core/generated/AccordionRegistration.h index c026e6bf2..486542a39 100644 --- a/src/private/mx/core/generated/AccordionRegistration.h +++ b/src/private/mx/core/generated/AccordionRegistration.h @@ -28,6 +28,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The accordion-registration type is used for accordion registration symbols. These are circular /// symbols divided horizontally into high, middle, and low sections that correspond to 4', 8', and /// 16' pipes. Each accordion-high, accordion-middle, and accordion-low element represents the @@ -90,8 +92,12 @@ class AccordionRegistration final AccordionRegistration parseAccordionRegistration(pugi::xml_node el); +AccordionRegistration parseAccordionRegistration(pugi::xml_node el, const ParseContext &context); + void parseAccordionRegistrationContent(AccordionRegistration &out, pugi::xml_node el); +void parseAccordionRegistrationContent(AccordionRegistration &out, pugi::xml_node el, const ParseContext &context); + void serializeAccordionRegistration(const AccordionRegistration &v, pugi::xml_node parent, const char *tag); void serializeAccordionRegistrationContent(const AccordionRegistration &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/AllMarginsGroup.cpp b/src/private/mx/core/generated/AllMarginsGroup.cpp index 56a0afa20..7616f8fb4 100644 --- a/src/private/mx/core/generated/AllMarginsGroup.cpp +++ b/src/private/mx/core/generated/AllMarginsGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/AllMarginsGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,11 +42,16 @@ void AllMarginsGroup::setBottomMargin(Tenths value) } AllMarginsGroup parseAllMarginsGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseAllMarginsGroup(el, cursor, ParseContext{}); +} + +AllMarginsGroup parseAllMarginsGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { AllMarginsGroup out; if (cursor && (cursorIs(cursor, "left-margin"))) { - out.setLeftRightMargins(parseLeftRightMarginsGroup(el, cursor)); + out.setLeftRightMargins(parseLeftRightMarginsGroup(el, cursor, context)); } else { @@ -53,7 +59,7 @@ AllMarginsGroup parseAllMarginsGroup(pugi::xml_node el, pugi::xml_node &cursor) } if (cursorIs(cursor, "top-margin")) { - out.setTopMargin(Tenths::parse(childText(cursor))); + out.setTopMargin(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -62,7 +68,7 @@ AllMarginsGroup parseAllMarginsGroup(pugi::xml_node el, pugi::xml_node &cursor) } if (cursorIs(cursor, "bottom-margin")) { - out.setBottomMargin(Tenths::parse(childText(cursor))); + out.setBottomMargin(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else diff --git a/src/private/mx/core/generated/AllMarginsGroup.h b/src/private/mx/core/generated/AllMarginsGroup.h index 856e62ba8..33f8d934c 100644 --- a/src/private/mx/core/generated/AllMarginsGroup.h +++ b/src/private/mx/core/generated/AllMarginsGroup.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The all-margins group specifies both horizontal and vertical margins in tenths. /// A shared content group: transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -42,6 +44,8 @@ class AllMarginsGroup final /// is the enclosing element, for error paths. AllMarginsGroup parseAllMarginsGroup(pugi::xml_node el, pugi::xml_node &cursor); +AllMarginsGroup parseAllMarginsGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeAllMarginsGroup(const AllMarginsGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/Appearance.cpp b/src/private/mx/core/generated/Appearance.cpp index 3eaf8c7e8..6d773f948 100644 --- a/src/private/mx/core/generated/Appearance.cpp +++ b/src/private/mx/core/generated/Appearance.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Appearance.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -86,6 +87,11 @@ void Appearance::setOtherAppearance(std::vector value) } Appearance parseAppearance(pugi::xml_node el) +{ + return parseAppearance(el, ParseContext{}); +} + +Appearance parseAppearance(pugi::xml_node el, const ParseContext &context) { Appearance out; for (pugi::xml_attribute a : el.attributes()) @@ -97,36 +103,41 @@ Appearance parseAppearance(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseAppearanceContent(out, el); + parseAppearanceContent(out, el, context); return out; } void parseAppearanceContent(Appearance &out, pugi::xml_node el) +{ + parseAppearanceContent(out, el, ParseContext{}); +} + +void parseAppearanceContent(Appearance &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); while (cursorIs(cursor, "line-width")) { - out.addLineWidth(parseLineWidth(cursor)); + out.addLineWidth(parseLineWidth(cursor, context)); cursor = nextElement(cursor); } while (cursorIs(cursor, "note-size")) { - out.addNoteSize(parseNoteSize(cursor)); + out.addNoteSize(parseNoteSize(cursor, context)); cursor = nextElement(cursor); } while (cursorIs(cursor, "distance")) { - out.addDistance(parseDistance(cursor)); + out.addDistance(parseDistance(cursor, context)); cursor = nextElement(cursor); } while (cursorIs(cursor, "glyph")) { - out.addGlyph(parseGlyph(cursor)); + out.addGlyph(parseGlyph(cursor, context)); cursor = nextElement(cursor); } while (cursorIs(cursor, "other-appearance")) { - out.addOtherAppearance(parseOtherAppearance(cursor)); + out.addOtherAppearance(parseOtherAppearance(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/Appearance.h b/src/private/mx/core/generated/Appearance.h index 746125608..fcb261551 100644 --- a/src/private/mx/core/generated/Appearance.h +++ b/src/private/mx/core/generated/Appearance.h @@ -21,6 +21,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The appearance type controls general graphical settings for the music's final form appearance on /// a printed page of display. This includes support for line widths, definitions for note sizes, and /// standard distances between notation elements, plus an extension element for other aspects of @@ -57,8 +59,12 @@ class Appearance final Appearance parseAppearance(pugi::xml_node el); +Appearance parseAppearance(pugi::xml_node el, const ParseContext &context); + void parseAppearanceContent(Appearance &out, pugi::xml_node el); +void parseAppearanceContent(Appearance &out, pugi::xml_node el, const ParseContext &context); + void serializeAppearance(const Appearance &v, pugi::xml_node parent, const char *tag); void serializeAppearanceContent(const Appearance &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Arpeggiate.cpp b/src/private/mx/core/generated/Arpeggiate.cpp index c75269602..75e961670 100644 --- a/src/private/mx/core/generated/Arpeggiate.cpp +++ b/src/private/mx/core/generated/Arpeggiate.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Arpeggiate.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -111,6 +112,11 @@ void Arpeggiate::setID(std::optional value) } Arpeggiate parseArpeggiate(pugi::xml_node el) +{ + return parseArpeggiate(el, ParseContext{}); +} + +Arpeggiate parseArpeggiate(pugi::xml_node el, const ParseContext &context) { Arpeggiate out; for (pugi::xml_attribute a : el.attributes()) @@ -122,39 +128,39 @@ Arpeggiate parseArpeggiate(pugi::xml_node el) } if (aname == "number") { - out.setNumber(NumberLevel::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else if (aname == "direction") { - out.setDirection(UpDown::parse(a.value())); + out.setDirection(parseValue(a.value(), context, el, "direction")); } else if (aname == "unbroken") { - out.setUnbroken(YesNo::parse(a.value())); + out.setUnbroken(parseValue(a.value(), context, el, "unbroken")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "id") { @@ -165,13 +171,19 @@ Arpeggiate parseArpeggiate(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseArpeggiateContent(out, el); + parseArpeggiateContent(out, el, context); return out; } void parseArpeggiateContent(Arpeggiate &out, pugi::xml_node el) +{ + parseArpeggiateContent(out, el, ParseContext{}); +} + +void parseArpeggiateContent(Arpeggiate &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Arpeggiate.h b/src/private/mx/core/generated/Arpeggiate.h index 745df1f11..92aa90156 100644 --- a/src/private/mx/core/generated/Arpeggiate.h +++ b/src/private/mx/core/generated/Arpeggiate.h @@ -22,6 +22,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The arpeggiate type indicates that this note is part of an arpeggiated chord. The number /// attribute can be used to distinguish between two simultaneous chords arpeggiated separately /// (different numbers) or together (same number). The direction attribute is used if there is an @@ -70,8 +72,12 @@ class Arpeggiate final Arpeggiate parseArpeggiate(pugi::xml_node el); +Arpeggiate parseArpeggiate(pugi::xml_node el, const ParseContext &context); + void parseArpeggiateContent(Arpeggiate &out, pugi::xml_node el); +void parseArpeggiateContent(Arpeggiate &out, pugi::xml_node el, const ParseContext &context); + void serializeArpeggiate(const Arpeggiate &v, pugi::xml_node parent, const char *tag); void serializeArpeggiateContent(const Arpeggiate &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Arrow.cpp b/src/private/mx/core/generated/Arrow.cpp index 8750566b3..ff4b3711c 100644 --- a/src/private/mx/core/generated/Arrow.cpp +++ b/src/private/mx/core/generated/Arrow.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Arrow.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -131,6 +132,11 @@ void Arrow::setChoice(ArrowChoice value) } Arrow parseArrow(pugi::xml_node el) +{ + return parseArrow(el, ParseContext{}); +} + +Arrow parseArrow(pugi::xml_node el, const ParseContext &context) { Arrow out; for (pugi::xml_attribute a : el.attributes()) @@ -142,63 +148,68 @@ Arrow parseArrow(pugi::xml_node el) } if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else if (aname == "smufl") { - out.setSmufl(SmuflGlyphName::parse(a.value())); + out.setSmufl(parseValue(a.value(), context, el, "smufl")); } else { throwUnknownAttribute(el, a.name()); } } - parseArrowContent(out, el); + parseArrowContent(out, el, context); return out; } void parseArrowContent(Arrow &out, pugi::xml_node el) +{ + parseArrowContent(out, el, ParseContext{}); +} + +void parseArrowContent(Arrow &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "arrow-direction") || cursorIs(cursor, "circular-arrow"))) { - out.setChoice(parseArrowChoice(el, cursor)); + out.setChoice(parseArrowChoice(el, cursor, context)); } else { diff --git a/src/private/mx/core/generated/Arrow.h b/src/private/mx/core/generated/Arrow.h index a4281ee2e..b88955240 100644 --- a/src/private/mx/core/generated/Arrow.h +++ b/src/private/mx/core/generated/Arrow.h @@ -25,6 +25,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The arrow element represents an arrow used for a musical technical indication. It can represent /// both Unicode and SMuFL arrows. The presence of an arrowhead element indicates that only the /// arrowhead is displayed, not the arrow stem. The smufl attribute distinguishes different SMuFL @@ -78,8 +80,12 @@ class Arrow final Arrow parseArrow(pugi::xml_node el); +Arrow parseArrow(pugi::xml_node el, const ParseContext &context); + void parseArrowContent(Arrow &out, pugi::xml_node el); +void parseArrowContent(Arrow &out, pugi::xml_node el, const ParseContext &context); + void serializeArrow(const Arrow &v, pugi::xml_node parent, const char *tag); void serializeArrowContent(const Arrow &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/ArrowChoice.cpp b/src/private/mx/core/generated/ArrowChoice.cpp index 87e13198f..db4e9c9f7 100644 --- a/src/private/mx/core/generated/ArrowChoice.cpp +++ b/src/private/mx/core/generated/ArrowChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/ArrowChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -26,14 +27,19 @@ ArrowChoice ArrowChoice::circularArrow(CircularArrow value) } ArrowChoice parseArrowChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseArrowChoice(el, cursor, ParseContext{}); +} + +ArrowChoice parseArrowChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "arrow-direction"))) { - return ArrowChoice::group(parseArrowChoiceGroup(el, cursor)); + return ArrowChoice::group(parseArrowChoiceGroup(el, cursor, context)); } if (cursor && (cursorIs(cursor, "circular-arrow"))) { - CircularArrow value = CircularArrow::parse(childText(cursor)); + CircularArrow value = parseValue(childText(cursor), context, cursor, nullptr); cursor = nextElement(cursor); return ArrowChoice::circularArrow(std::move(value)); } diff --git a/src/private/mx/core/generated/ArrowChoice.h b/src/private/mx/core/generated/ArrowChoice.h index bbc6b4c1d..7c91a7303 100644 --- a/src/private/mx/core/generated/ArrowChoice.h +++ b/src/private/mx/core/generated/ArrowChoice.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -82,6 +84,8 @@ class ArrowChoice final /// the enclosing element, for error paths. ArrowChoice parseArrowChoice(pugi::xml_node el, pugi::xml_node &cursor); +ArrowChoice parseArrowChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeArrowChoice(const ArrowChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/ArrowChoiceGroup.cpp b/src/private/mx/core/generated/ArrowChoiceGroup.cpp index 22137a5ef..e31edce6b 100644 --- a/src/private/mx/core/generated/ArrowChoiceGroup.cpp +++ b/src/private/mx/core/generated/ArrowChoiceGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/ArrowChoiceGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,11 +42,16 @@ void ArrowChoiceGroup::setArrowhead(bool value) noexcept } ArrowChoiceGroup parseArrowChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseArrowChoiceGroup(el, cursor, ParseContext{}); +} + +ArrowChoiceGroup parseArrowChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { ArrowChoiceGroup out; if (cursorIs(cursor, "arrow-direction")) { - out.setArrowDirection(ArrowDirection::parse(childText(cursor))); + out.setArrowDirection(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -54,12 +60,12 @@ ArrowChoiceGroup parseArrowChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor } if (cursorIs(cursor, "arrow-style")) { - out.setArrowStyle(ArrowStyle::parse(childText(cursor))); + out.setArrowStyle(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (cursorIs(cursor, "arrowhead")) { - parseEmpty(cursor); + parseEmpty(cursor, context); out.setArrowhead(true); cursor = nextElement(cursor); } diff --git a/src/private/mx/core/generated/ArrowChoiceGroup.h b/src/private/mx/core/generated/ArrowChoiceGroup.h index a93629ff6..8ed0be9f6 100644 --- a/src/private/mx/core/generated/ArrowChoiceGroup.h +++ b/src/private/mx/core/generated/ArrowChoiceGroup.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A shared content group (synthesized from an anonymous /// particle of the schema): transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -43,6 +45,8 @@ class ArrowChoiceGroup final /// is the enclosing element, for error paths. ArrowChoiceGroup parseArrowChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor); +ArrowChoiceGroup parseArrowChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeArrowChoiceGroup(const ArrowChoiceGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/ArrowDirection.cpp b/src/private/mx/core/generated/ArrowDirection.cpp index 680f73192..478b33117 100644 --- a/src/private/mx/core/generated/ArrowDirection.cpp +++ b/src/private/mx/core/generated/ArrowDirection.cpp @@ -98,9 +98,15 @@ bool ArrowDirection::tryParse(std::string_view text, ArrowDirection &out) noexce } ArrowDirection ArrowDirection::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +ArrowDirection ArrowDirection::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { ArrowDirection v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/ArrowDirection.h b/src/private/mx/core/generated/ArrowDirection.h index 35aed9b42..d28b782ae 100644 --- a/src/private/mx/core/generated/ArrowDirection.h +++ b/src/private/mx/core/generated/ArrowDirection.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -63,6 +65,9 @@ class ArrowDirection final /// (the import leniency policy; never produces an invalid value). static ArrowDirection parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static ArrowDirection parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const ArrowDirection &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/ArrowStyle.cpp b/src/private/mx/core/generated/ArrowStyle.cpp index dbe9a8636..86bda74f3 100644 --- a/src/private/mx/core/generated/ArrowStyle.cpp +++ b/src/private/mx/core/generated/ArrowStyle.cpp @@ -66,9 +66,15 @@ bool ArrowStyle::tryParse(std::string_view text, ArrowStyle &out) noexcept } ArrowStyle ArrowStyle::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +ArrowStyle ArrowStyle::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { ArrowStyle v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/ArrowStyle.h b/src/private/mx/core/generated/ArrowStyle.h index 096f01015..26bb2fb0b 100644 --- a/src/private/mx/core/generated/ArrowStyle.h +++ b/src/private/mx/core/generated/ArrowStyle.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -53,6 +55,9 @@ class ArrowStyle final /// (the import leniency policy; never produces an invalid value). static ArrowStyle parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static ArrowStyle parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const ArrowStyle &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Articulations.cpp b/src/private/mx/core/generated/Articulations.cpp index b815920b9..ff56284a5 100644 --- a/src/private/mx/core/generated/Articulations.cpp +++ b/src/private/mx/core/generated/Articulations.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Articulations.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -36,6 +37,11 @@ void Articulations::setChoice(std::vector value) } Articulations parseArticulations(pugi::xml_node el) +{ + return parseArticulations(el, ParseContext{}); +} + +Articulations parseArticulations(pugi::xml_node el, const ParseContext &context) { Articulations out; for (pugi::xml_attribute a : el.attributes()) @@ -54,11 +60,16 @@ Articulations parseArticulations(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseArticulationsContent(out, el); + parseArticulationsContent(out, el, context); return out; } void parseArticulationsContent(Articulations &out, pugi::xml_node el) +{ + parseArticulationsContent(out, el, ParseContext{}); +} + +void parseArticulationsContent(Articulations &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); while (cursor && @@ -69,7 +80,7 @@ void parseArticulationsContent(Articulations &out, pugi::xml_node el) cursorIs(cursor, "caesura") || cursorIs(cursor, "stress") || cursorIs(cursor, "unstress") || cursorIs(cursor, "soft-accent") || cursorIs(cursor, "other-articulation"))) { - out.addChoice(parseArticulationsChoice(el, cursor)); + out.addChoice(parseArticulationsChoice(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/Articulations.h b/src/private/mx/core/generated/Articulations.h index 66e38f44c..94b562070 100644 --- a/src/private/mx/core/generated/Articulations.h +++ b/src/private/mx/core/generated/Articulations.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Articulations and accents are grouped together here. /// Content fields mirror the schema grammar in declaration order; the /// serializer walks them, so a wrong order is unrepresentable (plan ยง2.3). @@ -39,8 +41,12 @@ class Articulations final Articulations parseArticulations(pugi::xml_node el); +Articulations parseArticulations(pugi::xml_node el, const ParseContext &context); + void parseArticulationsContent(Articulations &out, pugi::xml_node el); +void parseArticulationsContent(Articulations &out, pugi::xml_node el, const ParseContext &context); + void serializeArticulations(const Articulations &v, pugi::xml_node parent, const char *tag); void serializeArticulationsContent(const Articulations &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/ArticulationsChoice.cpp b/src/private/mx/core/generated/ArticulationsChoice.cpp index 511088cf0..62d5556a7 100644 --- a/src/private/mx/core/generated/ArticulationsChoice.cpp +++ b/src/private/mx/core/generated/ArticulationsChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/ArticulationsChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -101,106 +102,111 @@ ArticulationsChoice ArticulationsChoice::otherArticulation(OtherPlacementText va } ArticulationsChoice parseArticulationsChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseArticulationsChoice(el, cursor, ParseContext{}); +} + +ArticulationsChoice parseArticulationsChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "accent"))) { - EmptyPlacement value = parseEmptyPlacement(cursor); + EmptyPlacement value = parseEmptyPlacement(cursor, context); cursor = nextElement(cursor); return ArticulationsChoice::accent(std::move(value)); } if (cursor && (cursorIs(cursor, "strong-accent"))) { - StrongAccent value = parseStrongAccent(cursor); + StrongAccent value = parseStrongAccent(cursor, context); cursor = nextElement(cursor); return ArticulationsChoice::strongAccent(std::move(value)); } if (cursor && (cursorIs(cursor, "staccato"))) { - EmptyPlacement value = parseEmptyPlacement(cursor); + EmptyPlacement value = parseEmptyPlacement(cursor, context); cursor = nextElement(cursor); return ArticulationsChoice::staccato(std::move(value)); } if (cursor && (cursorIs(cursor, "tenuto"))) { - EmptyPlacement value = parseEmptyPlacement(cursor); + EmptyPlacement value = parseEmptyPlacement(cursor, context); cursor = nextElement(cursor); return ArticulationsChoice::tenuto(std::move(value)); } if (cursor && (cursorIs(cursor, "detached-legato"))) { - EmptyPlacement value = parseEmptyPlacement(cursor); + EmptyPlacement value = parseEmptyPlacement(cursor, context); cursor = nextElement(cursor); return ArticulationsChoice::detachedLegato(std::move(value)); } if (cursor && (cursorIs(cursor, "staccatissimo"))) { - EmptyPlacement value = parseEmptyPlacement(cursor); + EmptyPlacement value = parseEmptyPlacement(cursor, context); cursor = nextElement(cursor); return ArticulationsChoice::staccatissimo(std::move(value)); } if (cursor && (cursorIs(cursor, "spiccato"))) { - EmptyPlacement value = parseEmptyPlacement(cursor); + EmptyPlacement value = parseEmptyPlacement(cursor, context); cursor = nextElement(cursor); return ArticulationsChoice::spiccato(std::move(value)); } if (cursor && (cursorIs(cursor, "scoop"))) { - EmptyLine value = parseEmptyLine(cursor); + EmptyLine value = parseEmptyLine(cursor, context); cursor = nextElement(cursor); return ArticulationsChoice::scoop(std::move(value)); } if (cursor && (cursorIs(cursor, "plop"))) { - EmptyLine value = parseEmptyLine(cursor); + EmptyLine value = parseEmptyLine(cursor, context); cursor = nextElement(cursor); return ArticulationsChoice::plop(std::move(value)); } if (cursor && (cursorIs(cursor, "doit"))) { - EmptyLine value = parseEmptyLine(cursor); + EmptyLine value = parseEmptyLine(cursor, context); cursor = nextElement(cursor); return ArticulationsChoice::doit(std::move(value)); } if (cursor && (cursorIs(cursor, "falloff"))) { - EmptyLine value = parseEmptyLine(cursor); + EmptyLine value = parseEmptyLine(cursor, context); cursor = nextElement(cursor); return ArticulationsChoice::falloff(std::move(value)); } if (cursor && (cursorIs(cursor, "breath-mark"))) { - BreathMark value = parseBreathMark(cursor); + BreathMark value = parseBreathMark(cursor, context); cursor = nextElement(cursor); return ArticulationsChoice::breathMark(std::move(value)); } if (cursor && (cursorIs(cursor, "caesura"))) { - Caesura value = parseCaesura(cursor); + Caesura value = parseCaesura(cursor, context); cursor = nextElement(cursor); return ArticulationsChoice::caesura(std::move(value)); } if (cursor && (cursorIs(cursor, "stress"))) { - EmptyPlacement value = parseEmptyPlacement(cursor); + EmptyPlacement value = parseEmptyPlacement(cursor, context); cursor = nextElement(cursor); return ArticulationsChoice::stress(std::move(value)); } if (cursor && (cursorIs(cursor, "unstress"))) { - EmptyPlacement value = parseEmptyPlacement(cursor); + EmptyPlacement value = parseEmptyPlacement(cursor, context); cursor = nextElement(cursor); return ArticulationsChoice::unstress(std::move(value)); } if (cursor && (cursorIs(cursor, "soft-accent"))) { - EmptyPlacement value = parseEmptyPlacement(cursor); + EmptyPlacement value = parseEmptyPlacement(cursor, context); cursor = nextElement(cursor); return ArticulationsChoice::softAccent(std::move(value)); } if (cursor && (cursorIs(cursor, "other-articulation"))) { - OtherPlacementText value = parseOtherPlacementText(cursor); + OtherPlacementText value = parseOtherPlacementText(cursor, context); cursor = nextElement(cursor); return ArticulationsChoice::otherArticulation(std::move(value)); } diff --git a/src/private/mx/core/generated/ArticulationsChoice.h b/src/private/mx/core/generated/ArticulationsChoice.h index bd78abce8..aa0e20356 100644 --- a/src/private/mx/core/generated/ArticulationsChoice.h +++ b/src/private/mx/core/generated/ArticulationsChoice.h @@ -22,6 +22,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -298,6 +300,8 @@ class ArticulationsChoice final /// the enclosing element, for error paths. ArticulationsChoice parseArticulationsChoice(pugi::xml_node el, pugi::xml_node &cursor); +ArticulationsChoice parseArticulationsChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeArticulationsChoice(const ArticulationsChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/Assess.cpp b/src/private/mx/core/generated/Assess.cpp index 797da221f..7e9adb81f 100644 --- a/src/private/mx/core/generated/Assess.cpp +++ b/src/private/mx/core/generated/Assess.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Assess.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,6 +42,11 @@ void Assess::setTimeOnly(std::optional value) } Assess parseAssess(pugi::xml_node el) +{ + return parseAssess(el, ParseContext{}); +} + +Assess parseAssess(pugi::xml_node el, const ParseContext &context) { Assess out; bool seen_type = false; @@ -54,7 +60,7 @@ Assess parseAssess(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(YesNo::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "player") { @@ -62,7 +68,7 @@ Assess parseAssess(pugi::xml_node el) } else if (aname == "time-only") { - out.setTimeOnly(TimeOnly::parse(a.value())); + out.setTimeOnly(parseValue(a.value(), context, el, "time-only")); } else { @@ -73,13 +79,19 @@ Assess parseAssess(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseAssessContent(out, el); + parseAssessContent(out, el, context); return out; } void parseAssessContent(Assess &out, pugi::xml_node el) +{ + parseAssessContent(out, el, ParseContext{}); +} + +void parseAssessContent(Assess &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Assess.h b/src/private/mx/core/generated/Assess.h index 3a7eb0f3d..562bd0702 100644 --- a/src/private/mx/core/generated/Assess.h +++ b/src/private/mx/core/generated/Assess.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// By default, an assessment application should assess all notes without a cue child element, and /// not assess any note with a cue child element. The assess type allows this default assessment to /// be overridden for individual notes. The optional player and time-only attributes restrict the @@ -44,8 +46,12 @@ class Assess final Assess parseAssess(pugi::xml_node el); +Assess parseAssess(pugi::xml_node el, const ParseContext &context); + void parseAssessContent(Assess &out, pugi::xml_node el); +void parseAssessContent(Assess &out, pugi::xml_node el, const ParseContext &context); + void serializeAssess(const Assess &v, pugi::xml_node parent, const char *tag); void serializeAssessContent(const Assess &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Attributes.cpp b/src/private/mx/core/generated/Attributes.cpp index df236f925..d7acf7b56 100644 --- a/src/private/mx/core/generated/Attributes.cpp +++ b/src/private/mx/core/generated/Attributes.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Attributes.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -161,6 +162,11 @@ void Attributes::setMeasureStyle(std::vector value) } Attributes parseAttributes(pugi::xml_node el) +{ + return parseAttributes(el, ParseContext{}); +} + +Attributes parseAttributes(pugi::xml_node el, const ParseContext &context) { Attributes out; for (pugi::xml_attribute a : el.attributes()) @@ -172,69 +178,74 @@ Attributes parseAttributes(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseAttributesContent(out, el); + parseAttributesContent(out, el, context); return out; } void parseAttributesContent(Attributes &out, pugi::xml_node el) +{ + parseAttributesContent(out, el, ParseContext{}); +} + +void parseAttributesContent(Attributes &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "footnote") || cursorIs(cursor, "level"))) { - out.setEditorial(parseEditorialGroup(el, cursor)); + out.setEditorial(parseEditorialGroup(el, cursor, context)); } if (cursorIs(cursor, "divisions")) { - out.setDivisions(PositiveDivisions::parse(childText(cursor))); + out.setDivisions(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } while (cursorIs(cursor, "key")) { - out.addKey(parseKey(cursor)); + out.addKey(parseKey(cursor, context)); cursor = nextElement(cursor); } while (cursorIs(cursor, "time")) { - out.addTime(parseTime(cursor)); + out.addTime(parseTime(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "staves")) { - out.setStaves(parseInt(childText(cursor))); + out.setStaves(parseIntegerValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (cursorIs(cursor, "part-symbol")) { - out.setPartSymbol(parsePartSymbol(cursor)); + out.setPartSymbol(parsePartSymbol(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "instruments")) { - out.setInstruments(parseInt(childText(cursor))); + out.setInstruments(parseIntegerValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } while (cursorIs(cursor, "clef")) { - out.addClef(parseClef(cursor)); + out.addClef(parseClef(cursor, context)); cursor = nextElement(cursor); } while (cursorIs(cursor, "staff-details")) { - out.addStaffDetails(parseStaffDetails(cursor)); + out.addStaffDetails(parseStaffDetails(cursor, context)); cursor = nextElement(cursor); } if (cursor && (cursorIs(cursor, "transpose") || cursorIs(cursor, "for-part"))) { - out.setChoice(parseAttributesChoice(el, cursor)); + out.setChoice(parseAttributesChoice(el, cursor, context)); } while (cursorIs(cursor, "directive")) { - out.addDirective(parseDirective(cursor)); + out.addDirective(parseDirective(cursor, context)); cursor = nextElement(cursor); } while (cursorIs(cursor, "measure-style")) { - out.addMeasureStyle(parseMeasureStyle(cursor)); + out.addMeasureStyle(parseMeasureStyle(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/Attributes.h b/src/private/mx/core/generated/Attributes.h index d152a743e..9023f6e4b 100644 --- a/src/private/mx/core/generated/Attributes.h +++ b/src/private/mx/core/generated/Attributes.h @@ -26,6 +26,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The attributes element contains musical information that typically changes on measure boundaries. /// This includes key and time signatures, clefs, transpositions, and staving. When attributes are /// changed mid-measure, it affects the music in score order, not in MusicXML document order. @@ -83,8 +85,12 @@ class Attributes final Attributes parseAttributes(pugi::xml_node el); +Attributes parseAttributes(pugi::xml_node el, const ParseContext &context); + void parseAttributesContent(Attributes &out, pugi::xml_node el); +void parseAttributesContent(Attributes &out, pugi::xml_node el, const ParseContext &context); + void serializeAttributes(const Attributes &v, pugi::xml_node parent, const char *tag); void serializeAttributesContent(const Attributes &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/AttributesChoice.cpp b/src/private/mx/core/generated/AttributesChoice.cpp index 7f157d412..1ccc20d23 100644 --- a/src/private/mx/core/generated/AttributesChoice.cpp +++ b/src/private/mx/core/generated/AttributesChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/AttributesChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -26,13 +27,18 @@ AttributesChoice AttributesChoice::forPart(std::vector value) } AttributesChoice parseAttributesChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseAttributesChoice(el, cursor, ParseContext{}); +} + +AttributesChoice parseAttributesChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "transpose"))) { std::vector items; while (cursor && (cursorIs(cursor, "transpose"))) { - items.push_back(parseTranspose(cursor)); + items.push_back(parseTranspose(cursor, context)); cursor = nextElement(cursor); } return AttributesChoice::transpose(std::move(items)); @@ -42,7 +48,7 @@ AttributesChoice parseAttributesChoice(pugi::xml_node el, pugi::xml_node &cursor std::vector items; while (cursor && (cursorIs(cursor, "for-part"))) { - items.push_back(parseForPart(cursor)); + items.push_back(parseForPart(cursor, context)); cursor = nextElement(cursor); } return AttributesChoice::forPart(std::move(items)); diff --git a/src/private/mx/core/generated/AttributesChoice.h b/src/private/mx/core/generated/AttributesChoice.h index 3634e367b..628289b53 100644 --- a/src/private/mx/core/generated/AttributesChoice.h +++ b/src/private/mx/core/generated/AttributesChoice.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -83,6 +85,8 @@ class AttributesChoice final /// the enclosing element, for error paths. AttributesChoice parseAttributesChoice(pugi::xml_node el, pugi::xml_node &cursor); +AttributesChoice parseAttributesChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeAttributesChoice(const AttributesChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/Backup.cpp b/src/private/mx/core/generated/Backup.cpp index 9f1066e94..7946b027d 100644 --- a/src/private/mx/core/generated/Backup.cpp +++ b/src/private/mx/core/generated/Backup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Backup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void Backup::setEditorial(EditorialGroup value) } Backup parseBackup(pugi::xml_node el) +{ + return parseBackup(el, ParseContext{}); +} + +Backup parseBackup(pugi::xml_node el, const ParseContext &context) { Backup out; for (pugi::xml_attribute a : el.attributes()) @@ -42,16 +48,21 @@ Backup parseBackup(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseBackupContent(out, el); + parseBackupContent(out, el, context); return out; } void parseBackupContent(Backup &out, pugi::xml_node el) +{ + parseBackupContent(out, el, ParseContext{}); +} + +void parseBackupContent(Backup &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "duration")) { - out.setDuration(PositiveDivisions::parse(childText(cursor))); + out.setDuration(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -60,7 +71,7 @@ void parseBackupContent(Backup &out, pugi::xml_node el) } if (cursor && (cursorIs(cursor, "footnote") || cursorIs(cursor, "level"))) { - out.setEditorial(parseEditorialGroup(el, cursor)); + out.setEditorial(parseEditorialGroup(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/Backup.h b/src/private/mx/core/generated/Backup.h index 84919da0a..5bb803526 100644 --- a/src/private/mx/core/generated/Backup.h +++ b/src/private/mx/core/generated/Backup.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The backup and forward elements are required to coordinate multiple voices in one part, including /// music on multiple staves. The backup type is generally used to move between voices and staves. /// Thus the backup element does not include voice or staff elements. Duration values should always @@ -41,8 +43,12 @@ class Backup final Backup parseBackup(pugi::xml_node el); +Backup parseBackup(pugi::xml_node el, const ParseContext &context); + void parseBackupContent(Backup &out, pugi::xml_node el); +void parseBackupContent(Backup &out, pugi::xml_node el, const ParseContext &context); + void serializeBackup(const Backup &v, pugi::xml_node parent, const char *tag); void serializeBackupContent(const Backup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/BackwardForward.cpp b/src/private/mx/core/generated/BackwardForward.cpp index 3fc85239f..fa73bb146 100644 --- a/src/private/mx/core/generated/BackwardForward.cpp +++ b/src/private/mx/core/generated/BackwardForward.cpp @@ -42,9 +42,15 @@ bool BackwardForward::tryParse(std::string_view text, BackwardForward &out) noex } BackwardForward BackwardForward::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +BackwardForward BackwardForward::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { BackwardForward v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/BackwardForward.h b/src/private/mx/core/generated/BackwardForward.h index ace778bda..a46adafa7 100644 --- a/src/private/mx/core/generated/BackwardForward.h +++ b/src/private/mx/core/generated/BackwardForward.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -41,6 +43,9 @@ class BackwardForward final /// (the import leniency policy; never produces an invalid value). static BackwardForward parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static BackwardForward parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const BackwardForward &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/BarStyle.cpp b/src/private/mx/core/generated/BarStyle.cpp index 91e0cdcda..89d462151 100644 --- a/src/private/mx/core/generated/BarStyle.cpp +++ b/src/private/mx/core/generated/BarStyle.cpp @@ -87,9 +87,15 @@ bool BarStyle::tryParse(std::string_view text, BarStyle &out) noexcept } BarStyle BarStyle::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +BarStyle BarStyle::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { BarStyle v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/BarStyle.h b/src/private/mx/core/generated/BarStyle.h index e4d226620..49879cd05 100644 --- a/src/private/mx/core/generated/BarStyle.h +++ b/src/private/mx/core/generated/BarStyle.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -60,6 +62,9 @@ class BarStyle final /// (the import leniency policy; never produces an invalid value). static BarStyle parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static BarStyle parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const BarStyle &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/BarStyleColor.cpp b/src/private/mx/core/generated/BarStyleColor.cpp index ba48d2758..e9fd86692 100644 --- a/src/private/mx/core/generated/BarStyleColor.cpp +++ b/src/private/mx/core/generated/BarStyleColor.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/BarStyleColor.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void BarStyleColor::setValue(BarStyle value) } BarStyleColor parseBarStyleColor(pugi::xml_node el) +{ + return parseBarStyleColor(el, ParseContext{}); +} + +BarStyleColor parseBarStyleColor(pugi::xml_node el, const ParseContext &context) { BarStyleColor out; for (pugi::xml_attribute a : el.attributes()) @@ -42,20 +48,25 @@ BarStyleColor parseBarStyleColor(pugi::xml_node el) } if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else { throwUnknownAttribute(el, a.name()); } } - parseBarStyleColorContent(out, el); + parseBarStyleColorContent(out, el, context); return out; } void parseBarStyleColorContent(BarStyleColor &out, pugi::xml_node el) { - out.setValue(BarStyle::parse(childText(el))); + parseBarStyleColorContent(out, el, ParseContext{}); +} + +void parseBarStyleColorContent(BarStyleColor &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/BarStyleColor.h b/src/private/mx/core/generated/BarStyleColor.h index 1ade2024f..b71cf0f1d 100644 --- a/src/private/mx/core/generated/BarStyleColor.h +++ b/src/private/mx/core/generated/BarStyleColor.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The bar-style-color type contains barline style and color information. class BarStyleColor final { @@ -33,8 +35,12 @@ class BarStyleColor final BarStyleColor parseBarStyleColor(pugi::xml_node el); +BarStyleColor parseBarStyleColor(pugi::xml_node el, const ParseContext &context); + void parseBarStyleColorContent(BarStyleColor &out, pugi::xml_node el); +void parseBarStyleColorContent(BarStyleColor &out, pugi::xml_node el, const ParseContext &context); + void serializeBarStyleColor(const BarStyleColor &v, pugi::xml_node parent, const char *tag); void serializeBarStyleColorContent(const BarStyleColor &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Barline.cpp b/src/private/mx/core/generated/Barline.cpp index dec69309a..ca23c9eee 100644 --- a/src/private/mx/core/generated/Barline.cpp +++ b/src/private/mx/core/generated/Barline.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Barline.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -151,6 +152,11 @@ void Barline::setRepeat(std::optional value) } Barline parseBarline(pugi::xml_node el) +{ + return parseBarline(el, ParseContext{}); +} + +Barline parseBarline(pugi::xml_node el, const ParseContext &context) { Barline out; for (pugi::xml_attribute a : el.attributes()) @@ -162,7 +168,7 @@ Barline parseBarline(pugi::xml_node el) } if (aname == "location") { - out.setLocation(RightLeftMiddle::parse(a.value())); + out.setLocation(parseValue(a.value(), context, el, "location")); } else if (aname == "segno") { @@ -174,7 +180,7 @@ Barline parseBarline(pugi::xml_node el) } else if (aname == "divisions") { - out.setDivisions(Divisions::parse(a.value())); + out.setDivisions(parseValue(a.value(), context, el, "divisions")); } else if (aname == "id") { @@ -185,40 +191,45 @@ Barline parseBarline(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseBarlineContent(out, el); + parseBarlineContent(out, el, context); return out; } void parseBarlineContent(Barline &out, pugi::xml_node el) +{ + parseBarlineContent(out, el, ParseContext{}); +} + +void parseBarlineContent(Barline &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "bar-style")) { - out.setBarStyle(parseBarStyleColor(cursor)); + out.setBarStyle(parseBarStyleColor(cursor, context)); cursor = nextElement(cursor); } if (cursor && (cursorIs(cursor, "footnote") || cursorIs(cursor, "level"))) { - out.setEditorial(parseEditorialGroup(el, cursor)); + out.setEditorial(parseEditorialGroup(el, cursor, context)); } if (cursorIs(cursor, "wavy-line")) { - out.setWavyLine(parseWavyLine(cursor)); + out.setWavyLine(parseWavyLine(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "segno")) { - out.setSegno(parseSegno(cursor)); + out.setSegno(parseSegno(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "coda")) { - out.setCoda(parseCoda(cursor)); + out.setCoda(parseCoda(cursor, context)); cursor = nextElement(cursor); } while (cursorIs(cursor, "fermata")) { - if (!out.addFermata(parseFermata(cursor))) + if (!out.addFermata(parseFermata(cursor, context))) { throwTooManyElements(cursor); } @@ -226,12 +237,12 @@ void parseBarlineContent(Barline &out, pugi::xml_node el) } if (cursorIs(cursor, "ending")) { - out.setEnding(parseEnding(cursor)); + out.setEnding(parseEnding(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "repeat")) { - out.setRepeat(parseRepeat(cursor)); + out.setRepeat(parseRepeat(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/Barline.h b/src/private/mx/core/generated/Barline.h index d875910f2..617be1451 100644 --- a/src/private/mx/core/generated/Barline.h +++ b/src/private/mx/core/generated/Barline.h @@ -29,6 +29,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// If a barline is other than a normal single barline, it should be represented by a barline type /// that describes it. This includes information about repeats and multiple endings, as well as line /// style. Barline data is on the same level as the other musical data in a score - a child of a @@ -98,8 +100,12 @@ class Barline final Barline parseBarline(pugi::xml_node el); +Barline parseBarline(pugi::xml_node el, const ParseContext &context); + void parseBarlineContent(Barline &out, pugi::xml_node el); +void parseBarlineContent(Barline &out, pugi::xml_node el, const ParseContext &context); + void serializeBarline(const Barline &v, pugi::xml_node parent, const char *tag); void serializeBarlineContent(const Barline &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Barre.cpp b/src/private/mx/core/generated/Barre.cpp index 74cb9bdd4..7b8ea8795 100644 --- a/src/private/mx/core/generated/Barre.cpp +++ b/src/private/mx/core/generated/Barre.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Barre.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void Barre::setColor(std::optional value) } Barre parseBarre(pugi::xml_node el) +{ + return parseBarre(el, ParseContext{}); +} + +Barre parseBarre(pugi::xml_node el, const ParseContext &context) { Barre out; bool seen_type = false; @@ -44,11 +50,11 @@ Barre parseBarre(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(StartStop::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else { @@ -59,13 +65,19 @@ Barre parseBarre(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseBarreContent(out, el); + parseBarreContent(out, el, context); return out; } void parseBarreContent(Barre &out, pugi::xml_node el) +{ + parseBarreContent(out, el, ParseContext{}); +} + +void parseBarreContent(Barre &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Barre.h b/src/private/mx/core/generated/Barre.h index 14ad3f489..85f5509a3 100644 --- a/src/private/mx/core/generated/Barre.h +++ b/src/private/mx/core/generated/Barre.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The barre element indicates placing a finger over multiple strings on a single fret. The type is /// "start" for the lowest pitched string (e.g., the string with the highest MusicXML number) and is /// "stop" for the highest pitched string. @@ -35,8 +37,12 @@ class Barre final Barre parseBarre(pugi::xml_node el); +Barre parseBarre(pugi::xml_node el, const ParseContext &context); + void parseBarreContent(Barre &out, pugi::xml_node el); +void parseBarreContent(Barre &out, pugi::xml_node el, const ParseContext &context); + void serializeBarre(const Barre &v, pugi::xml_node parent, const char *tag); void serializeBarreContent(const Barre &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Bass.cpp b/src/private/mx/core/generated/Bass.cpp index d9d9b1885..fb0aab6ea 100644 --- a/src/private/mx/core/generated/Bass.cpp +++ b/src/private/mx/core/generated/Bass.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Bass.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -51,6 +52,11 @@ void Bass::setBassAlter(std::optional value) } Bass parseBass(pugi::xml_node el) +{ + return parseBass(el, ParseContext{}); +} + +Bass parseBass(pugi::xml_node el, const ParseContext &context) { Bass out; for (pugi::xml_attribute a : el.attributes()) @@ -62,28 +68,33 @@ Bass parseBass(pugi::xml_node el) } if (aname == "arrangement") { - out.setArrangement(HarmonyArrangement::parse(a.value())); + out.setArrangement(parseValue(a.value(), context, el, "arrangement")); } else { throwUnknownAttribute(el, a.name()); } } - parseBassContent(out, el); + parseBassContent(out, el, context); return out; } void parseBassContent(Bass &out, pugi::xml_node el) +{ + parseBassContent(out, el, ParseContext{}); +} + +void parseBassContent(Bass &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "bass-separator")) { - out.setBassSeparator(parseStyleText(cursor)); + out.setBassSeparator(parseStyleText(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "bass-step")) { - out.setBassStep(parseBassStep(cursor)); + out.setBassStep(parseBassStep(cursor, context)); cursor = nextElement(cursor); } else @@ -92,7 +103,7 @@ void parseBassContent(Bass &out, pugi::xml_node el) } if (cursorIs(cursor, "bass-alter")) { - out.setBassAlter(parseHarmonyAlter(cursor)); + out.setBassAlter(parseHarmonyAlter(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/Bass.h b/src/private/mx/core/generated/Bass.h index 58193ed83..a175e5e55 100644 --- a/src/private/mx/core/generated/Bass.h +++ b/src/private/mx/core/generated/Bass.h @@ -20,6 +20,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The bass type is used to indicate a bass note in popular music chord symbols, e.g. G/C. It is /// generally not used in functional harmony, as inversion is generally not used in pop chord /// symbols. As with root, it is divided into step and alter elements, similar to pitches. The @@ -48,8 +50,12 @@ class Bass final Bass parseBass(pugi::xml_node el); +Bass parseBass(pugi::xml_node el, const ParseContext &context); + void parseBassContent(Bass &out, pugi::xml_node el); +void parseBassContent(Bass &out, pugi::xml_node el, const ParseContext &context); + void serializeBass(const Bass &v, pugi::xml_node parent, const char *tag); void serializeBassContent(const Bass &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/BassStep.cpp b/src/private/mx/core/generated/BassStep.cpp index fead3cfd3..39a20e381 100644 --- a/src/private/mx/core/generated/BassStep.cpp +++ b/src/private/mx/core/generated/BassStep.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/BassStep.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -121,6 +122,11 @@ void BassStep::setValue(Step value) } BassStep parseBassStep(pugi::xml_node el) +{ + return parseBassStep(el, ParseContext{}); +} + +BassStep parseBassStep(pugi::xml_node el, const ParseContext &context) { BassStep out; for (pugi::xml_attribute a : el.attributes()) @@ -136,52 +142,57 @@ BassStep parseBassStep(pugi::xml_node el) } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else { throwUnknownAttribute(el, a.name()); } } - parseBassStepContent(out, el); + parseBassStepContent(out, el, context); return out; } void parseBassStepContent(BassStep &out, pugi::xml_node el) { - out.setValue(Step::parse(childText(el))); + parseBassStepContent(out, el, ParseContext{}); +} + +void parseBassStepContent(BassStep &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/BassStep.h b/src/private/mx/core/generated/BassStep.h index 14fae7540..6be73b59d 100644 --- a/src/private/mx/core/generated/BassStep.h +++ b/src/private/mx/core/generated/BassStep.h @@ -21,6 +21,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The bass-step type represents the pitch step of the bass of the current chord within the harmony /// element. The text attribute indicates how the bass should appear in a score if not using the /// element contents. @@ -67,8 +69,12 @@ class BassStep final BassStep parseBassStep(pugi::xml_node el); +BassStep parseBassStep(pugi::xml_node el, const ParseContext &context); + void parseBassStepContent(BassStep &out, pugi::xml_node el); +void parseBassStepContent(BassStep &out, pugi::xml_node el, const ParseContext &context); + void serializeBassStep(const BassStep &v, pugi::xml_node parent, const char *tag); void serializeBassStepContent(const BassStep &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Beam.cpp b/src/private/mx/core/generated/Beam.cpp index b3f5d3619..90f2a58fe 100644 --- a/src/private/mx/core/generated/Beam.cpp +++ b/src/private/mx/core/generated/Beam.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Beam.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -71,6 +72,11 @@ void Beam::setValue(BeamValue value) } Beam parseBeam(pugi::xml_node el) +{ + return parseBeam(el, ParseContext{}); +} + +Beam parseBeam(pugi::xml_node el, const ParseContext &context) { Beam out; for (pugi::xml_attribute a : el.attributes()) @@ -82,19 +88,19 @@ Beam parseBeam(pugi::xml_node el) } if (aname == "number") { - out.setNumber(BeamLevel::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else if (aname == "repeater") { - out.setRepeater(YesNo::parse(a.value())); + out.setRepeater(parseValue(a.value(), context, el, "repeater")); } else if (aname == "fan") { - out.setFan(Fan::parse(a.value())); + out.setFan(parseValue(a.value(), context, el, "fan")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "id") { @@ -105,13 +111,18 @@ Beam parseBeam(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseBeamContent(out, el); + parseBeamContent(out, el, context); return out; } void parseBeamContent(Beam &out, pugi::xml_node el) { - out.setValue(BeamValue::parse(childText(el))); + parseBeamContent(out, el, ParseContext{}); +} + +void parseBeamContent(Beam &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Beam.h b/src/private/mx/core/generated/Beam.h index 508173146..d857ef9a2 100644 --- a/src/private/mx/core/generated/Beam.h +++ b/src/private/mx/core/generated/Beam.h @@ -21,6 +21,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Beam values include begin, continue, end, forward hook, and backward hook. Up to eight concurrent /// beams are available to cover up to 1024th notes. Each beam in a note is represented with a /// separate beam element, starting with the eighth note beam using a number attribute of 1. Note @@ -59,8 +61,12 @@ class Beam final Beam parseBeam(pugi::xml_node el); +Beam parseBeam(pugi::xml_node el, const ParseContext &context); + void parseBeamContent(Beam &out, pugi::xml_node el); +void parseBeamContent(Beam &out, pugi::xml_node el, const ParseContext &context); + void serializeBeam(const Beam &v, pugi::xml_node parent, const char *tag); void serializeBeamContent(const Beam &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/BeamLevel.cpp b/src/private/mx/core/generated/BeamLevel.cpp index 21a0012e2..60b45f2e1 100644 --- a/src/private/mx/core/generated/BeamLevel.cpp +++ b/src/private/mx/core/generated/BeamLevel.cpp @@ -42,20 +42,33 @@ std::string BeamLevel::toString() const bool BeamLevel::tryParse(std::string_view text, BeamLevel &out) { - int v{}; - if (!tryParseInt(text, v)) + ValueParseOutcome outcome = ValueParseOutcome::valid; + BeamLevel parsed = parse(text, outcome); + if (outcome == ValueParseOutcome::invalid) { return false; } - out = BeamLevel{v}; + out = std::move(parsed); return true; } BeamLevel BeamLevel::parse(std::string_view text) { - BeamLevel v; - tryParse(text, v); - return v; + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +BeamLevel BeamLevel::parse(std::string_view text, ValueParseOutcome &outcome) +{ + int v{}; + if (!tryParseInt(text, v)) + { + outcome = ValueParseOutcome::invalid; + return BeamLevel{}; + } + BeamLevel out{v}; + outcome = out.value() == v ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; } } // namespace mx::core diff --git a/src/private/mx/core/generated/BeamLevel.h b/src/private/mx/core/generated/BeamLevel.h index 74a555fe4..afba0ccdb 100644 --- a/src/private/mx/core/generated/BeamLevel.h +++ b/src/private/mx/core/generated/BeamLevel.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -37,6 +39,9 @@ class BeamLevel final /// Lenient: non-numeric text yields the clamped zero. static BeamLevel parse(std::string_view text); + /// Lenient, and says whether the text was non-numeric or clamped. + static BeamLevel parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const BeamLevel &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/BeamValue.cpp b/src/private/mx/core/generated/BeamValue.cpp index 748b414ac..a868d5188 100644 --- a/src/private/mx/core/generated/BeamValue.cpp +++ b/src/private/mx/core/generated/BeamValue.cpp @@ -56,9 +56,15 @@ bool BeamValue::tryParse(std::string_view text, BeamValue &out) noexcept } BeamValue BeamValue::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +BeamValue BeamValue::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { BeamValue v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/BeamValue.h b/src/private/mx/core/generated/BeamValue.h index 824c8eb7e..eaffde993 100644 --- a/src/private/mx/core/generated/BeamValue.h +++ b/src/private/mx/core/generated/BeamValue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -47,6 +49,9 @@ class BeamValue final /// (the import leniency policy; never produces an invalid value). static BeamValue parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static BeamValue parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const BeamValue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/BeatRepeat.cpp b/src/private/mx/core/generated/BeatRepeat.cpp index dd68fefb4..2c9612dd2 100644 --- a/src/private/mx/core/generated/BeatRepeat.cpp +++ b/src/private/mx/core/generated/BeatRepeat.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/BeatRepeat.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -51,6 +52,11 @@ void BeatRepeat::setSlash(std::optional value) } BeatRepeat parseBeatRepeat(pugi::xml_node el) +{ + return parseBeatRepeat(el, ParseContext{}); +} + +BeatRepeat parseBeatRepeat(pugi::xml_node el, const ParseContext &context) { BeatRepeat out; bool seen_type = false; @@ -64,15 +70,15 @@ BeatRepeat parseBeatRepeat(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(StartStop::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "slashes") { - out.setSlashes(parseInt(a.value())); + out.setSlashes(parseIntegerValue(a.value(), context, el, "slashes")); } else if (aname == "use-dots") { - out.setUseDots(YesNo::parse(a.value())); + out.setUseDots(parseValue(a.value(), context, el, "use-dots")); } else { @@ -83,16 +89,21 @@ BeatRepeat parseBeatRepeat(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseBeatRepeatContent(out, el); + parseBeatRepeatContent(out, el, context); return out; } void parseBeatRepeatContent(BeatRepeat &out, pugi::xml_node el) +{ + parseBeatRepeatContent(out, el, ParseContext{}); +} + +void parseBeatRepeatContent(BeatRepeat &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "slash-type") || cursorIs(cursor, "except-voice"))) { - out.setSlash(parseSlashGroup(el, cursor)); + out.setSlash(parseSlashGroup(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/BeatRepeat.h b/src/private/mx/core/generated/BeatRepeat.h index a12c5aaf3..8ca873153 100644 --- a/src/private/mx/core/generated/BeatRepeat.h +++ b/src/private/mx/core/generated/BeatRepeat.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The beat-repeat type is used to indicate that a single beat (but possibly many notes) is /// repeated. The slashes attribute specifies the number of slashes to use in the symbol. The /// use-dots attribute indicates whether or not to use dots as well (for instance, with mixed rhythm @@ -52,8 +54,12 @@ class BeatRepeat final BeatRepeat parseBeatRepeat(pugi::xml_node el); +BeatRepeat parseBeatRepeat(pugi::xml_node el, const ParseContext &context); + void parseBeatRepeatContent(BeatRepeat &out, pugi::xml_node el); +void parseBeatRepeatContent(BeatRepeat &out, pugi::xml_node el, const ParseContext &context); + void serializeBeatRepeat(const BeatRepeat &v, pugi::xml_node parent, const char *tag); void serializeBeatRepeatContent(const BeatRepeat &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/BeatUnitGroup.cpp b/src/private/mx/core/generated/BeatUnitGroup.cpp index 07d6f4394..15d231b89 100644 --- a/src/private/mx/core/generated/BeatUnitGroup.cpp +++ b/src/private/mx/core/generated/BeatUnitGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/BeatUnitGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -36,11 +37,16 @@ void BeatUnitGroup::setBeatUnitDot(std::vector value) } BeatUnitGroup parseBeatUnitGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseBeatUnitGroup(el, cursor, ParseContext{}); +} + +BeatUnitGroup parseBeatUnitGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { BeatUnitGroup out; if (cursorIs(cursor, "beat-unit")) { - out.setBeatUnit(NoteTypeValue::parse(childText(cursor))); + out.setBeatUnit(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -49,7 +55,7 @@ BeatUnitGroup parseBeatUnitGroup(pugi::xml_node el, pugi::xml_node &cursor) } while (cursorIs(cursor, "beat-unit-dot")) { - out.addBeatUnitDot(parseEmpty(cursor)); + out.addBeatUnitDot(parseEmpty(cursor, context)); cursor = nextElement(cursor); } return out; diff --git a/src/private/mx/core/generated/BeatUnitGroup.h b/src/private/mx/core/generated/BeatUnitGroup.h index b58bea6f3..1210d5b27 100644 --- a/src/private/mx/core/generated/BeatUnitGroup.h +++ b/src/private/mx/core/generated/BeatUnitGroup.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The beat-unit group combines elements used repeatedly in the metronome element to specify a note /// within a metronome mark. /// A shared content group: transparent on the wire, its @@ -41,6 +43,8 @@ class BeatUnitGroup final /// is the enclosing element, for error paths. BeatUnitGroup parseBeatUnitGroup(pugi::xml_node el, pugi::xml_node &cursor); +BeatUnitGroup parseBeatUnitGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeBeatUnitGroup(const BeatUnitGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/BeatUnitTied.cpp b/src/private/mx/core/generated/BeatUnitTied.cpp index 0ca4eb2ff..4a6679b83 100644 --- a/src/private/mx/core/generated/BeatUnitTied.cpp +++ b/src/private/mx/core/generated/BeatUnitTied.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/BeatUnitTied.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -21,6 +22,11 @@ void BeatUnitTied::setBeatUnit(BeatUnitGroup value) } BeatUnitTied parseBeatUnitTied(pugi::xml_node el) +{ + return parseBeatUnitTied(el, ParseContext{}); +} + +BeatUnitTied parseBeatUnitTied(pugi::xml_node el, const ParseContext &context) { BeatUnitTied out; for (pugi::xml_attribute a : el.attributes()) @@ -32,16 +38,21 @@ BeatUnitTied parseBeatUnitTied(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseBeatUnitTiedContent(out, el); + parseBeatUnitTiedContent(out, el, context); return out; } void parseBeatUnitTiedContent(BeatUnitTied &out, pugi::xml_node el) +{ + parseBeatUnitTiedContent(out, el, ParseContext{}); +} + +void parseBeatUnitTiedContent(BeatUnitTied &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "beat-unit"))) { - out.setBeatUnit(parseBeatUnitGroup(el, cursor)); + out.setBeatUnit(parseBeatUnitGroup(el, cursor, context)); } else { diff --git a/src/private/mx/core/generated/BeatUnitTied.h b/src/private/mx/core/generated/BeatUnitTied.h index 2a2e755da..204e084a3 100644 --- a/src/private/mx/core/generated/BeatUnitTied.h +++ b/src/private/mx/core/generated/BeatUnitTied.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The beat-unit-tied type indicates a beat-unit within a metronome mark that is tied to the /// preceding beat-unit. This allows two or more tied notes to be associated with a per-minute value /// in a metronome mark, whereas the metronome-tied element is restricted to metric relationship @@ -36,8 +38,12 @@ class BeatUnitTied final BeatUnitTied parseBeatUnitTied(pugi::xml_node el); +BeatUnitTied parseBeatUnitTied(pugi::xml_node el, const ParseContext &context); + void parseBeatUnitTiedContent(BeatUnitTied &out, pugi::xml_node el); +void parseBeatUnitTiedContent(BeatUnitTied &out, pugi::xml_node el, const ParseContext &context); + void serializeBeatUnitTied(const BeatUnitTied &v, pugi::xml_node parent, const char *tag); void serializeBeatUnitTiedContent(const BeatUnitTied &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Beater.cpp b/src/private/mx/core/generated/Beater.cpp index 718609dd1..9107c5857 100644 --- a/src/private/mx/core/generated/Beater.cpp +++ b/src/private/mx/core/generated/Beater.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Beater.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void Beater::setValue(BeaterValue value) } Beater parseBeater(pugi::xml_node el) +{ + return parseBeater(el, ParseContext{}); +} + +Beater parseBeater(pugi::xml_node el, const ParseContext &context) { Beater out; for (pugi::xml_attribute a : el.attributes()) @@ -42,20 +48,25 @@ Beater parseBeater(pugi::xml_node el) } if (aname == "tip") { - out.setTip(TipDirection::parse(a.value())); + out.setTip(parseValue(a.value(), context, el, "tip")); } else { throwUnknownAttribute(el, a.name()); } } - parseBeaterContent(out, el); + parseBeaterContent(out, el, context); return out; } void parseBeaterContent(Beater &out, pugi::xml_node el) { - out.setValue(BeaterValue::parse(childText(el))); + parseBeaterContent(out, el, ParseContext{}); +} + +void parseBeaterContent(Beater &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Beater.h b/src/private/mx/core/generated/Beater.h index 9c776b097..9d3a2561c 100644 --- a/src/private/mx/core/generated/Beater.h +++ b/src/private/mx/core/generated/Beater.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The beater type represents pictograms for beaters, mallets, and sticks that do not have different /// materials represented in the pictogram. class Beater final @@ -34,8 +36,12 @@ class Beater final Beater parseBeater(pugi::xml_node el); +Beater parseBeater(pugi::xml_node el, const ParseContext &context); + void parseBeaterContent(Beater &out, pugi::xml_node el); +void parseBeaterContent(Beater &out, pugi::xml_node el, const ParseContext &context); + void serializeBeater(const Beater &v, pugi::xml_node parent, const char *tag); void serializeBeaterContent(const Beater &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/BeaterValue.cpp b/src/private/mx/core/generated/BeaterValue.cpp index 499931e7e..26587e455 100644 --- a/src/private/mx/core/generated/BeaterValue.cpp +++ b/src/private/mx/core/generated/BeaterValue.cpp @@ -150,9 +150,15 @@ bool BeaterValue::tryParse(std::string_view text, BeaterValue &out) noexcept } BeaterValue BeaterValue::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +BeaterValue BeaterValue::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { BeaterValue v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/BeaterValue.h b/src/private/mx/core/generated/BeaterValue.h index 7530d8790..01048ea06 100644 --- a/src/private/mx/core/generated/BeaterValue.h +++ b/src/private/mx/core/generated/BeaterValue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -78,6 +80,9 @@ class BeaterValue final /// (the import leniency policy; never produces an invalid value). static BeaterValue parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static BeaterValue parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const BeaterValue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Bend.cpp b/src/private/mx/core/generated/Bend.cpp index 227908031..681ecb823 100644 --- a/src/private/mx/core/generated/Bend.cpp +++ b/src/private/mx/core/generated/Bend.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Bend.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -181,6 +182,11 @@ void Bend::setWithBar(std::optional value) } Bend parseBend(pugi::xml_node el) +{ + return parseBend(el, ParseContext{}); +} + +Bend parseBend(pugi::xml_node el, const ParseContext &context) { Bend out; for (pugi::xml_attribute a : el.attributes()) @@ -192,75 +198,80 @@ Bend parseBend(pugi::xml_node el) } if (aname == "shape") { - out.setShape(BendShape::parse(a.value())); + out.setShape(parseValue(a.value(), context, el, "shape")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "accelerate") { - out.setAccelerate(YesNo::parse(a.value())); + out.setAccelerate(parseValue(a.value(), context, el, "accelerate")); } else if (aname == "beats") { - out.setBeats(TrillBeats::parse(a.value())); + out.setBeats(parseValue(a.value(), context, el, "beats")); } else if (aname == "first-beat") { - out.setFirstBeat(Percent::parse(a.value())); + out.setFirstBeat(parseValue(a.value(), context, el, "first-beat")); } else if (aname == "last-beat") { - out.setLastBeat(Percent::parse(a.value())); + out.setLastBeat(parseValue(a.value(), context, el, "last-beat")); } else { throwUnknownAttribute(el, a.name()); } } - parseBendContent(out, el); + parseBendContent(out, el, context); return out; } void parseBendContent(Bend &out, pugi::xml_node el) +{ + parseBendContent(out, el, ParseContext{}); +} + +void parseBendContent(Bend &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "bend-alter")) { - out.setBendAlter(Semitones::parse(childText(cursor))); + out.setBendAlter(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -269,11 +280,11 @@ void parseBendContent(Bend &out, pugi::xml_node el) } if (cursor && (cursorIs(cursor, "pre-bend") || cursorIs(cursor, "release"))) { - out.setChoice(parseBendChoice(el, cursor)); + out.setChoice(parseBendChoice(el, cursor, context)); } if (cursorIs(cursor, "with-bar")) { - out.setWithBar(parsePlacementText(cursor)); + out.setWithBar(parsePlacementText(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/Bend.h b/src/private/mx/core/generated/Bend.h index 8aa6d8212..c7c7bcdf0 100644 --- a/src/private/mx/core/generated/Bend.h +++ b/src/private/mx/core/generated/Bend.h @@ -29,6 +29,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The bend type is used in guitar notation and tablature. A single note with a bend and release /// will contain two bend elements: the first to represent the bend and the second to represent the /// release. The shape attribute distinguishes between the angled bend symbols commonly used in @@ -97,8 +99,12 @@ class Bend final Bend parseBend(pugi::xml_node el); +Bend parseBend(pugi::xml_node el, const ParseContext &context); + void parseBendContent(Bend &out, pugi::xml_node el); +void parseBendContent(Bend &out, pugi::xml_node el, const ParseContext &context); + void serializeBend(const Bend &v, pugi::xml_node parent, const char *tag); void serializeBendContent(const Bend &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/BendChoice.cpp b/src/private/mx/core/generated/BendChoice.cpp index 1500c8d33..8866d0549 100644 --- a/src/private/mx/core/generated/BendChoice.cpp +++ b/src/private/mx/core/generated/BendChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/BendChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -26,16 +27,21 @@ BendChoice BendChoice::release(Release value) } BendChoice parseBendChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseBendChoice(el, cursor, ParseContext{}); +} + +BendChoice parseBendChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "pre-bend"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return BendChoice::preBend(std::move(value)); } if (cursor && (cursorIs(cursor, "release"))) { - Release value = parseRelease(cursor); + Release value = parseRelease(cursor, context); cursor = nextElement(cursor); return BendChoice::release(std::move(value)); } diff --git a/src/private/mx/core/generated/BendChoice.h b/src/private/mx/core/generated/BendChoice.h index 6ce0d3ede..669ac8116 100644 --- a/src/private/mx/core/generated/BendChoice.h +++ b/src/private/mx/core/generated/BendChoice.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -82,6 +84,8 @@ class BendChoice final /// the enclosing element, for error paths. BendChoice parseBendChoice(pugi::xml_node el, pugi::xml_node &cursor); +BendChoice parseBendChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeBendChoice(const BendChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/BendShape.cpp b/src/private/mx/core/generated/BendShape.cpp index a3675a69c..e4380e56c 100644 --- a/src/private/mx/core/generated/BendShape.cpp +++ b/src/private/mx/core/generated/BendShape.cpp @@ -42,9 +42,15 @@ bool BendShape::tryParse(std::string_view text, BendShape &out) noexcept } BendShape BendShape::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +BendShape BendShape::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { BendShape v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/BendShape.h b/src/private/mx/core/generated/BendShape.h index 0cf7a4444..681c0b8a9 100644 --- a/src/private/mx/core/generated/BendShape.h +++ b/src/private/mx/core/generated/BendShape.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -41,6 +43,9 @@ class BendShape final /// (the import leniency policy; never produces an invalid value). static BendShape parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static BendShape parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const BendShape &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Bookmark.cpp b/src/private/mx/core/generated/Bookmark.cpp index a3ef099b6..061ba76a6 100644 --- a/src/private/mx/core/generated/Bookmark.cpp +++ b/src/private/mx/core/generated/Bookmark.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Bookmark.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -51,6 +52,11 @@ void Bookmark::setPosition(std::optional value) } Bookmark parseBookmark(pugi::xml_node el) +{ + return parseBookmark(el, ParseContext{}); +} + +Bookmark parseBookmark(pugi::xml_node el, const ParseContext &context) { Bookmark out; bool seen_id = false; @@ -76,7 +82,7 @@ Bookmark parseBookmark(pugi::xml_node el) } else if (aname == "position") { - out.setPosition(parseInt(a.value())); + out.setPosition(parseIntegerValue(a.value(), context, el, "position")); } else { @@ -87,13 +93,19 @@ Bookmark parseBookmark(pugi::xml_node el) { throwMissingAttribute(el, "id"); } - parseBookmarkContent(out, el); + parseBookmarkContent(out, el, context); return out; } void parseBookmarkContent(Bookmark &out, pugi::xml_node el) +{ + parseBookmarkContent(out, el, ParseContext{}); +} + +void parseBookmarkContent(Bookmark &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Bookmark.h b/src/private/mx/core/generated/Bookmark.h index efef95d7c..4dbbd44cd 100644 --- a/src/private/mx/core/generated/Bookmark.h +++ b/src/private/mx/core/generated/Bookmark.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The bookmark type serves as a well-defined target for an incoming simple XLink. class Bookmark final { @@ -39,8 +41,12 @@ class Bookmark final Bookmark parseBookmark(pugi::xml_node el); +Bookmark parseBookmark(pugi::xml_node el, const ParseContext &context); + void parseBookmarkContent(Bookmark &out, pugi::xml_node el); +void parseBookmarkContent(Bookmark &out, pugi::xml_node el, const ParseContext &context); + void serializeBookmark(const Bookmark &v, pugi::xml_node parent, const char *tag); void serializeBookmarkContent(const Bookmark &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Bracket.cpp b/src/private/mx/core/generated/Bracket.cpp index f3f4bdbef..821af4a24 100644 --- a/src/private/mx/core/generated/Bracket.cpp +++ b/src/private/mx/core/generated/Bracket.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Bracket.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -141,6 +142,11 @@ void Bracket::setID(std::optional value) } Bracket parseBracket(pugi::xml_node el) +{ + return parseBracket(el, ParseContext{}); +} + +Bracket parseBracket(pugi::xml_node el, const ParseContext &context) { Bracket out; bool seen_type = false; @@ -155,52 +161,52 @@ Bracket parseBracket(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(StartStopContinue::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "number") { - out.setNumber(NumberLevel::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else if (aname == "line-end") { seen_lineEnd = true; - out.setLineEnd(LineEnd::parse(a.value())); + out.setLineEnd(parseValue(a.value(), context, el, "line-end")); } else if (aname == "end-length") { - out.setEndLength(Tenths::parse(a.value())); + out.setEndLength(parseValue(a.value(), context, el, "end-length")); } else if (aname == "line-type") { - out.setLineType(LineType::parse(a.value())); + out.setLineType(parseValue(a.value(), context, el, "line-type")); } else if (aname == "dash-length") { - out.setDashLength(Tenths::parse(a.value())); + out.setDashLength(parseValue(a.value(), context, el, "dash-length")); } else if (aname == "space-length") { - out.setSpaceLength(Tenths::parse(a.value())); + out.setSpaceLength(parseValue(a.value(), context, el, "space-length")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "id") { @@ -219,13 +225,19 @@ Bracket parseBracket(pugi::xml_node el) { throwMissingAttribute(el, "line-end"); } - parseBracketContent(out, el); + parseBracketContent(out, el, context); return out; } void parseBracketContent(Bracket &out, pugi::xml_node el) +{ + parseBracketContent(out, el, ParseContext{}); +} + +void parseBracketContent(Bracket &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Bracket.h b/src/private/mx/core/generated/Bracket.h index f05da8c26..a83a9e5b8 100644 --- a/src/private/mx/core/generated/Bracket.h +++ b/src/private/mx/core/generated/Bracket.h @@ -22,6 +22,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Brackets are combined with words in a variety of modern directions. The line-end attribute /// specifies if there is a jog up or down (or both), an arrow, or nothing at the start or end of the /// bracket. If the line-end is up or down, the length of the jog can be specified using the @@ -75,8 +77,12 @@ class Bracket final Bracket parseBracket(pugi::xml_node el); +Bracket parseBracket(pugi::xml_node el, const ParseContext &context); + void parseBracketContent(Bracket &out, pugi::xml_node el); +void parseBracketContent(Bracket &out, pugi::xml_node el, const ParseContext &context); + void serializeBracket(const Bracket &v, pugi::xml_node parent, const char *tag); void serializeBracketContent(const Bracket &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/BreathMark.cpp b/src/private/mx/core/generated/BreathMark.cpp index de5bf33fb..b73c4f69e 100644 --- a/src/private/mx/core/generated/BreathMark.cpp +++ b/src/private/mx/core/generated/BreathMark.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/BreathMark.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -121,6 +122,11 @@ void BreathMark::setValue(BreathMarkValue value) } BreathMark parseBreathMark(pugi::xml_node el) +{ + return parseBreathMark(el, ParseContext{}); +} + +BreathMark parseBreathMark(pugi::xml_node el, const ParseContext &context) { BreathMark out; for (pugi::xml_attribute a : el.attributes()) @@ -132,56 +138,61 @@ BreathMark parseBreathMark(pugi::xml_node el) } if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else { throwUnknownAttribute(el, a.name()); } } - parseBreathMarkContent(out, el); + parseBreathMarkContent(out, el, context); return out; } void parseBreathMarkContent(BreathMark &out, pugi::xml_node el) { - out.setValue(BreathMarkValue::parse(childText(el))); + parseBreathMarkContent(out, el, ParseContext{}); +} + +void parseBreathMarkContent(BreathMark &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/BreathMark.h b/src/private/mx/core/generated/BreathMark.h index 2cdb98007..9962a7044 100644 --- a/src/private/mx/core/generated/BreathMark.h +++ b/src/private/mx/core/generated/BreathMark.h @@ -22,6 +22,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The breath-mark element indicates a place to take a breath. class BreathMark final { @@ -66,8 +68,12 @@ class BreathMark final BreathMark parseBreathMark(pugi::xml_node el); +BreathMark parseBreathMark(pugi::xml_node el, const ParseContext &context); + void parseBreathMarkContent(BreathMark &out, pugi::xml_node el); +void parseBreathMarkContent(BreathMark &out, pugi::xml_node el, const ParseContext &context); + void serializeBreathMark(const BreathMark &v, pugi::xml_node parent, const char *tag); void serializeBreathMarkContent(const BreathMark &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/BreathMarkValue.cpp b/src/private/mx/core/generated/BreathMarkValue.cpp index 8ececee9e..370ec4d11 100644 --- a/src/private/mx/core/generated/BreathMarkValue.cpp +++ b/src/private/mx/core/generated/BreathMarkValue.cpp @@ -56,9 +56,15 @@ bool BreathMarkValue::tryParse(std::string_view text, BreathMarkValue &out) noex } BreathMarkValue BreathMarkValue::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +BreathMarkValue BreathMarkValue::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { BreathMarkValue v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/BreathMarkValue.h b/src/private/mx/core/generated/BreathMarkValue.h index ae7db17c4..be919e21c 100644 --- a/src/private/mx/core/generated/BreathMarkValue.h +++ b/src/private/mx/core/generated/BreathMarkValue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -46,6 +48,9 @@ class BreathMarkValue final /// (the import leniency policy; never produces an invalid value). static BreathMarkValue parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static BreathMarkValue parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const BreathMarkValue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/CSSFontSize.cpp b/src/private/mx/core/generated/CSSFontSize.cpp index 1726eb021..3921e34d0 100644 --- a/src/private/mx/core/generated/CSSFontSize.cpp +++ b/src/private/mx/core/generated/CSSFontSize.cpp @@ -66,9 +66,15 @@ bool CSSFontSize::tryParse(std::string_view text, CSSFontSize &out) noexcept } CSSFontSize CSSFontSize::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +CSSFontSize CSSFontSize::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { CSSFontSize v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/CSSFontSize.h b/src/private/mx/core/generated/CSSFontSize.h index 0a7b7fa3a..492747386 100644 --- a/src/private/mx/core/generated/CSSFontSize.h +++ b/src/private/mx/core/generated/CSSFontSize.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -51,6 +53,9 @@ class CSSFontSize final /// (the import leniency policy; never produces an invalid value). static CSSFontSize parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static CSSFontSize parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const CSSFontSize &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Caesura.cpp b/src/private/mx/core/generated/Caesura.cpp index 26e7a450d..3fafe625e 100644 --- a/src/private/mx/core/generated/Caesura.cpp +++ b/src/private/mx/core/generated/Caesura.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Caesura.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -121,6 +122,11 @@ void Caesura::setValue(CaesuraValue value) } Caesura parseCaesura(pugi::xml_node el) +{ + return parseCaesura(el, ParseContext{}); +} + +Caesura parseCaesura(pugi::xml_node el, const ParseContext &context) { Caesura out; for (pugi::xml_attribute a : el.attributes()) @@ -132,56 +138,61 @@ Caesura parseCaesura(pugi::xml_node el) } if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else { throwUnknownAttribute(el, a.name()); } } - parseCaesuraContent(out, el); + parseCaesuraContent(out, el, context); return out; } void parseCaesuraContent(Caesura &out, pugi::xml_node el) { - out.setValue(CaesuraValue::parse(childText(el))); + parseCaesuraContent(out, el, ParseContext{}); +} + +void parseCaesuraContent(Caesura &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Caesura.h b/src/private/mx/core/generated/Caesura.h index d28fb4b4f..e2282cd57 100644 --- a/src/private/mx/core/generated/Caesura.h +++ b/src/private/mx/core/generated/Caesura.h @@ -22,6 +22,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The caesura element indicates a slight pause. It is notated using a "railroad tracks" symbol or /// other variations specified in the element content. class Caesura final @@ -67,8 +69,12 @@ class Caesura final Caesura parseCaesura(pugi::xml_node el); +Caesura parseCaesura(pugi::xml_node el, const ParseContext &context); + void parseCaesuraContent(Caesura &out, pugi::xml_node el); +void parseCaesuraContent(Caesura &out, pugi::xml_node el, const ParseContext &context); + void serializeCaesura(const Caesura &v, pugi::xml_node parent, const char *tag); void serializeCaesuraContent(const Caesura &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/CaesuraValue.cpp b/src/private/mx/core/generated/CaesuraValue.cpp index af5dc8564..a352740c4 100644 --- a/src/private/mx/core/generated/CaesuraValue.cpp +++ b/src/private/mx/core/generated/CaesuraValue.cpp @@ -61,9 +61,15 @@ bool CaesuraValue::tryParse(std::string_view text, CaesuraValue &out) noexcept } CaesuraValue CaesuraValue::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +CaesuraValue CaesuraValue::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { CaesuraValue v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/CaesuraValue.h b/src/private/mx/core/generated/CaesuraValue.h index a93c0d9ab..961b7027d 100644 --- a/src/private/mx/core/generated/CaesuraValue.h +++ b/src/private/mx/core/generated/CaesuraValue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -48,6 +50,9 @@ class CaesuraValue final /// (the import leniency policy; never produces an invalid value). static CaesuraValue parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static CaesuraValue parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const CaesuraValue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Cancel.cpp b/src/private/mx/core/generated/Cancel.cpp index 7e0b18960..57efcf59c 100644 --- a/src/private/mx/core/generated/Cancel.cpp +++ b/src/private/mx/core/generated/Cancel.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Cancel.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void Cancel::setValue(Fifths value) } Cancel parseCancel(pugi::xml_node el) +{ + return parseCancel(el, ParseContext{}); +} + +Cancel parseCancel(pugi::xml_node el, const ParseContext &context) { Cancel out; for (pugi::xml_attribute a : el.attributes()) @@ -42,20 +48,25 @@ Cancel parseCancel(pugi::xml_node el) } if (aname == "location") { - out.setLocation(CancelLocation::parse(a.value())); + out.setLocation(parseValue(a.value(), context, el, "location")); } else { throwUnknownAttribute(el, a.name()); } } - parseCancelContent(out, el); + parseCancelContent(out, el, context); return out; } void parseCancelContent(Cancel &out, pugi::xml_node el) { - out.setValue(Fifths::parse(childText(el))); + parseCancelContent(out, el, ParseContext{}); +} + +void parseCancelContent(Cancel &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Cancel.h b/src/private/mx/core/generated/Cancel.h index 3c88e65af..695d50aab 100644 --- a/src/private/mx/core/generated/Cancel.h +++ b/src/private/mx/core/generated/Cancel.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A cancel element indicates that the old key signature should be cancelled before the new one /// appears. This will always happen when changing to C major or A minor and need not be specified /// then. The cancel value matches the fifths value of the cancelled key signature (e.g., a cancel of @@ -37,8 +39,12 @@ class Cancel final Cancel parseCancel(pugi::xml_node el); +Cancel parseCancel(pugi::xml_node el, const ParseContext &context); + void parseCancelContent(Cancel &out, pugi::xml_node el); +void parseCancelContent(Cancel &out, pugi::xml_node el, const ParseContext &context); + void serializeCancel(const Cancel &v, pugi::xml_node parent, const char *tag); void serializeCancelContent(const Cancel &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/CancelLocation.cpp b/src/private/mx/core/generated/CancelLocation.cpp index be8e5a88b..d4e894388 100644 --- a/src/private/mx/core/generated/CancelLocation.cpp +++ b/src/private/mx/core/generated/CancelLocation.cpp @@ -48,9 +48,15 @@ bool CancelLocation::tryParse(std::string_view text, CancelLocation &out) noexce } CancelLocation CancelLocation::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +CancelLocation CancelLocation::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { CancelLocation v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/CancelLocation.h b/src/private/mx/core/generated/CancelLocation.h index 19a5c8186..e172c74bb 100644 --- a/src/private/mx/core/generated/CancelLocation.h +++ b/src/private/mx/core/generated/CancelLocation.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -45,6 +47,9 @@ class CancelLocation final /// (the import leniency policy; never produces an invalid value). static CancelLocation parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static CancelLocation parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const CancelLocation &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/CircularArrow.cpp b/src/private/mx/core/generated/CircularArrow.cpp index 32e7aa641..f6af0e4fd 100644 --- a/src/private/mx/core/generated/CircularArrow.cpp +++ b/src/private/mx/core/generated/CircularArrow.cpp @@ -42,9 +42,15 @@ bool CircularArrow::tryParse(std::string_view text, CircularArrow &out) noexcept } CircularArrow CircularArrow::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +CircularArrow CircularArrow::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { CircularArrow v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/CircularArrow.h b/src/private/mx/core/generated/CircularArrow.h index c24fd3c6d..1e9305f16 100644 --- a/src/private/mx/core/generated/CircularArrow.h +++ b/src/private/mx/core/generated/CircularArrow.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -41,6 +43,9 @@ class CircularArrow final /// (the import leniency policy; never produces an invalid value). static CircularArrow parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static CircularArrow parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const CircularArrow &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Clef.cpp b/src/private/mx/core/generated/Clef.cpp index 1b1ca916b..419510369 100644 --- a/src/private/mx/core/generated/Clef.cpp +++ b/src/private/mx/core/generated/Clef.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Clef.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -171,6 +172,11 @@ void Clef::setClef(ClefGroup value) } Clef parseClef(pugi::xml_node el) +{ + return parseClef(el, ParseContext{}); +} + +Clef parseClef(pugi::xml_node el, const ParseContext &context) { Clef out; for (pugi::xml_attribute a : el.attributes()) @@ -182,59 +188,59 @@ Clef parseClef(pugi::xml_node el) } if (aname == "number") { - out.setNumber(StaffNumber::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else if (aname == "additional") { - out.setAdditional(YesNo::parse(a.value())); + out.setAdditional(parseValue(a.value(), context, el, "additional")); } else if (aname == "size") { - out.setSize(SymbolSize::parse(a.value())); + out.setSize(parseValue(a.value(), context, el, "size")); } else if (aname == "after-barline") { - out.setAfterBarline(YesNo::parse(a.value())); + out.setAfterBarline(parseValue(a.value(), context, el, "after-barline")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "print-object") { - out.setPrintObject(YesNo::parse(a.value())); + out.setPrintObject(parseValue(a.value(), context, el, "print-object")); } else if (aname == "id") { @@ -245,16 +251,21 @@ Clef parseClef(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseClefContent(out, el); + parseClefContent(out, el, context); return out; } void parseClefContent(Clef &out, pugi::xml_node el) +{ + parseClefContent(out, el, ParseContext{}); +} + +void parseClefContent(Clef &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "sign"))) { - out.setClef(parseClefGroup(el, cursor)); + out.setClef(parseClefGroup(el, cursor, context)); } else { diff --git a/src/private/mx/core/generated/Clef.h b/src/private/mx/core/generated/Clef.h index ccaafe4e6..9e268bbad 100644 --- a/src/private/mx/core/generated/Clef.h +++ b/src/private/mx/core/generated/Clef.h @@ -28,6 +28,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Clefs are represented by a combination of sign, line, and clef-octave-change elements. The /// optional number attribute refers to staff numbers within the part. A value of 1 is assumed if not /// present. Sometimes clefs are added to the staff in non-standard line positions, either to @@ -99,8 +101,12 @@ class Clef final Clef parseClef(pugi::xml_node el); +Clef parseClef(pugi::xml_node el, const ParseContext &context); + void parseClefContent(Clef &out, pugi::xml_node el); +void parseClefContent(Clef &out, pugi::xml_node el, const ParseContext &context); + void serializeClef(const Clef &v, pugi::xml_node parent, const char *tag); void serializeClefContent(const Clef &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/ClefGroup.cpp b/src/private/mx/core/generated/ClefGroup.cpp index fec9da9ca..053208694 100644 --- a/src/private/mx/core/generated/ClefGroup.cpp +++ b/src/private/mx/core/generated/ClefGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/ClefGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,11 +42,16 @@ void ClefGroup::setClefOctaveChange(std::optional value) } ClefGroup parseClefGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseClefGroup(el, cursor, ParseContext{}); +} + +ClefGroup parseClefGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { ClefGroup out; if (cursorIs(cursor, "sign")) { - out.setSign(ClefSign::parse(childText(cursor))); + out.setSign(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -54,12 +60,12 @@ ClefGroup parseClefGroup(pugi::xml_node el, pugi::xml_node &cursor) } if (cursorIs(cursor, "line")) { - out.setLine(StaffLinePosition::parse(childText(cursor))); + out.setLine(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (cursorIs(cursor, "clef-octave-change")) { - out.setClefOctaveChange(parseInt(childText(cursor))); + out.setClefOctaveChange(parseIntegerValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } return out; diff --git a/src/private/mx/core/generated/ClefGroup.h b/src/private/mx/core/generated/ClefGroup.h index a10d876d9..137e40f98 100644 --- a/src/private/mx/core/generated/ClefGroup.h +++ b/src/private/mx/core/generated/ClefGroup.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Clefs are represented by a combination of sign, line, and clef-octave-change elements. /// A shared content group: transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -42,6 +44,8 @@ class ClefGroup final /// is the enclosing element, for error paths. ClefGroup parseClefGroup(pugi::xml_node el, pugi::xml_node &cursor); +ClefGroup parseClefGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeClefGroup(const ClefGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/ClefSign.cpp b/src/private/mx/core/generated/ClefSign.cpp index 0bd6cf61e..5427fa242 100644 --- a/src/private/mx/core/generated/ClefSign.cpp +++ b/src/private/mx/core/generated/ClefSign.cpp @@ -66,9 +66,15 @@ bool ClefSign::tryParse(std::string_view text, ClefSign &out) noexcept } ClefSign ClefSign::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +ClefSign ClefSign::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { ClefSign v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/ClefSign.h b/src/private/mx/core/generated/ClefSign.h index 28c939099..86cfc9691 100644 --- a/src/private/mx/core/generated/ClefSign.h +++ b/src/private/mx/core/generated/ClefSign.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -55,6 +57,9 @@ class ClefSign final /// (the import leniency policy; never produces an invalid value). static ClefSign parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static ClefSign parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const ClefSign &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Coda.cpp b/src/private/mx/core/generated/Coda.cpp index 83310b363..acc4b4720 100644 --- a/src/private/mx/core/generated/Coda.cpp +++ b/src/private/mx/core/generated/Coda.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Coda.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -141,6 +142,11 @@ void Coda::setID(std::optional value) } Coda parseCoda(pugi::xml_node el) +{ + return parseCoda(el, ParseContext{}); +} + +Coda parseCoda(pugi::xml_node el, const ParseContext &context) { Coda out; for (pugi::xml_attribute a : el.attributes()) @@ -152,51 +158,51 @@ Coda parseCoda(pugi::xml_node el) } if (aname == "smufl") { - out.setSmufl(SmuflCodaGlyphName::parse(a.value())); + out.setSmufl(parseValue(a.value(), context, el, "smufl")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "halign") { - out.setHalign(LeftCenterRight::parse(a.value())); + out.setHalign(parseValue(a.value(), context, el, "halign")); } else if (aname == "valign") { - out.setValign(Valign::parse(a.value())); + out.setValign(parseValue(a.value(), context, el, "valign")); } else if (aname == "id") { @@ -207,13 +213,19 @@ Coda parseCoda(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseCodaContent(out, el); + parseCodaContent(out, el, context); return out; } void parseCodaContent(Coda &out, pugi::xml_node el) +{ + parseCodaContent(out, el, ParseContext{}); +} + +void parseCodaContent(Coda &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Coda.h b/src/private/mx/core/generated/Coda.h index 28482ec3d..fae463714 100644 --- a/src/private/mx/core/generated/Coda.h +++ b/src/private/mx/core/generated/Coda.h @@ -25,6 +25,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The coda type is the visual indicator of a coda sign. The exact glyph can be specified with the /// smufl attribute. A sound element is also needed to guide playback applications reliably. class Coda final @@ -76,8 +78,12 @@ class Coda final Coda parseCoda(pugi::xml_node el); +Coda parseCoda(pugi::xml_node el, const ParseContext &context); + void parseCodaContent(Coda &out, pugi::xml_node el); +void parseCodaContent(Coda &out, pugi::xml_node el, const ParseContext &context); + void serializeCoda(const Coda &v, pugi::xml_node parent, const char *tag); void serializeCodaContent(const Coda &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Credit.cpp b/src/private/mx/core/generated/Credit.cpp index 834ed45d1..110a7fe31 100644 --- a/src/private/mx/core/generated/Credit.cpp +++ b/src/private/mx/core/generated/Credit.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Credit.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -86,6 +87,11 @@ void Credit::setChoice(CreditChoice value) } Credit parseCredit(pugi::xml_node el) +{ + return parseCredit(el, ParseContext{}); +} + +Credit parseCredit(pugi::xml_node el, const ParseContext &context) { Credit out; for (pugi::xml_attribute a : el.attributes()) @@ -97,7 +103,7 @@ Credit parseCredit(pugi::xml_node el) } if (aname == "page") { - out.setPage(parseInt(a.value())); + out.setPage(parseIntegerValue(a.value(), context, el, "page")); } else if (aname == "id") { @@ -108,11 +114,16 @@ Credit parseCredit(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseCreditContent(out, el); + parseCreditContent(out, el, context); return out; } void parseCreditContent(Credit &out, pugi::xml_node el) +{ + parseCreditContent(out, el, ParseContext{}); +} + +void parseCreditContent(Credit &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); while (cursorIs(cursor, "credit-type")) @@ -122,18 +133,18 @@ void parseCreditContent(Credit &out, pugi::xml_node el) } while (cursorIs(cursor, "link")) { - out.addLink(parseLink(cursor)); + out.addLink(parseLink(cursor, context)); cursor = nextElement(cursor); } while (cursorIs(cursor, "bookmark")) { - out.addBookmark(parseBookmark(cursor)); + out.addBookmark(parseBookmark(cursor, context)); cursor = nextElement(cursor); } if (cursor && (cursorIs(cursor, "credit-image") || cursorIs(cursor, "credit-words") || cursorIs(cursor, "credit-symbol"))) { - out.setChoice(parseCreditChoice(el, cursor)); + out.setChoice(parseCreditChoice(el, cursor, context)); } else { diff --git a/src/private/mx/core/generated/Credit.h b/src/private/mx/core/generated/Credit.h index 1a2f70a03..542e2350d 100644 --- a/src/private/mx/core/generated/Credit.h +++ b/src/private/mx/core/generated/Credit.h @@ -21,6 +21,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The credit type represents the appearance of the title, composer, arranger, lyricist, copyright, /// dedication, and other text, symbols, and graphics that commonly appear on the first page of a /// score. The credit-words, credit-symbol, and credit-image elements are similar to the words, @@ -69,8 +71,12 @@ class Credit final Credit parseCredit(pugi::xml_node el); +Credit parseCredit(pugi::xml_node el, const ParseContext &context); + void parseCreditContent(Credit &out, pugi::xml_node el); +void parseCreditContent(Credit &out, pugi::xml_node el, const ParseContext &context); + void serializeCredit(const Credit &v, pugi::xml_node parent, const char *tag); void serializeCreditContent(const Credit &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/CreditChoice.cpp b/src/private/mx/core/generated/CreditChoice.cpp index 1c2300a86..ca6df48d2 100644 --- a/src/private/mx/core/generated/CreditChoice.cpp +++ b/src/private/mx/core/generated/CreditChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/CreditChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -26,16 +27,21 @@ CreditChoice CreditChoice::group(CreditChoiceGroup value) } CreditChoice parseCreditChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseCreditChoice(el, cursor, ParseContext{}); +} + +CreditChoice parseCreditChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "credit-image"))) { - Image value = parseImage(cursor); + Image value = parseImage(cursor, context); cursor = nextElement(cursor); return CreditChoice::creditImage(std::move(value)); } if (cursor && (cursorIs(cursor, "credit-words") || cursorIs(cursor, "credit-symbol"))) { - return CreditChoice::group(parseCreditChoiceGroup(el, cursor)); + return CreditChoice::group(parseCreditChoiceGroup(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/CreditChoice.h b/src/private/mx/core/generated/CreditChoice.h index 94c649e21..a8adafede 100644 --- a/src/private/mx/core/generated/CreditChoice.h +++ b/src/private/mx/core/generated/CreditChoice.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -82,6 +84,8 @@ class CreditChoice final /// the enclosing element, for error paths. CreditChoice parseCreditChoice(pugi::xml_node el, pugi::xml_node &cursor); +CreditChoice parseCreditChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeCreditChoice(const CreditChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/CreditChoiceGroup.cpp b/src/private/mx/core/generated/CreditChoiceGroup.cpp index 7b5b55bca..6bfd61b5e 100644 --- a/src/private/mx/core/generated/CreditChoiceGroup.cpp +++ b/src/private/mx/core/generated/CreditChoiceGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/CreditChoiceGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -36,11 +37,16 @@ void CreditChoiceGroup::setGroup(std::vector value) } CreditChoiceGroup parseCreditChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseCreditChoiceGroup(el, cursor, ParseContext{}); +} + +CreditChoiceGroup parseCreditChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { CreditChoiceGroup out; if (cursor && (cursorIs(cursor, "credit-words") || cursorIs(cursor, "credit-symbol"))) { - out.setChoice(parseCreditChoiceGroupChoice(el, cursor)); + out.setChoice(parseCreditChoiceGroupChoice(el, cursor, context)); } else { @@ -49,7 +55,7 @@ CreditChoiceGroup parseCreditChoiceGroup(pugi::xml_node el, pugi::xml_node &curs while (cursor && (cursorIs(cursor, "link") || cursorIs(cursor, "bookmark") || cursorIs(cursor, "credit-words") || cursorIs(cursor, "credit-symbol"))) { - out.addGroup(parseCreditChoiceGroupGroup(el, cursor)); + out.addGroup(parseCreditChoiceGroupGroup(el, cursor, context)); } return out; } diff --git a/src/private/mx/core/generated/CreditChoiceGroup.h b/src/private/mx/core/generated/CreditChoiceGroup.h index d00d0dde1..d5e760075 100644 --- a/src/private/mx/core/generated/CreditChoiceGroup.h +++ b/src/private/mx/core/generated/CreditChoiceGroup.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A shared content group (synthesized from an anonymous /// particle of the schema): transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -40,6 +42,8 @@ class CreditChoiceGroup final /// is the enclosing element, for error paths. CreditChoiceGroup parseCreditChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor); +CreditChoiceGroup parseCreditChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeCreditChoiceGroup(const CreditChoiceGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/CreditChoiceGroupChoice.cpp b/src/private/mx/core/generated/CreditChoiceGroupChoice.cpp index 4416f08b6..bdd8060ff 100644 --- a/src/private/mx/core/generated/CreditChoiceGroupChoice.cpp +++ b/src/private/mx/core/generated/CreditChoiceGroupChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/CreditChoiceGroupChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -26,16 +27,22 @@ CreditChoiceGroupChoice CreditChoiceGroupChoice::creditSymbol(FormattedSymbolID } CreditChoiceGroupChoice parseCreditChoiceGroupChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseCreditChoiceGroupChoice(el, cursor, ParseContext{}); +} + +CreditChoiceGroupChoice parseCreditChoiceGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context) { if (cursor && (cursorIs(cursor, "credit-words"))) { - FormattedTextID value = parseFormattedTextID(cursor); + FormattedTextID value = parseFormattedTextID(cursor, context); cursor = nextElement(cursor); return CreditChoiceGroupChoice::creditWords(std::move(value)); } if (cursor && (cursorIs(cursor, "credit-symbol"))) { - FormattedSymbolID value = parseFormattedSymbolID(cursor); + FormattedSymbolID value = parseFormattedSymbolID(cursor, context); cursor = nextElement(cursor); return CreditChoiceGroupChoice::creditSymbol(std::move(value)); } diff --git a/src/private/mx/core/generated/CreditChoiceGroupChoice.h b/src/private/mx/core/generated/CreditChoiceGroupChoice.h index eb82acfc3..2286eb07b 100644 --- a/src/private/mx/core/generated/CreditChoiceGroupChoice.h +++ b/src/private/mx/core/generated/CreditChoiceGroupChoice.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -82,6 +84,9 @@ class CreditChoiceGroupChoice final /// the enclosing element, for error paths. CreditChoiceGroupChoice parseCreditChoiceGroupChoice(pugi::xml_node el, pugi::xml_node &cursor); +CreditChoiceGroupChoice parseCreditChoiceGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context); + void serializeCreditChoiceGroupChoice(const CreditChoiceGroupChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/CreditChoiceGroupGroup.cpp b/src/private/mx/core/generated/CreditChoiceGroupGroup.cpp index f829b8836..1739357b8 100644 --- a/src/private/mx/core/generated/CreditChoiceGroupGroup.cpp +++ b/src/private/mx/core/generated/CreditChoiceGroupGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/CreditChoiceGroupGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -51,21 +52,27 @@ void CreditChoiceGroupGroup::setChoice(CreditChoiceGroupGroupChoice value) } CreditChoiceGroupGroup parseCreditChoiceGroupGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseCreditChoiceGroupGroup(el, cursor, ParseContext{}); +} + +CreditChoiceGroupGroup parseCreditChoiceGroupGroup(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context) { CreditChoiceGroupGroup out; while (cursorIs(cursor, "link")) { - out.addLink(parseLink(cursor)); + out.addLink(parseLink(cursor, context)); cursor = nextElement(cursor); } while (cursorIs(cursor, "bookmark")) { - out.addBookmark(parseBookmark(cursor)); + out.addBookmark(parseBookmark(cursor, context)); cursor = nextElement(cursor); } if (cursor && (cursorIs(cursor, "credit-words") || cursorIs(cursor, "credit-symbol"))) { - out.setChoice(parseCreditChoiceGroupGroupChoice(el, cursor)); + out.setChoice(parseCreditChoiceGroupGroupChoice(el, cursor, context)); } else { diff --git a/src/private/mx/core/generated/CreditChoiceGroupGroup.h b/src/private/mx/core/generated/CreditChoiceGroupGroup.h index 5938aafae..86ef5b08b 100644 --- a/src/private/mx/core/generated/CreditChoiceGroupGroup.h +++ b/src/private/mx/core/generated/CreditChoiceGroupGroup.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A shared content group (synthesized from an anonymous /// particle of the schema): transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -45,6 +47,9 @@ class CreditChoiceGroupGroup final /// is the enclosing element, for error paths. CreditChoiceGroupGroup parseCreditChoiceGroupGroup(pugi::xml_node el, pugi::xml_node &cursor); +CreditChoiceGroupGroup parseCreditChoiceGroupGroup(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context); + void serializeCreditChoiceGroupGroup(const CreditChoiceGroupGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/CreditChoiceGroupGroupChoice.cpp b/src/private/mx/core/generated/CreditChoiceGroupGroupChoice.cpp index 69332ddb3..b305b6f84 100644 --- a/src/private/mx/core/generated/CreditChoiceGroupGroupChoice.cpp +++ b/src/private/mx/core/generated/CreditChoiceGroupGroupChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/CreditChoiceGroupGroupChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -26,16 +27,22 @@ CreditChoiceGroupGroupChoice CreditChoiceGroupGroupChoice::creditSymbol(Formatte } CreditChoiceGroupGroupChoice parseCreditChoiceGroupGroupChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseCreditChoiceGroupGroupChoice(el, cursor, ParseContext{}); +} + +CreditChoiceGroupGroupChoice parseCreditChoiceGroupGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context) { if (cursor && (cursorIs(cursor, "credit-words"))) { - FormattedTextID value = parseFormattedTextID(cursor); + FormattedTextID value = parseFormattedTextID(cursor, context); cursor = nextElement(cursor); return CreditChoiceGroupGroupChoice::creditWords(std::move(value)); } if (cursor && (cursorIs(cursor, "credit-symbol"))) { - FormattedSymbolID value = parseFormattedSymbolID(cursor); + FormattedSymbolID value = parseFormattedSymbolID(cursor, context); cursor = nextElement(cursor); return CreditChoiceGroupGroupChoice::creditSymbol(std::move(value)); } diff --git a/src/private/mx/core/generated/CreditChoiceGroupGroupChoice.h b/src/private/mx/core/generated/CreditChoiceGroupGroupChoice.h index 3b895919d..bd4a520c9 100644 --- a/src/private/mx/core/generated/CreditChoiceGroupGroupChoice.h +++ b/src/private/mx/core/generated/CreditChoiceGroupGroupChoice.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -82,6 +84,9 @@ class CreditChoiceGroupGroupChoice final /// the enclosing element, for error paths. CreditChoiceGroupGroupChoice parseCreditChoiceGroupGroupChoice(pugi::xml_node el, pugi::xml_node &cursor); +CreditChoiceGroupGroupChoice parseCreditChoiceGroupGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context); + void serializeCreditChoiceGroupGroupChoice(const CreditChoiceGroupGroupChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/CueNoteGroup.cpp b/src/private/mx/core/generated/CueNoteGroup.cpp index b7aad8f9e..fd197f65d 100644 --- a/src/private/mx/core/generated/CueNoteGroup.cpp +++ b/src/private/mx/core/generated/CueNoteGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/CueNoteGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,11 +42,16 @@ void CueNoteGroup::setDuration(PositiveDivisions value) } CueNoteGroup parseCueNoteGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseCueNoteGroup(el, cursor, ParseContext{}); +} + +CueNoteGroup parseCueNoteGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { CueNoteGroup out; if (cursorIs(cursor, "cue")) { - out.setCue(parseEmpty(cursor)); + out.setCue(parseEmpty(cursor, context)); cursor = nextElement(cursor); } else @@ -55,7 +61,7 @@ CueNoteGroup parseCueNoteGroup(pugi::xml_node el, pugi::xml_node &cursor) if (cursor && (cursorIs(cursor, "chord") || cursorIs(cursor, "pitch") || cursorIs(cursor, "unpitched") || cursorIs(cursor, "rest"))) { - out.setFullNote(parseFullNoteGroup(el, cursor)); + out.setFullNote(parseFullNoteGroup(el, cursor, context)); } else { @@ -63,7 +69,7 @@ CueNoteGroup parseCueNoteGroup(pugi::xml_node el, pugi::xml_node &cursor) } if (cursorIs(cursor, "duration")) { - out.setDuration(PositiveDivisions::parse(childText(cursor))); + out.setDuration(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else diff --git a/src/private/mx/core/generated/CueNoteGroup.h b/src/private/mx/core/generated/CueNoteGroup.h index 4ddbb3c81..6b2cec8f1 100644 --- a/src/private/mx/core/generated/CueNoteGroup.h +++ b/src/private/mx/core/generated/CueNoteGroup.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A shared content group (synthesized from an anonymous /// particle of the schema): transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -43,6 +45,8 @@ class CueNoteGroup final /// is the enclosing element, for error paths. CueNoteGroup parseCueNoteGroup(pugi::xml_node el, pugi::xml_node &cursor); +CueNoteGroup parseCueNoteGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeCueNoteGroup(const CueNoteGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/Dashes.cpp b/src/private/mx/core/generated/Dashes.cpp index b43dac5d7..dcff47d2f 100644 --- a/src/private/mx/core/generated/Dashes.cpp +++ b/src/private/mx/core/generated/Dashes.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Dashes.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -111,6 +112,11 @@ void Dashes::setID(std::optional value) } Dashes parseDashes(pugi::xml_node el) +{ + return parseDashes(el, ParseContext{}); +} + +Dashes parseDashes(pugi::xml_node el, const ParseContext &context) { Dashes out; bool seen_type = false; @@ -124,39 +130,39 @@ Dashes parseDashes(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(StartStopContinue::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "number") { - out.setNumber(NumberLevel::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else if (aname == "dash-length") { - out.setDashLength(Tenths::parse(a.value())); + out.setDashLength(parseValue(a.value(), context, el, "dash-length")); } else if (aname == "space-length") { - out.setSpaceLength(Tenths::parse(a.value())); + out.setSpaceLength(parseValue(a.value(), context, el, "space-length")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "id") { @@ -171,13 +177,19 @@ Dashes parseDashes(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseDashesContent(out, el); + parseDashesContent(out, el, context); return out; } void parseDashesContent(Dashes &out, pugi::xml_node el) +{ + parseDashesContent(out, el, ParseContext{}); +} + +void parseDashesContent(Dashes &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Dashes.h b/src/private/mx/core/generated/Dashes.h index 48f471374..436ec70c0 100644 --- a/src/private/mx/core/generated/Dashes.h +++ b/src/private/mx/core/generated/Dashes.h @@ -20,6 +20,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The dashes type represents dashes, used for instance with cresc. and dim. marks. class Dashes final { @@ -61,8 +63,12 @@ class Dashes final Dashes parseDashes(pugi::xml_node el); +Dashes parseDashes(pugi::xml_node el, const ParseContext &context); + void parseDashesContent(Dashes &out, pugi::xml_node el); +void parseDashesContent(Dashes &out, pugi::xml_node el, const ParseContext &context); + void serializeDashes(const Dashes &v, pugi::xml_node parent, const char *tag); void serializeDashesContent(const Dashes &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Defaults.cpp b/src/private/mx/core/generated/Defaults.cpp index 45de3e5af..6d22a1246 100644 --- a/src/private/mx/core/generated/Defaults.cpp +++ b/src/private/mx/core/generated/Defaults.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Defaults.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -101,6 +102,11 @@ void Defaults::setLyricLanguage(std::vector value) } Defaults parseDefaults(pugi::xml_node el) +{ + return parseDefaults(el, ParseContext{}); +} + +Defaults parseDefaults(pugi::xml_node el, const ParseContext &context) { Defaults out; for (pugi::xml_attribute a : el.attributes()) @@ -112,52 +118,57 @@ Defaults parseDefaults(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseDefaultsContent(out, el); + parseDefaultsContent(out, el, context); return out; } void parseDefaultsContent(Defaults &out, pugi::xml_node el) +{ + parseDefaultsContent(out, el, ParseContext{}); +} + +void parseDefaultsContent(Defaults &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "scaling")) { - out.setScaling(parseScaling(cursor)); + out.setScaling(parseScaling(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "concert-score")) { - parseEmpty(cursor); + parseEmpty(cursor, context); out.setConcertScore(true); cursor = nextElement(cursor); } if (cursor && (cursorIs(cursor, "page-layout") || cursorIs(cursor, "system-layout") || cursorIs(cursor, "staff-layout"))) { - out.setLayout(parseLayoutGroup(el, cursor)); + out.setLayout(parseLayoutGroup(el, cursor, context)); } if (cursorIs(cursor, "appearance")) { - out.setAppearance(parseAppearance(cursor)); + out.setAppearance(parseAppearance(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "music-font")) { - out.setMusicFont(parseEmptyFont(cursor)); + out.setMusicFont(parseEmptyFont(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "word-font")) { - out.setWordFont(parseEmptyFont(cursor)); + out.setWordFont(parseEmptyFont(cursor, context)); cursor = nextElement(cursor); } while (cursorIs(cursor, "lyric-font")) { - out.addLyricFont(parseLyricFont(cursor)); + out.addLyricFont(parseLyricFont(cursor, context)); cursor = nextElement(cursor); } while (cursorIs(cursor, "lyric-language")) { - out.addLyricLanguage(parseLyricLanguage(cursor)); + out.addLyricLanguage(parseLyricLanguage(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/Defaults.h b/src/private/mx/core/generated/Defaults.h index cbd9a034e..c12a51007 100644 --- a/src/private/mx/core/generated/Defaults.h +++ b/src/private/mx/core/generated/Defaults.h @@ -23,6 +23,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The defaults type specifies score-wide defaults for scaling; whether or not the file is a concert /// score; layout; and default values for the music font, word font, lyric font, and lyric language. /// Except for the concert-score element, if any defaults are missing, the choice of what to use is @@ -65,8 +67,12 @@ class Defaults final Defaults parseDefaults(pugi::xml_node el); +Defaults parseDefaults(pugi::xml_node el, const ParseContext &context); + void parseDefaultsContent(Defaults &out, pugi::xml_node el); +void parseDefaultsContent(Defaults &out, pugi::xml_node el, const ParseContext &context); + void serializeDefaults(const Defaults &v, pugi::xml_node parent, const char *tag); void serializeDefaultsContent(const Defaults &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Degree.cpp b/src/private/mx/core/generated/Degree.cpp index 9fbad5ae6..cd31a10a7 100644 --- a/src/private/mx/core/generated/Degree.cpp +++ b/src/private/mx/core/generated/Degree.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Degree.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -51,6 +52,11 @@ void Degree::setDegreeType(DegreeType value) } Degree parseDegree(pugi::xml_node el) +{ + return parseDegree(el, ParseContext{}); +} + +Degree parseDegree(pugi::xml_node el, const ParseContext &context) { Degree out; for (pugi::xml_attribute a : el.attributes()) @@ -62,23 +68,28 @@ Degree parseDegree(pugi::xml_node el) } if (aname == "print-object") { - out.setPrintObject(YesNo::parse(a.value())); + out.setPrintObject(parseValue(a.value(), context, el, "print-object")); } else { throwUnknownAttribute(el, a.name()); } } - parseDegreeContent(out, el); + parseDegreeContent(out, el, context); return out; } void parseDegreeContent(Degree &out, pugi::xml_node el) +{ + parseDegreeContent(out, el, ParseContext{}); +} + +void parseDegreeContent(Degree &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "degree-value")) { - out.setDegreeValue(parseDegreeValue(cursor)); + out.setDegreeValue(parseDegreeValue(cursor, context)); cursor = nextElement(cursor); } else @@ -87,7 +98,7 @@ void parseDegreeContent(Degree &out, pugi::xml_node el) } if (cursorIs(cursor, "degree-alter")) { - out.setDegreeAlter(parseDegreeAlter(cursor)); + out.setDegreeAlter(parseDegreeAlter(cursor, context)); cursor = nextElement(cursor); } else @@ -96,7 +107,7 @@ void parseDegreeContent(Degree &out, pugi::xml_node el) } if (cursorIs(cursor, "degree-type")) { - out.setDegreeType(parseDegreeType(cursor)); + out.setDegreeType(parseDegreeType(cursor, context)); cursor = nextElement(cursor); } else diff --git a/src/private/mx/core/generated/Degree.h b/src/private/mx/core/generated/Degree.h index ddc095c03..bffb8a108 100644 --- a/src/private/mx/core/generated/Degree.h +++ b/src/private/mx/core/generated/Degree.h @@ -20,6 +20,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The degree type is used to add, alter, or subtract individual notes in the chord. The /// print-object attribute can be used to keep the degree from printing separately when it has /// already taken into account in the text attribute of the kind element. The degree-value and @@ -50,8 +52,12 @@ class Degree final Degree parseDegree(pugi::xml_node el); +Degree parseDegree(pugi::xml_node el, const ParseContext &context); + void parseDegreeContent(Degree &out, pugi::xml_node el); +void parseDegreeContent(Degree &out, pugi::xml_node el, const ParseContext &context); + void serializeDegree(const Degree &v, pugi::xml_node parent, const char *tag); void serializeDegreeContent(const Degree &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/DegreeAlter.cpp b/src/private/mx/core/generated/DegreeAlter.cpp index e5d5472d2..05e89fa4e 100644 --- a/src/private/mx/core/generated/DegreeAlter.cpp +++ b/src/private/mx/core/generated/DegreeAlter.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/DegreeAlter.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -121,6 +122,11 @@ void DegreeAlter::setValue(Semitones value) } DegreeAlter parseDegreeAlter(pugi::xml_node el) +{ + return parseDegreeAlter(el, ParseContext{}); +} + +DegreeAlter parseDegreeAlter(pugi::xml_node el, const ParseContext &context) { DegreeAlter out; for (pugi::xml_attribute a : el.attributes()) @@ -132,56 +138,61 @@ DegreeAlter parseDegreeAlter(pugi::xml_node el) } if (aname == "plus-minus") { - out.setPlusMinus(YesNo::parse(a.value())); + out.setPlusMinus(parseValue(a.value(), context, el, "plus-minus")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else { throwUnknownAttribute(el, a.name()); } } - parseDegreeAlterContent(out, el); + parseDegreeAlterContent(out, el, context); return out; } void parseDegreeAlterContent(DegreeAlter &out, pugi::xml_node el) { - out.setValue(Semitones::parse(childText(el))); + parseDegreeAlterContent(out, el, ParseContext{}); +} + +void parseDegreeAlterContent(DegreeAlter &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/DegreeAlter.h b/src/private/mx/core/generated/DegreeAlter.h index 6e248fc3d..032aef0c9 100644 --- a/src/private/mx/core/generated/DegreeAlter.h +++ b/src/private/mx/core/generated/DegreeAlter.h @@ -22,6 +22,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The degree-alter type represents the chromatic alteration for the current degree. If the /// degree-type value is alter or subtract, the degree-alter value is relative to the degree already /// in the chord based on its kind element. If the degree-type value is add, the degree-alter is @@ -71,8 +73,12 @@ class DegreeAlter final DegreeAlter parseDegreeAlter(pugi::xml_node el); +DegreeAlter parseDegreeAlter(pugi::xml_node el, const ParseContext &context); + void parseDegreeAlterContent(DegreeAlter &out, pugi::xml_node el); +void parseDegreeAlterContent(DegreeAlter &out, pugi::xml_node el, const ParseContext &context); + void serializeDegreeAlter(const DegreeAlter &v, pugi::xml_node parent, const char *tag); void serializeDegreeAlterContent(const DegreeAlter &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/DegreeSymbolValue.cpp b/src/private/mx/core/generated/DegreeSymbolValue.cpp index 0b9dde810..c61cf1b77 100644 --- a/src/private/mx/core/generated/DegreeSymbolValue.cpp +++ b/src/private/mx/core/generated/DegreeSymbolValue.cpp @@ -56,9 +56,15 @@ bool DegreeSymbolValue::tryParse(std::string_view text, DegreeSymbolValue &out) } DegreeSymbolValue DegreeSymbolValue::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +DegreeSymbolValue DegreeSymbolValue::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { DegreeSymbolValue v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/DegreeSymbolValue.h b/src/private/mx/core/generated/DegreeSymbolValue.h index 9a59fd104..3210eafd7 100644 --- a/src/private/mx/core/generated/DegreeSymbolValue.h +++ b/src/private/mx/core/generated/DegreeSymbolValue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -46,6 +48,9 @@ class DegreeSymbolValue final /// (the import leniency policy; never produces an invalid value). static DegreeSymbolValue parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static DegreeSymbolValue parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const DegreeSymbolValue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/DegreeType.cpp b/src/private/mx/core/generated/DegreeType.cpp index 4dbff0e34..fa0ab7731 100644 --- a/src/private/mx/core/generated/DegreeType.cpp +++ b/src/private/mx/core/generated/DegreeType.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/DegreeType.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -121,6 +122,11 @@ void DegreeType::setValue(DegreeTypeValue value) } DegreeType parseDegreeType(pugi::xml_node el) +{ + return parseDegreeType(el, ParseContext{}); +} + +DegreeType parseDegreeType(pugi::xml_node el, const ParseContext &context) { DegreeType out; for (pugi::xml_attribute a : el.attributes()) @@ -136,52 +142,57 @@ DegreeType parseDegreeType(pugi::xml_node el) } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else { throwUnknownAttribute(el, a.name()); } } - parseDegreeTypeContent(out, el); + parseDegreeTypeContent(out, el, context); return out; } void parseDegreeTypeContent(DegreeType &out, pugi::xml_node el) { - out.setValue(DegreeTypeValue::parse(childText(el))); + parseDegreeTypeContent(out, el, ParseContext{}); +} + +void parseDegreeTypeContent(DegreeType &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/DegreeType.h b/src/private/mx/core/generated/DegreeType.h index c722c7b5e..2f540cf12 100644 --- a/src/private/mx/core/generated/DegreeType.h +++ b/src/private/mx/core/generated/DegreeType.h @@ -21,6 +21,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The degree-type type indicates if this degree is an addition, alteration, or subtraction relative /// to the kind of the current chord. The value of the degree-type element affects the interpretation /// of the value of the degree-alter element. The text attribute specifies how the type of the degree @@ -68,8 +70,12 @@ class DegreeType final DegreeType parseDegreeType(pugi::xml_node el); +DegreeType parseDegreeType(pugi::xml_node el, const ParseContext &context); + void parseDegreeTypeContent(DegreeType &out, pugi::xml_node el); +void parseDegreeTypeContent(DegreeType &out, pugi::xml_node el, const ParseContext &context); + void serializeDegreeType(const DegreeType &v, pugi::xml_node parent, const char *tag); void serializeDegreeTypeContent(const DegreeType &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/DegreeTypeValue.cpp b/src/private/mx/core/generated/DegreeTypeValue.cpp index 27f86f312..8966dd0bb 100644 --- a/src/private/mx/core/generated/DegreeTypeValue.cpp +++ b/src/private/mx/core/generated/DegreeTypeValue.cpp @@ -48,9 +48,15 @@ bool DegreeTypeValue::tryParse(std::string_view text, DegreeTypeValue &out) noex } DegreeTypeValue DegreeTypeValue::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +DegreeTypeValue DegreeTypeValue::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { DegreeTypeValue v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/DegreeTypeValue.h b/src/private/mx/core/generated/DegreeTypeValue.h index 1fe966d06..a1e3c651a 100644 --- a/src/private/mx/core/generated/DegreeTypeValue.h +++ b/src/private/mx/core/generated/DegreeTypeValue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -43,6 +45,9 @@ class DegreeTypeValue final /// (the import leniency policy; never produces an invalid value). static DegreeTypeValue parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static DegreeTypeValue parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const DegreeTypeValue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/DegreeValue.cpp b/src/private/mx/core/generated/DegreeValue.cpp index c99f2b6ed..72ca5bd37 100644 --- a/src/private/mx/core/generated/DegreeValue.cpp +++ b/src/private/mx/core/generated/DegreeValue.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/DegreeValue.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -131,6 +132,11 @@ void DegreeValue::setValue(int value) } DegreeValue parseDegreeValue(pugi::xml_node el) +{ + return parseDegreeValue(el, ParseContext{}); +} + +DegreeValue parseDegreeValue(pugi::xml_node el, const ParseContext &context) { DegreeValue out; for (pugi::xml_attribute a : el.attributes()) @@ -142,7 +148,7 @@ DegreeValue parseDegreeValue(pugi::xml_node el) } if (aname == "symbol") { - out.setSymbol(DegreeSymbolValue::parse(a.value())); + out.setSymbol(parseValue(a.value(), context, el, "symbol")); } else if (aname == "text") { @@ -150,52 +156,57 @@ DegreeValue parseDegreeValue(pugi::xml_node el) } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else { throwUnknownAttribute(el, a.name()); } } - parseDegreeValueContent(out, el); + parseDegreeValueContent(out, el, context); return out; } void parseDegreeValueContent(DegreeValue &out, pugi::xml_node el) { - out.setValue(parseInt(childText(el))); + parseDegreeValueContent(out, el, ParseContext{}); +} + +void parseDegreeValueContent(DegreeValue &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseIntegerValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/DegreeValue.h b/src/private/mx/core/generated/DegreeValue.h index a19adf854..04cd6b4a6 100644 --- a/src/private/mx/core/generated/DegreeValue.h +++ b/src/private/mx/core/generated/DegreeValue.h @@ -21,6 +21,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The content of the degree-value type is a number indicating the degree of the chord (1 for the /// root, 3 for third, etc). The text attribute specifies how the value of the degree should be /// displayed. The symbol attribute indicates that a symbol should be used in specifying the degree. @@ -71,8 +73,12 @@ class DegreeValue final DegreeValue parseDegreeValue(pugi::xml_node el); +DegreeValue parseDegreeValue(pugi::xml_node el, const ParseContext &context); + void parseDegreeValueContent(DegreeValue &out, pugi::xml_node el); +void parseDegreeValueContent(DegreeValue &out, pugi::xml_node el, const ParseContext &context); + void serializeDegreeValue(const DegreeValue &v, pugi::xml_node parent, const char *tag); void serializeDegreeValueContent(const DegreeValue &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Direction.cpp b/src/private/mx/core/generated/Direction.cpp index ef76c2a89..1e5972312 100644 --- a/src/private/mx/core/generated/Direction.cpp +++ b/src/private/mx/core/generated/Direction.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Direction.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -116,6 +117,11 @@ void Direction::setListening(std::optional value) } Direction parseDirection(pugi::xml_node el) +{ + return parseDirection(el, ParseContext{}); +} + +Direction parseDirection(pugi::xml_node el, const ParseContext &context) { Direction out; for (pugi::xml_attribute a : el.attributes()) @@ -127,15 +133,15 @@ Direction parseDirection(pugi::xml_node el) } if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else if (aname == "directive") { - out.setDirective(YesNo::parse(a.value())); + out.setDirective(parseValue(a.value(), context, el, "directive")); } else if (aname == "system") { - out.setSystem(SystemRelation::parse(a.value())); + out.setSystem(parseValue(a.value(), context, el, "system")); } else if (aname == "id") { @@ -146,46 +152,51 @@ Direction parseDirection(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseDirectionContent(out, el); + parseDirectionContent(out, el, context); return out; } void parseDirectionContent(Direction &out, pugi::xml_node el) +{ + parseDirectionContent(out, el, ParseContext{}); +} + +void parseDirectionContent(Direction &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (!cursorIs(cursor, "direction-type")) { throwMissingOrMisplaced(el, cursor, "direction-type"); } - out.setDirectionType(OneOrMore{parseDirectionType(cursor)}); + out.setDirectionType(OneOrMore{parseDirectionType(cursor, context)}); cursor = nextElement(cursor); while (cursorIs(cursor, "direction-type")) { - out.addDirectionType(parseDirectionType(cursor)); + out.addDirectionType(parseDirectionType(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "offset")) { - out.setOffset(parseOffset(cursor)); + out.setOffset(parseOffset(cursor, context)); cursor = nextElement(cursor); } if (cursor && (cursorIs(cursor, "footnote") || cursorIs(cursor, "level") || cursorIs(cursor, "voice"))) { - out.setEditorialVoiceDirection(parseEditorialVoiceDirectionGroup(el, cursor)); + out.setEditorialVoiceDirection(parseEditorialVoiceDirectionGroup(el, cursor, context)); } if (cursorIs(cursor, "staff")) { - out.setStaff(parseInt(childText(cursor))); + out.setStaff(parseIntegerValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (cursorIs(cursor, "sound")) { - out.setSound(parseSound(cursor)); + out.setSound(parseSound(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "listening")) { - out.setListening(parseListening(cursor)); + out.setListening(parseListening(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/Direction.h b/src/private/mx/core/generated/Direction.h index 6bcd3f65f..b82f96b3f 100644 --- a/src/private/mx/core/generated/Direction.h +++ b/src/private/mx/core/generated/Direction.h @@ -27,6 +27,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A direction is a musical indication that is not necessarily attached to a specific note. Two or /// more may be combined to indicate words followed by the start of a dashed line, the end of a wedge /// followed by dynamics, etc. For applications where a specific direction is indeed attached to a @@ -78,8 +80,12 @@ class Direction final Direction parseDirection(pugi::xml_node el); +Direction parseDirection(pugi::xml_node el, const ParseContext &context); + void parseDirectionContent(Direction &out, pugi::xml_node el); +void parseDirectionContent(Direction &out, pugi::xml_node el, const ParseContext &context); + void serializeDirection(const Direction &v, pugi::xml_node parent, const char *tag); void serializeDirectionContent(const Direction &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/DirectionType.cpp b/src/private/mx/core/generated/DirectionType.cpp index 135bed160..6a820e6e2 100644 --- a/src/private/mx/core/generated/DirectionType.cpp +++ b/src/private/mx/core/generated/DirectionType.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/DirectionType.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void DirectionType::setChoice(DirectionTypeChoice value) } DirectionType parseDirectionType(pugi::xml_node el) +{ + return parseDirectionType(el, ParseContext{}); +} + +DirectionType parseDirectionType(pugi::xml_node el, const ParseContext &context) { DirectionType out; for (pugi::xml_attribute a : el.attributes()) @@ -49,11 +55,16 @@ DirectionType parseDirectionType(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseDirectionTypeContent(out, el); + parseDirectionTypeContent(out, el, context); return out; } void parseDirectionTypeContent(DirectionType &out, pugi::xml_node el) +{ + parseDirectionTypeContent(out, el, ParseContext{}); +} + +void parseDirectionTypeContent(DirectionType &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "rehearsal") || cursorIs(cursor, "segno") || cursorIs(cursor, "coda") || @@ -66,7 +77,7 @@ void parseDirectionTypeContent(DirectionType &out, pugi::xml_node el) cursorIs(cursor, "percussion") || cursorIs(cursor, "accordion-registration") || cursorIs(cursor, "staff-divide") || cursorIs(cursor, "other-direction"))) { - out.setChoice(parseDirectionTypeChoice(el, cursor)); + out.setChoice(parseDirectionTypeChoice(el, cursor, context)); } else { diff --git a/src/private/mx/core/generated/DirectionType.h b/src/private/mx/core/generated/DirectionType.h index 14d6d9c90..6e0cdcc47 100644 --- a/src/private/mx/core/generated/DirectionType.h +++ b/src/private/mx/core/generated/DirectionType.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Textual direction types may have more than 1 component due to multiple fonts. The dynamics /// element may also be used in the notations element. Attribute groups related to print suggestions /// apply to the individual direction-type, not to the overall direction. @@ -40,8 +42,12 @@ class DirectionType final DirectionType parseDirectionType(pugi::xml_node el); +DirectionType parseDirectionType(pugi::xml_node el, const ParseContext &context); + void parseDirectionTypeContent(DirectionType &out, pugi::xml_node el); +void parseDirectionTypeContent(DirectionType &out, pugi::xml_node el, const ParseContext &context); + void serializeDirectionType(const DirectionType &v, pugi::xml_node parent, const char *tag); void serializeDirectionTypeContent(const DirectionType &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/DirectionTypeChoice.cpp b/src/private/mx/core/generated/DirectionTypeChoice.cpp index ff9b8c4ac..271d3895b 100644 --- a/src/private/mx/core/generated/DirectionTypeChoice.cpp +++ b/src/private/mx/core/generated/DirectionTypeChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/DirectionTypeChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -131,170 +132,175 @@ DirectionTypeChoice DirectionTypeChoice::otherDirection(OtherDirection value) } DirectionTypeChoice parseDirectionTypeChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseDirectionTypeChoice(el, cursor, ParseContext{}); +} + +DirectionTypeChoice parseDirectionTypeChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "rehearsal"))) { - OneOrMore items{parseFormattedTextID(cursor)}; + OneOrMore items{parseFormattedTextID(cursor, context)}; cursor = nextElement(cursor); while (cursor && (cursorIs(cursor, "rehearsal"))) { - items.add(parseFormattedTextID(cursor)); + items.add(parseFormattedTextID(cursor, context)); cursor = nextElement(cursor); } return DirectionTypeChoice::rehearsal(std::move(items)); } if (cursor && (cursorIs(cursor, "segno"))) { - OneOrMore items{parseSegno(cursor)}; + OneOrMore items{parseSegno(cursor, context)}; cursor = nextElement(cursor); while (cursor && (cursorIs(cursor, "segno"))) { - items.add(parseSegno(cursor)); + items.add(parseSegno(cursor, context)); cursor = nextElement(cursor); } return DirectionTypeChoice::segno(std::move(items)); } if (cursor && (cursorIs(cursor, "coda"))) { - OneOrMore items{parseCoda(cursor)}; + OneOrMore items{parseCoda(cursor, context)}; cursor = nextElement(cursor); while (cursor && (cursorIs(cursor, "coda"))) { - items.add(parseCoda(cursor)); + items.add(parseCoda(cursor, context)); cursor = nextElement(cursor); } return DirectionTypeChoice::coda(std::move(items)); } if (cursor && (cursorIs(cursor, "words") || cursorIs(cursor, "symbol"))) { - OneOrMore items{parseDirectionTypeChoiceChoice(el, cursor)}; + OneOrMore items{parseDirectionTypeChoiceChoice(el, cursor, context)}; while (cursor && (cursorIs(cursor, "words") || cursorIs(cursor, "symbol"))) { - items.add(parseDirectionTypeChoiceChoice(el, cursor)); + items.add(parseDirectionTypeChoiceChoice(el, cursor, context)); } return DirectionTypeChoice::choice(std::move(items)); } if (cursor && (cursorIs(cursor, "wedge"))) { - Wedge value = parseWedge(cursor); + Wedge value = parseWedge(cursor, context); cursor = nextElement(cursor); return DirectionTypeChoice::wedge(std::move(value)); } if (cursor && (cursorIs(cursor, "dynamics"))) { - OneOrMore items{parseDynamics(cursor)}; + OneOrMore items{parseDynamics(cursor, context)}; cursor = nextElement(cursor); while (cursor && (cursorIs(cursor, "dynamics"))) { - items.add(parseDynamics(cursor)); + items.add(parseDynamics(cursor, context)); cursor = nextElement(cursor); } return DirectionTypeChoice::dynamics(std::move(items)); } if (cursor && (cursorIs(cursor, "dashes"))) { - Dashes value = parseDashes(cursor); + Dashes value = parseDashes(cursor, context); cursor = nextElement(cursor); return DirectionTypeChoice::dashes(std::move(value)); } if (cursor && (cursorIs(cursor, "bracket"))) { - Bracket value = parseBracket(cursor); + Bracket value = parseBracket(cursor, context); cursor = nextElement(cursor); return DirectionTypeChoice::bracket(std::move(value)); } if (cursor && (cursorIs(cursor, "pedal"))) { - Pedal value = parsePedal(cursor); + Pedal value = parsePedal(cursor, context); cursor = nextElement(cursor); return DirectionTypeChoice::pedal(std::move(value)); } if (cursor && (cursorIs(cursor, "metronome"))) { - Metronome value = parseMetronome(cursor); + Metronome value = parseMetronome(cursor, context); cursor = nextElement(cursor); return DirectionTypeChoice::metronome(std::move(value)); } if (cursor && (cursorIs(cursor, "octave-shift"))) { - OctaveShift value = parseOctaveShift(cursor); + OctaveShift value = parseOctaveShift(cursor, context); cursor = nextElement(cursor); return DirectionTypeChoice::octaveShift(std::move(value)); } if (cursor && (cursorIs(cursor, "harp-pedals"))) { - HarpPedals value = parseHarpPedals(cursor); + HarpPedals value = parseHarpPedals(cursor, context); cursor = nextElement(cursor); return DirectionTypeChoice::harpPedals(std::move(value)); } if (cursor && (cursorIs(cursor, "damp"))) { - EmptyPrintStyleAlignID value = parseEmptyPrintStyleAlignID(cursor); + EmptyPrintStyleAlignID value = parseEmptyPrintStyleAlignID(cursor, context); cursor = nextElement(cursor); return DirectionTypeChoice::damp(std::move(value)); } if (cursor && (cursorIs(cursor, "damp-all"))) { - EmptyPrintStyleAlignID value = parseEmptyPrintStyleAlignID(cursor); + EmptyPrintStyleAlignID value = parseEmptyPrintStyleAlignID(cursor, context); cursor = nextElement(cursor); return DirectionTypeChoice::dampAll(std::move(value)); } if (cursor && (cursorIs(cursor, "eyeglasses"))) { - EmptyPrintStyleAlignID value = parseEmptyPrintStyleAlignID(cursor); + EmptyPrintStyleAlignID value = parseEmptyPrintStyleAlignID(cursor, context); cursor = nextElement(cursor); return DirectionTypeChoice::eyeglasses(std::move(value)); } if (cursor && (cursorIs(cursor, "string-mute"))) { - StringMute value = parseStringMute(cursor); + StringMute value = parseStringMute(cursor, context); cursor = nextElement(cursor); return DirectionTypeChoice::stringMute(std::move(value)); } if (cursor && (cursorIs(cursor, "scordatura"))) { - Scordatura value = parseScordatura(cursor); + Scordatura value = parseScordatura(cursor, context); cursor = nextElement(cursor); return DirectionTypeChoice::scordatura(std::move(value)); } if (cursor && (cursorIs(cursor, "image"))) { - Image value = parseImage(cursor); + Image value = parseImage(cursor, context); cursor = nextElement(cursor); return DirectionTypeChoice::image(std::move(value)); } if (cursor && (cursorIs(cursor, "principal-voice"))) { - PrincipalVoice value = parsePrincipalVoice(cursor); + PrincipalVoice value = parsePrincipalVoice(cursor, context); cursor = nextElement(cursor); return DirectionTypeChoice::principalVoice(std::move(value)); } if (cursor && (cursorIs(cursor, "percussion"))) { - OneOrMore items{parsePercussion(cursor)}; + OneOrMore items{parsePercussion(cursor, context)}; cursor = nextElement(cursor); while (cursor && (cursorIs(cursor, "percussion"))) { - items.add(parsePercussion(cursor)); + items.add(parsePercussion(cursor, context)); cursor = nextElement(cursor); } return DirectionTypeChoice::percussion(std::move(items)); } if (cursor && (cursorIs(cursor, "accordion-registration"))) { - AccordionRegistration value = parseAccordionRegistration(cursor); + AccordionRegistration value = parseAccordionRegistration(cursor, context); cursor = nextElement(cursor); return DirectionTypeChoice::accordionRegistration(std::move(value)); } if (cursor && (cursorIs(cursor, "staff-divide"))) { - StaffDivide value = parseStaffDivide(cursor); + StaffDivide value = parseStaffDivide(cursor, context); cursor = nextElement(cursor); return DirectionTypeChoice::staffDivide(std::move(value)); } if (cursor && (cursorIs(cursor, "other-direction"))) { - OtherDirection value = parseOtherDirection(cursor); + OtherDirection value = parseOtherDirection(cursor, context); cursor = nextElement(cursor); return DirectionTypeChoice::otherDirection(std::move(value)); } diff --git a/src/private/mx/core/generated/DirectionTypeChoice.h b/src/private/mx/core/generated/DirectionTypeChoice.h index 2042d0908..f78bf1a3d 100644 --- a/src/private/mx/core/generated/DirectionTypeChoice.h +++ b/src/private/mx/core/generated/DirectionTypeChoice.h @@ -38,6 +38,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -401,6 +403,8 @@ class DirectionTypeChoice final /// the enclosing element, for error paths. DirectionTypeChoice parseDirectionTypeChoice(pugi::xml_node el, pugi::xml_node &cursor); +DirectionTypeChoice parseDirectionTypeChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeDirectionTypeChoice(const DirectionTypeChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/DirectionTypeChoiceChoice.cpp b/src/private/mx/core/generated/DirectionTypeChoiceChoice.cpp index d6db71b7e..d533df35e 100644 --- a/src/private/mx/core/generated/DirectionTypeChoiceChoice.cpp +++ b/src/private/mx/core/generated/DirectionTypeChoiceChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/DirectionTypeChoiceChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -26,16 +27,22 @@ DirectionTypeChoiceChoice DirectionTypeChoiceChoice::symbol(FormattedSymbolID va } DirectionTypeChoiceChoice parseDirectionTypeChoiceChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseDirectionTypeChoiceChoice(el, cursor, ParseContext{}); +} + +DirectionTypeChoiceChoice parseDirectionTypeChoiceChoice(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context) { if (cursor && (cursorIs(cursor, "words"))) { - FormattedTextID value = parseFormattedTextID(cursor); + FormattedTextID value = parseFormattedTextID(cursor, context); cursor = nextElement(cursor); return DirectionTypeChoiceChoice::words(std::move(value)); } if (cursor && (cursorIs(cursor, "symbol"))) { - FormattedSymbolID value = parseFormattedSymbolID(cursor); + FormattedSymbolID value = parseFormattedSymbolID(cursor, context); cursor = nextElement(cursor); return DirectionTypeChoiceChoice::symbol(std::move(value)); } diff --git a/src/private/mx/core/generated/DirectionTypeChoiceChoice.h b/src/private/mx/core/generated/DirectionTypeChoiceChoice.h index ab3d1c02f..2d04f69e2 100644 --- a/src/private/mx/core/generated/DirectionTypeChoiceChoice.h +++ b/src/private/mx/core/generated/DirectionTypeChoiceChoice.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -82,6 +84,9 @@ class DirectionTypeChoiceChoice final /// the enclosing element, for error paths. DirectionTypeChoiceChoice parseDirectionTypeChoiceChoice(pugi::xml_node el, pugi::xml_node &cursor); +DirectionTypeChoiceChoice parseDirectionTypeChoiceChoice(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context); + void serializeDirectionTypeChoiceChoice(const DirectionTypeChoiceChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/Directive.cpp b/src/private/mx/core/generated/Directive.cpp index d13894542..0e8ec17b5 100644 --- a/src/private/mx/core/generated/Directive.cpp +++ b/src/private/mx/core/generated/Directive.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Directive.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -121,6 +122,11 @@ void Directive::setValue(std::string value) } Directive parseDirective(pugi::xml_node el) +{ + return parseDirective(el, ParseContext{}); +} + +Directive parseDirective(pugi::xml_node el, const ParseContext &context) { Directive out; for (pugi::xml_attribute a : el.attributes()) @@ -136,50 +142,55 @@ Directive parseDirective(pugi::xml_node el) } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else { throwUnknownAttribute(el, a.name()); } } - parseDirectiveContent(out, el); + parseDirectiveContent(out, el, context); return out; } void parseDirectiveContent(Directive &out, pugi::xml_node el) +{ + parseDirectiveContent(out, el, ParseContext{}); +} + +void parseDirectiveContent(Directive &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/Directive.h b/src/private/mx/core/generated/Directive.h index 6249adeb4..c7829a9dd 100644 --- a/src/private/mx/core/generated/Directive.h +++ b/src/private/mx/core/generated/Directive.h @@ -20,6 +20,8 @@ class xml_node; namespace mx::core { +class ParseContext; + class Directive final { public: @@ -63,8 +65,12 @@ class Directive final Directive parseDirective(pugi::xml_node el); +Directive parseDirective(pugi::xml_node el, const ParseContext &context); + void parseDirectiveContent(Directive &out, pugi::xml_node el); +void parseDirectiveContent(Directive &out, pugi::xml_node el, const ParseContext &context); + void serializeDirective(const Directive &v, pugi::xml_node parent, const char *tag); void serializeDirectiveContent(const Directive &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/DisplayStepOctaveGroup.cpp b/src/private/mx/core/generated/DisplayStepOctaveGroup.cpp index 981245331..d78ff85c8 100644 --- a/src/private/mx/core/generated/DisplayStepOctaveGroup.cpp +++ b/src/private/mx/core/generated/DisplayStepOctaveGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/DisplayStepOctaveGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,11 +32,17 @@ void DisplayStepOctaveGroup::setDisplayOctave(Octave value) } DisplayStepOctaveGroup parseDisplayStepOctaveGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseDisplayStepOctaveGroup(el, cursor, ParseContext{}); +} + +DisplayStepOctaveGroup parseDisplayStepOctaveGroup(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context) { DisplayStepOctaveGroup out; if (cursorIs(cursor, "display-step")) { - out.setDisplayStep(Step::parse(childText(cursor))); + out.setDisplayStep(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -44,7 +51,7 @@ DisplayStepOctaveGroup parseDisplayStepOctaveGroup(pugi::xml_node el, pugi::xml_ } if (cursorIs(cursor, "display-octave")) { - out.setDisplayOctave(Octave::parse(childText(cursor))); + out.setDisplayOctave(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else diff --git a/src/private/mx/core/generated/DisplayStepOctaveGroup.h b/src/private/mx/core/generated/DisplayStepOctaveGroup.h index 18a879bef..91f3929dc 100644 --- a/src/private/mx/core/generated/DisplayStepOctaveGroup.h +++ b/src/private/mx/core/generated/DisplayStepOctaveGroup.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The display-step-octave group contains the sequence of elements used by both the rest and /// unpitched elements. This group is used to place rests and unpitched elements on the staff without /// implying that these elements have pitch. Positioning follows the current clef. If percussion clef @@ -43,6 +45,9 @@ class DisplayStepOctaveGroup final /// is the enclosing element, for error paths. DisplayStepOctaveGroup parseDisplayStepOctaveGroup(pugi::xml_node el, pugi::xml_node &cursor); +DisplayStepOctaveGroup parseDisplayStepOctaveGroup(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context); + void serializeDisplayStepOctaveGroup(const DisplayStepOctaveGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/Distance.cpp b/src/private/mx/core/generated/Distance.cpp index f2a1ea9cd..26d21a181 100644 --- a/src/private/mx/core/generated/Distance.cpp +++ b/src/private/mx/core/generated/Distance.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Distance.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void Distance::setValue(Tenths value) } Distance parseDistance(pugi::xml_node el) +{ + return parseDistance(el, ParseContext{}); +} + +Distance parseDistance(pugi::xml_node el, const ParseContext &context) { Distance out; bool seen_type = false; @@ -44,7 +50,7 @@ Distance parseDistance(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(DistanceType::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else { @@ -55,13 +61,18 @@ Distance parseDistance(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseDistanceContent(out, el); + parseDistanceContent(out, el, context); return out; } void parseDistanceContent(Distance &out, pugi::xml_node el) { - out.setValue(Tenths::parse(childText(el))); + parseDistanceContent(out, el, ParseContext{}); +} + +void parseDistanceContent(Distance &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Distance.h b/src/private/mx/core/generated/Distance.h index bcf5847bc..99b0297ec 100644 --- a/src/private/mx/core/generated/Distance.h +++ b/src/private/mx/core/generated/Distance.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The distance element represents standard distances between notation elements in tenths. The type /// attribute defines what type of distance is being defined. Valid values include hyphen (for /// hyphens in lyrics) and beam. @@ -35,8 +37,12 @@ class Distance final Distance parseDistance(pugi::xml_node el); +Distance parseDistance(pugi::xml_node el, const ParseContext &context); + void parseDistanceContent(Distance &out, pugi::xml_node el); +void parseDistanceContent(Distance &out, pugi::xml_node el, const ParseContext &context); + void serializeDistance(const Distance &v, pugi::xml_node parent, const char *tag); void serializeDistanceContent(const Distance &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/DistanceType.cpp b/src/private/mx/core/generated/DistanceType.cpp index b46f430b6..c06825c90 100644 --- a/src/private/mx/core/generated/DistanceType.cpp +++ b/src/private/mx/core/generated/DistanceType.cpp @@ -32,4 +32,11 @@ DistanceType DistanceType::parse(std::string_view text) return DistanceType{std::string{text}}; } +DistanceType DistanceType::parse(std::string_view text, ValueParseOutcome &outcome) +{ + DistanceType out{std::string{text}}; + outcome = out.value() == text ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; +} + } // namespace mx::core diff --git a/src/private/mx/core/generated/DistanceType.h b/src/private/mx/core/generated/DistanceType.h index 610900824..ce39c4302 100644 --- a/src/private/mx/core/generated/DistanceType.h +++ b/src/private/mx/core/generated/DistanceType.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -36,6 +38,9 @@ class DistanceType final static DistanceType parse(std::string_view text); + /// Says whether the text had to be repaired. + static DistanceType parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const DistanceType &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Divisions.cpp b/src/private/mx/core/generated/Divisions.cpp index 91a724764..a0769c4d2 100644 --- a/src/private/mx/core/generated/Divisions.cpp +++ b/src/private/mx/core/generated/Divisions.cpp @@ -34,20 +34,33 @@ std::string Divisions::toString() const bool Divisions::tryParse(std::string_view text, Divisions &out) { - Decimal v; - if (!Decimal::tryParse(text, v)) + ValueParseOutcome outcome = ValueParseOutcome::valid; + Divisions parsed = parse(text, outcome); + if (outcome == ValueParseOutcome::invalid) { return false; } - out = Divisions{std::move(v)}; + out = std::move(parsed); return true; } Divisions Divisions::parse(std::string_view text) { - Divisions v; - tryParse(text, v); - return v; + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +Divisions Divisions::parse(std::string_view text, ValueParseOutcome &outcome) +{ + Decimal v; + if (!Decimal::tryParse(text, v)) + { + outcome = ValueParseOutcome::invalid; + return Divisions{}; + } + Divisions out{v}; + outcome = out.value() == v ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; } } // namespace mx::core diff --git a/src/private/mx/core/generated/Divisions.h b/src/private/mx/core/generated/Divisions.h index 535b0c36f..2580b5efb 100644 --- a/src/private/mx/core/generated/Divisions.h +++ b/src/private/mx/core/generated/Divisions.h @@ -3,6 +3,7 @@ #pragma once #include "mx/core/Decimal.h" +#include "mx/core/Lexical.h" #include #include @@ -39,6 +40,9 @@ class Divisions final /// Lenient: non-numeric text yields the clamped zero. static Divisions parse(std::string_view text); + /// Lenient, and says whether the text was non-numeric or clamped. + static Divisions parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const Divisions &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Document.cpp b/src/private/mx/core/generated/Document.cpp index a54b6c258..7eff91ab3 100644 --- a/src/private/mx/core/generated/Document.cpp +++ b/src/private/mx/core/generated/Document.cpp @@ -4,6 +4,7 @@ #include "mx/core/Error.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include "mx/core/generated/Version.h" @@ -14,6 +15,11 @@ namespace mx::core { Result parse(const pugi::xml_document &doc) +{ + return parse(doc, ParseContext{}); +} + +Result parse(const pugi::xml_document &doc, const ParseContext &context) { try { @@ -41,11 +47,11 @@ Result parse(const pugi::xml_document &doc) Document d; if (tag == "score-partwise") { - d = Document{parseScorePartwise(root)}; + d = Document{parseScorePartwise(root, context)}; } else if (tag == "score-timewise") { - d = Document{parseScoreTimewise(root)}; + d = Document{parseScoreTimewise(root, context)}; } else { diff --git a/src/private/mx/core/generated/Document.h b/src/private/mx/core/generated/Document.h index f8fc590fe..de1e5fabb 100644 --- a/src/private/mx/core/generated/Document.h +++ b/src/private/mx/core/generated/Document.h @@ -19,6 +19,8 @@ class xml_document; namespace mx::core { +class ParseContext; + /// A namespace declaration preserved verbatim from the parsed root element /// (xmlns, xmlns:xlink, ...): document plumbing, not schema data, but /// round-trip parity requires writing it back. @@ -103,6 +105,8 @@ class Document final /// SupportedMusicXMLVersion is rejected with unsupportedVersion. Result parse(const pugi::xml_document &doc); +Result parse(const pugi::xml_document &doc, const ParseContext &context); + /// Total for every Document (ยง1.1 guarantees validity): writes the XML /// declaration, the matching DOCTYPE, the preserved root namespace /// declarations, and the typed tree. diff --git a/src/private/mx/core/generated/Double.cpp b/src/private/mx/core/generated/Double.cpp index 128082dd8..3bb94b4f9 100644 --- a/src/private/mx/core/generated/Double.cpp +++ b/src/private/mx/core/generated/Double.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Double.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -21,6 +22,11 @@ void Double::setAbove(std::optional value) } Double parseDouble(pugi::xml_node el) +{ + return parseDouble(el, ParseContext{}); +} + +Double parseDouble(pugi::xml_node el, const ParseContext &context) { Double out; for (pugi::xml_attribute a : el.attributes()) @@ -32,20 +38,26 @@ Double parseDouble(pugi::xml_node el) } if (aname == "above") { - out.setAbove(YesNo::parse(a.value())); + out.setAbove(parseValue(a.value(), context, el, "above")); } else { throwUnknownAttribute(el, a.name()); } } - parseDoubleContent(out, el); + parseDoubleContent(out, el, context); return out; } void parseDoubleContent(Double &out, pugi::xml_node el) +{ + parseDoubleContent(out, el, ParseContext{}); +} + +void parseDoubleContent(Double &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Double.h b/src/private/mx/core/generated/Double.h index 106eb0939..f6717df37 100644 --- a/src/private/mx/core/generated/Double.h +++ b/src/private/mx/core/generated/Double.h @@ -15,6 +15,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The double type indicates that the music is doubled one octave from what is currently written. If /// the above attribute is set to yes, the doubling is one octave above what is written, as for mixed /// flute / piccolo parts in band literature. Otherwise the doubling is one octave below what is @@ -32,8 +34,12 @@ class Double final Double parseDouble(pugi::xml_node el); +Double parseDouble(pugi::xml_node el, const ParseContext &context); + void parseDoubleContent(Double &out, pugi::xml_node el); +void parseDoubleContent(Double &out, pugi::xml_node el, const ParseContext &context); + void serializeDouble(const Double &v, pugi::xml_node parent, const char *tag); void serializeDoubleContent(const Double &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Dynamics.cpp b/src/private/mx/core/generated/Dynamics.cpp index 2f78e9641..5203f1887 100644 --- a/src/private/mx/core/generated/Dynamics.cpp +++ b/src/private/mx/core/generated/Dynamics.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Dynamics.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -196,6 +197,11 @@ void Dynamics::setChoice(std::vector value) } Dynamics parseDynamics(pugi::xml_node el) +{ + return parseDynamics(el, ParseContext{}); +} + +Dynamics parseDynamics(pugi::xml_node el, const ParseContext &context) { Dynamics out; for (pugi::xml_attribute a : el.attributes()) @@ -207,67 +213,67 @@ Dynamics parseDynamics(pugi::xml_node el) } if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "halign") { - out.setHalign(LeftCenterRight::parse(a.value())); + out.setHalign(parseValue(a.value(), context, el, "halign")); } else if (aname == "valign") { - out.setValign(Valign::parse(a.value())); + out.setValign(parseValue(a.value(), context, el, "valign")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else if (aname == "underline") { - out.setUnderline(NumberOfLines::parse(a.value())); + out.setUnderline(parseValue(a.value(), context, el, "underline")); } else if (aname == "overline") { - out.setOverline(NumberOfLines::parse(a.value())); + out.setOverline(parseValue(a.value(), context, el, "overline")); } else if (aname == "line-through") { - out.setLineThrough(NumberOfLines::parse(a.value())); + out.setLineThrough(parseValue(a.value(), context, el, "line-through")); } else if (aname == "enclosure") { - out.setEnclosure(EnclosureShape::parse(a.value())); + out.setEnclosure(parseValue(a.value(), context, el, "enclosure")); } else if (aname == "id") { @@ -278,11 +284,16 @@ Dynamics parseDynamics(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseDynamicsContent(out, el); + parseDynamicsContent(out, el, context); return out; } void parseDynamicsContent(Dynamics &out, pugi::xml_node el) +{ + parseDynamicsContent(out, el, ParseContext{}); +} + +void parseDynamicsContent(Dynamics &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); while (cursor && @@ -295,7 +306,7 @@ void parseDynamicsContent(Dynamics &out, pugi::xml_node el) cursorIs(cursor, "sffz") || cursorIs(cursor, "fz") || cursorIs(cursor, "n") || cursorIs(cursor, "pf") || cursorIs(cursor, "sfzp") || cursorIs(cursor, "other-dynamics"))) { - out.addChoice(parseDynamicsChoice(el, cursor)); + out.addChoice(parseDynamicsChoice(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/Dynamics.h b/src/private/mx/core/generated/Dynamics.h index 9fc71785e..88cf9d5e2 100644 --- a/src/private/mx/core/generated/Dynamics.h +++ b/src/private/mx/core/generated/Dynamics.h @@ -30,6 +30,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Dynamics can be associated either with a note or a general musical direction. To avoid /// inconsistencies between and amongst the letter abbreviations for dynamics (what is sf vs. sfz, /// standing alone or with a trailing dynamic that is not always piano), we use the actual letters as @@ -109,8 +111,12 @@ class Dynamics final Dynamics parseDynamics(pugi::xml_node el); +Dynamics parseDynamics(pugi::xml_node el, const ParseContext &context); + void parseDynamicsContent(Dynamics &out, pugi::xml_node el); +void parseDynamicsContent(Dynamics &out, pugi::xml_node el, const ParseContext &context); + void serializeDynamics(const Dynamics &v, pugi::xml_node parent, const char *tag); void serializeDynamicsContent(const Dynamics &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/DynamicsChoice.cpp b/src/private/mx/core/generated/DynamicsChoice.cpp index 98be29622..5b224b696 100644 --- a/src/private/mx/core/generated/DynamicsChoice.cpp +++ b/src/private/mx/core/generated/DynamicsChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/DynamicsChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -151,166 +152,171 @@ DynamicsChoice DynamicsChoice::otherDynamics(OtherText value) } DynamicsChoice parseDynamicsChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseDynamicsChoice(el, cursor, ParseContext{}); +} + +DynamicsChoice parseDynamicsChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "p"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return DynamicsChoice::p(std::move(value)); } if (cursor && (cursorIs(cursor, "pp"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return DynamicsChoice::pp(std::move(value)); } if (cursor && (cursorIs(cursor, "ppp"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return DynamicsChoice::ppp(std::move(value)); } if (cursor && (cursorIs(cursor, "pppp"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return DynamicsChoice::pppp(std::move(value)); } if (cursor && (cursorIs(cursor, "ppppp"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return DynamicsChoice::ppppp(std::move(value)); } if (cursor && (cursorIs(cursor, "pppppp"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return DynamicsChoice::pppppp(std::move(value)); } if (cursor && (cursorIs(cursor, "f"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return DynamicsChoice::f(std::move(value)); } if (cursor && (cursorIs(cursor, "ff"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return DynamicsChoice::ff(std::move(value)); } if (cursor && (cursorIs(cursor, "fff"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return DynamicsChoice::fff(std::move(value)); } if (cursor && (cursorIs(cursor, "ffff"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return DynamicsChoice::ffff(std::move(value)); } if (cursor && (cursorIs(cursor, "fffff"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return DynamicsChoice::fffff(std::move(value)); } if (cursor && (cursorIs(cursor, "ffffff"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return DynamicsChoice::ffffff(std::move(value)); } if (cursor && (cursorIs(cursor, "mp"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return DynamicsChoice::mp(std::move(value)); } if (cursor && (cursorIs(cursor, "mf"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return DynamicsChoice::mf(std::move(value)); } if (cursor && (cursorIs(cursor, "sf"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return DynamicsChoice::sf(std::move(value)); } if (cursor && (cursorIs(cursor, "sfp"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return DynamicsChoice::sfp(std::move(value)); } if (cursor && (cursorIs(cursor, "sfpp"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return DynamicsChoice::sfpp(std::move(value)); } if (cursor && (cursorIs(cursor, "fp"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return DynamicsChoice::fp(std::move(value)); } if (cursor && (cursorIs(cursor, "rf"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return DynamicsChoice::rf(std::move(value)); } if (cursor && (cursorIs(cursor, "rfz"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return DynamicsChoice::rfz(std::move(value)); } if (cursor && (cursorIs(cursor, "sfz"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return DynamicsChoice::sfz(std::move(value)); } if (cursor && (cursorIs(cursor, "sffz"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return DynamicsChoice::sffz(std::move(value)); } if (cursor && (cursorIs(cursor, "fz"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return DynamicsChoice::fz(std::move(value)); } if (cursor && (cursorIs(cursor, "n"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return DynamicsChoice::n(std::move(value)); } if (cursor && (cursorIs(cursor, "pf"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return DynamicsChoice::pf(std::move(value)); } if (cursor && (cursorIs(cursor, "sfzp"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return DynamicsChoice::sfzp(std::move(value)); } if (cursor && (cursorIs(cursor, "other-dynamics"))) { - OtherText value = parseOtherText(cursor); + OtherText value = parseOtherText(cursor, context); cursor = nextElement(cursor); return DynamicsChoice::otherDynamics(std::move(value)); } diff --git a/src/private/mx/core/generated/DynamicsChoice.h b/src/private/mx/core/generated/DynamicsChoice.h index 52ccf721f..981dcdcf5 100644 --- a/src/private/mx/core/generated/DynamicsChoice.h +++ b/src/private/mx/core/generated/DynamicsChoice.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -434,6 +436,8 @@ class DynamicsChoice final /// the enclosing element, for error paths. DynamicsChoice parseDynamicsChoice(pugi::xml_node el, pugi::xml_node &cursor); +DynamicsChoice parseDynamicsChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeDynamicsChoice(const DynamicsChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/EditorialGroup.cpp b/src/private/mx/core/generated/EditorialGroup.cpp index 4296ec847..d4ff21f37 100644 --- a/src/private/mx/core/generated/EditorialGroup.cpp +++ b/src/private/mx/core/generated/EditorialGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/EditorialGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,16 +32,21 @@ void EditorialGroup::setLevel(std::optional value) } EditorialGroup parseEditorialGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseEditorialGroup(el, cursor, ParseContext{}); +} + +EditorialGroup parseEditorialGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { EditorialGroup out; if (cursorIs(cursor, "footnote")) { - out.setFootnote(parseFormattedText(cursor)); + out.setFootnote(parseFormattedText(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "level")) { - out.setLevel(parseLevel(cursor)); + out.setLevel(parseLevel(cursor, context)); cursor = nextElement(cursor); } return out; diff --git a/src/private/mx/core/generated/EditorialGroup.h b/src/private/mx/core/generated/EditorialGroup.h index 4025ee96e..812c79369 100644 --- a/src/private/mx/core/generated/EditorialGroup.h +++ b/src/private/mx/core/generated/EditorialGroup.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The editorial group specifies editorial information for a musical element. /// A shared content group: transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -39,6 +41,8 @@ class EditorialGroup final /// is the enclosing element, for error paths. EditorialGroup parseEditorialGroup(pugi::xml_node el, pugi::xml_node &cursor); +EditorialGroup parseEditorialGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeEditorialGroup(const EditorialGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/EditorialVoiceDirectionGroup.cpp b/src/private/mx/core/generated/EditorialVoiceDirectionGroup.cpp index c530438ce..dffcba704 100644 --- a/src/private/mx/core/generated/EditorialVoiceDirectionGroup.cpp +++ b/src/private/mx/core/generated/EditorialVoiceDirectionGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/EditorialVoiceDirectionGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,16 +42,22 @@ void EditorialVoiceDirectionGroup::setVoice(std::optional value) } EditorialVoiceDirectionGroup parseEditorialVoiceDirectionGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseEditorialVoiceDirectionGroup(el, cursor, ParseContext{}); +} + +EditorialVoiceDirectionGroup parseEditorialVoiceDirectionGroup(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context) { EditorialVoiceDirectionGroup out; if (cursorIs(cursor, "footnote")) { - out.setFootnote(parseFormattedText(cursor)); + out.setFootnote(parseFormattedText(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "level")) { - out.setLevel(parseLevel(cursor)); + out.setLevel(parseLevel(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "voice")) diff --git a/src/private/mx/core/generated/EditorialVoiceDirectionGroup.h b/src/private/mx/core/generated/EditorialVoiceDirectionGroup.h index aa1cf51d7..e22840ecc 100644 --- a/src/private/mx/core/generated/EditorialVoiceDirectionGroup.h +++ b/src/private/mx/core/generated/EditorialVoiceDirectionGroup.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The editorial-voice-direction group supports the common combination of editorial and voice /// information for a direction element. It is separate from the editorial-voice element because /// extensions and restrictions might be different for directions than for the note and forward @@ -45,6 +47,9 @@ class EditorialVoiceDirectionGroup final /// is the enclosing element, for error paths. EditorialVoiceDirectionGroup parseEditorialVoiceDirectionGroup(pugi::xml_node el, pugi::xml_node &cursor); +EditorialVoiceDirectionGroup parseEditorialVoiceDirectionGroup(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context); + void serializeEditorialVoiceDirectionGroup(const EditorialVoiceDirectionGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/EditorialVoiceGroup.cpp b/src/private/mx/core/generated/EditorialVoiceGroup.cpp index e9aa79ddd..6086f3922 100644 --- a/src/private/mx/core/generated/EditorialVoiceGroup.cpp +++ b/src/private/mx/core/generated/EditorialVoiceGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/EditorialVoiceGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,16 +42,21 @@ void EditorialVoiceGroup::setVoice(std::optional value) } EditorialVoiceGroup parseEditorialVoiceGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseEditorialVoiceGroup(el, cursor, ParseContext{}); +} + +EditorialVoiceGroup parseEditorialVoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { EditorialVoiceGroup out; if (cursorIs(cursor, "footnote")) { - out.setFootnote(parseFormattedText(cursor)); + out.setFootnote(parseFormattedText(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "level")) { - out.setLevel(parseLevel(cursor)); + out.setLevel(parseLevel(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "voice")) diff --git a/src/private/mx/core/generated/EditorialVoiceGroup.h b/src/private/mx/core/generated/EditorialVoiceGroup.h index fbd4a5364..ad8882ec7 100644 --- a/src/private/mx/core/generated/EditorialVoiceGroup.h +++ b/src/private/mx/core/generated/EditorialVoiceGroup.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The editorial-voice group supports the common combination of editorial and voice information for /// a musical element. /// A shared content group: transparent on the wire, its @@ -43,6 +45,8 @@ class EditorialVoiceGroup final /// is the enclosing element, for error paths. EditorialVoiceGroup parseEditorialVoiceGroup(pugi::xml_node el, pugi::xml_node &cursor); +EditorialVoiceGroup parseEditorialVoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeEditorialVoiceGroup(const EditorialVoiceGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/Effect.cpp b/src/private/mx/core/generated/Effect.cpp index 22dc1926c..4de9c6384 100644 --- a/src/private/mx/core/generated/Effect.cpp +++ b/src/private/mx/core/generated/Effect.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Effect.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void Effect::setValue(EffectValue value) } Effect parseEffect(pugi::xml_node el) +{ + return parseEffect(el, ParseContext{}); +} + +Effect parseEffect(pugi::xml_node el, const ParseContext &context) { Effect out; for (pugi::xml_attribute a : el.attributes()) @@ -42,20 +48,25 @@ Effect parseEffect(pugi::xml_node el) } if (aname == "smufl") { - out.setSmufl(SmuflPictogramGlyphName::parse(a.value())); + out.setSmufl(parseValue(a.value(), context, el, "smufl")); } else { throwUnknownAttribute(el, a.name()); } } - parseEffectContent(out, el); + parseEffectContent(out, el, context); return out; } void parseEffectContent(Effect &out, pugi::xml_node el) { - out.setValue(EffectValue::parse(childText(el))); + parseEffectContent(out, el, ParseContext{}); +} + +void parseEffectContent(Effect &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Effect.h b/src/private/mx/core/generated/Effect.h index c79739371..91ab7943a 100644 --- a/src/private/mx/core/generated/Effect.h +++ b/src/private/mx/core/generated/Effect.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The effect type represents pictograms for sound effect percussion instruments. The smufl /// attribute is used to distinguish different SMuFL stylistic alternates. class Effect final @@ -34,8 +36,12 @@ class Effect final Effect parseEffect(pugi::xml_node el); +Effect parseEffect(pugi::xml_node el, const ParseContext &context); + void parseEffectContent(Effect &out, pugi::xml_node el); +void parseEffectContent(Effect &out, pugi::xml_node el, const ParseContext &context); + void serializeEffect(const Effect &v, pugi::xml_node parent, const char *tag); void serializeEffectContent(const Effect &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/EffectValue.cpp b/src/private/mx/core/generated/EffectValue.cpp index aa2db4651..662f736da 100644 --- a/src/private/mx/core/generated/EffectValue.cpp +++ b/src/private/mx/core/generated/EffectValue.cpp @@ -113,9 +113,15 @@ bool EffectValue::tryParse(std::string_view text, EffectValue &out) noexcept } EffectValue EffectValue::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +EffectValue EffectValue::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { EffectValue v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/EffectValue.h b/src/private/mx/core/generated/EffectValue.h index 5a3e6bab4..58caf75e3 100644 --- a/src/private/mx/core/generated/EffectValue.h +++ b/src/private/mx/core/generated/EffectValue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -69,6 +71,9 @@ class EffectValue final /// (the import leniency policy; never produces an invalid value). static EffectValue parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static EffectValue parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const EffectValue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Elision.cpp b/src/private/mx/core/generated/Elision.cpp index f5faa0d43..82d2b119c 100644 --- a/src/private/mx/core/generated/Elision.cpp +++ b/src/private/mx/core/generated/Elision.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Elision.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -81,6 +82,11 @@ void Elision::setValue(std::string value) } Elision parseElision(pugi::xml_node el) +{ + return parseElision(el, ParseContext{}); +} + +Elision parseElision(pugi::xml_node el, const ParseContext &context) { Elision out; for (pugi::xml_attribute a : el.attributes()) @@ -92,38 +98,43 @@ Elision parseElision(pugi::xml_node el) } if (aname == "smufl") { - out.setSmufl(SmuflLyricsGlyphName::parse(a.value())); + out.setSmufl(parseValue(a.value(), context, el, "smufl")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else { throwUnknownAttribute(el, a.name()); } } - parseElisionContent(out, el); + parseElisionContent(out, el, context); return out; } void parseElisionContent(Elision &out, pugi::xml_node el) +{ + parseElisionContent(out, el, ParseContext{}); +} + +void parseElisionContent(Elision &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/Elision.h b/src/private/mx/core/generated/Elision.h index 1e43cbcbc..98def3af4 100644 --- a/src/private/mx/core/generated/Elision.h +++ b/src/private/mx/core/generated/Elision.h @@ -20,6 +20,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The elision type represents an elision between lyric syllables. The text content specifies the /// symbol used to display the elision. Common values are a no-break space (Unicode 00A0), an /// underscore (Unicode 005F), or an undertie (Unicode 203F). If the text content is empty, the smufl @@ -58,8 +60,12 @@ class Elision final Elision parseElision(pugi::xml_node el); +Elision parseElision(pugi::xml_node el, const ParseContext &context); + void parseElisionContent(Elision &out, pugi::xml_node el); +void parseElisionContent(Elision &out, pugi::xml_node el, const ParseContext &context); + void serializeElision(const Elision &v, pugi::xml_node parent, const char *tag); void serializeElisionContent(const Elision &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/ElisionSyllabicGroup.cpp b/src/private/mx/core/generated/ElisionSyllabicGroup.cpp index f41f8793f..0f358b878 100644 --- a/src/private/mx/core/generated/ElisionSyllabicGroup.cpp +++ b/src/private/mx/core/generated/ElisionSyllabicGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/ElisionSyllabicGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,11 +32,16 @@ void ElisionSyllabicGroup::setSyllabic(std::optional value) } ElisionSyllabicGroup parseElisionSyllabicGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseElisionSyllabicGroup(el, cursor, ParseContext{}); +} + +ElisionSyllabicGroup parseElisionSyllabicGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { ElisionSyllabicGroup out; if (cursorIs(cursor, "elision")) { - out.setElision(parseElision(cursor)); + out.setElision(parseElision(cursor, context)); cursor = nextElement(cursor); } else @@ -44,7 +50,7 @@ ElisionSyllabicGroup parseElisionSyllabicGroup(pugi::xml_node el, pugi::xml_node } if (cursorIs(cursor, "syllabic")) { - out.setSyllabic(Syllabic::parse(childText(cursor))); + out.setSyllabic(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } return out; diff --git a/src/private/mx/core/generated/ElisionSyllabicGroup.h b/src/private/mx/core/generated/ElisionSyllabicGroup.h index 0b063a5ae..72f511c1f 100644 --- a/src/private/mx/core/generated/ElisionSyllabicGroup.h +++ b/src/private/mx/core/generated/ElisionSyllabicGroup.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A shared content group (synthesized from an anonymous /// particle of the schema): transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -39,6 +41,8 @@ class ElisionSyllabicGroup final /// is the enclosing element, for error paths. ElisionSyllabicGroup parseElisionSyllabicGroup(pugi::xml_node el, pugi::xml_node &cursor); +ElisionSyllabicGroup parseElisionSyllabicGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeElisionSyllabicGroup(const ElisionSyllabicGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/Empty.cpp b/src/private/mx/core/generated/Empty.cpp index 990b6fbb5..931deadeb 100644 --- a/src/private/mx/core/generated/Empty.cpp +++ b/src/private/mx/core/generated/Empty.cpp @@ -2,12 +2,18 @@ #include "mx/core/generated/Empty.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" namespace mx::core { Empty parseEmpty(pugi::xml_node el) +{ + return parseEmpty(el, ParseContext{}); +} + +Empty parseEmpty(pugi::xml_node el, const ParseContext &context) { Empty out; for (pugi::xml_attribute a : el.attributes()) @@ -19,13 +25,19 @@ Empty parseEmpty(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseEmptyContent(out, el); + parseEmptyContent(out, el, context); return out; } void parseEmptyContent(Empty &out, pugi::xml_node el) +{ + parseEmptyContent(out, el, ParseContext{}); +} + +void parseEmptyContent(Empty &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Empty.h b/src/private/mx/core/generated/Empty.h index 2766300c7..4b172eef8 100644 --- a/src/private/mx/core/generated/Empty.h +++ b/src/private/mx/core/generated/Empty.h @@ -10,6 +10,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The empty type represents an empty element with no attributes. /// Presence-only marker: the element's only information is whether it /// appears. Optional occurrences project to bool fields; choice @@ -22,8 +24,12 @@ class Empty Empty parseEmpty(pugi::xml_node el); +Empty parseEmpty(pugi::xml_node el, const ParseContext &context); + void parseEmptyContent(Empty &out, pugi::xml_node el); +void parseEmptyContent(Empty &out, pugi::xml_node el, const ParseContext &context); + void serializeEmpty(const Empty &v, pugi::xml_node parent, const char *tag); void serializeEmptyContent(const Empty &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/EmptyFont.cpp b/src/private/mx/core/generated/EmptyFont.cpp index 11a8f344d..6f4b97c52 100644 --- a/src/private/mx/core/generated/EmptyFont.cpp +++ b/src/private/mx/core/generated/EmptyFont.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/EmptyFont.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -51,6 +52,11 @@ void EmptyFont::setFontWeight(std::optional value) } EmptyFont parseEmptyFont(pugi::xml_node el) +{ + return parseEmptyFont(el, ParseContext{}); +} + +EmptyFont parseEmptyFont(pugi::xml_node el, const ParseContext &context) { EmptyFont out; for (pugi::xml_attribute a : el.attributes()) @@ -62,32 +68,38 @@ EmptyFont parseEmptyFont(pugi::xml_node el) } if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else { throwUnknownAttribute(el, a.name()); } } - parseEmptyFontContent(out, el); + parseEmptyFontContent(out, el, context); return out; } void parseEmptyFontContent(EmptyFont &out, pugi::xml_node el) +{ + parseEmptyFontContent(out, el, ParseContext{}); +} + +void parseEmptyFontContent(EmptyFont &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/EmptyFont.h b/src/private/mx/core/generated/EmptyFont.h index 592220cc5..affe836b2 100644 --- a/src/private/mx/core/generated/EmptyFont.h +++ b/src/private/mx/core/generated/EmptyFont.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The empty-font type represents an empty element with font attributes. class EmptyFont final { @@ -41,8 +43,12 @@ class EmptyFont final EmptyFont parseEmptyFont(pugi::xml_node el); +EmptyFont parseEmptyFont(pugi::xml_node el, const ParseContext &context); + void parseEmptyFontContent(EmptyFont &out, pugi::xml_node el); +void parseEmptyFontContent(EmptyFont &out, pugi::xml_node el, const ParseContext &context); + void serializeEmptyFont(const EmptyFont &v, pugi::xml_node parent, const char *tag); void serializeEmptyFontContent(const EmptyFont &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/EmptyLine.cpp b/src/private/mx/core/generated/EmptyLine.cpp index 68b8ff05e..9abe96c27 100644 --- a/src/private/mx/core/generated/EmptyLine.cpp +++ b/src/private/mx/core/generated/EmptyLine.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/EmptyLine.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -161,6 +162,11 @@ void EmptyLine::setPlacement(std::optional value) } EmptyLine parseEmptyLine(pugi::xml_node el) +{ + return parseEmptyLine(el, ParseContext{}); +} + +EmptyLine parseEmptyLine(pugi::xml_node el, const ParseContext &context) { EmptyLine out; for (pugi::xml_attribute a : el.attributes()) @@ -172,76 +178,82 @@ EmptyLine parseEmptyLine(pugi::xml_node el) } if (aname == "line-shape") { - out.setLineShape(LineShape::parse(a.value())); + out.setLineShape(parseValue(a.value(), context, el, "line-shape")); } else if (aname == "line-type") { - out.setLineType(LineType::parse(a.value())); + out.setLineType(parseValue(a.value(), context, el, "line-type")); } else if (aname == "line-length") { - out.setLineLength(LineLength::parse(a.value())); + out.setLineLength(parseValue(a.value(), context, el, "line-length")); } else if (aname == "dash-length") { - out.setDashLength(Tenths::parse(a.value())); + out.setDashLength(parseValue(a.value(), context, el, "dash-length")); } else if (aname == "space-length") { - out.setSpaceLength(Tenths::parse(a.value())); + out.setSpaceLength(parseValue(a.value(), context, el, "space-length")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else { throwUnknownAttribute(el, a.name()); } } - parseEmptyLineContent(out, el); + parseEmptyLineContent(out, el, context); return out; } void parseEmptyLineContent(EmptyLine &out, pugi::xml_node el) +{ + parseEmptyLineContent(out, el, ParseContext{}); +} + +void parseEmptyLineContent(EmptyLine &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/EmptyLine.h b/src/private/mx/core/generated/EmptyLine.h index 73f8590b4..6cea161f4 100644 --- a/src/private/mx/core/generated/EmptyLine.h +++ b/src/private/mx/core/generated/EmptyLine.h @@ -24,6 +24,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The empty-line type represents an empty element with line-shape, line-type, line-length, /// dashed-formatting, print-style and placement attributes. class EmptyLine final @@ -81,8 +83,12 @@ class EmptyLine final EmptyLine parseEmptyLine(pugi::xml_node el); +EmptyLine parseEmptyLine(pugi::xml_node el, const ParseContext &context); + void parseEmptyLineContent(EmptyLine &out, pugi::xml_node el); +void parseEmptyLineContent(EmptyLine &out, pugi::xml_node el, const ParseContext &context); + void serializeEmptyLine(const EmptyLine &v, pugi::xml_node parent, const char *tag); void serializeEmptyLineContent(const EmptyLine &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/EmptyPlacement.cpp b/src/private/mx/core/generated/EmptyPlacement.cpp index 9ea49e65c..a8a68f126 100644 --- a/src/private/mx/core/generated/EmptyPlacement.cpp +++ b/src/private/mx/core/generated/EmptyPlacement.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/EmptyPlacement.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -111,6 +112,11 @@ void EmptyPlacement::setPlacement(std::optional value) } EmptyPlacement parseEmptyPlacement(pugi::xml_node el) +{ + return parseEmptyPlacement(el, ParseContext{}); +} + +EmptyPlacement parseEmptyPlacement(pugi::xml_node el, const ParseContext &context) { EmptyPlacement out; for (pugi::xml_attribute a : el.attributes()) @@ -122,56 +128,62 @@ EmptyPlacement parseEmptyPlacement(pugi::xml_node el) } if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else { throwUnknownAttribute(el, a.name()); } } - parseEmptyPlacementContent(out, el); + parseEmptyPlacementContent(out, el, context); return out; } void parseEmptyPlacementContent(EmptyPlacement &out, pugi::xml_node el) +{ + parseEmptyPlacementContent(out, el, ParseContext{}); +} + +void parseEmptyPlacementContent(EmptyPlacement &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/EmptyPlacement.h b/src/private/mx/core/generated/EmptyPlacement.h index ca00d40fe..0aa066430 100644 --- a/src/private/mx/core/generated/EmptyPlacement.h +++ b/src/private/mx/core/generated/EmptyPlacement.h @@ -21,6 +21,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The empty-placement type represents an empty element with print-style and placement attributes. class EmptyPlacement { @@ -62,8 +64,12 @@ class EmptyPlacement EmptyPlacement parseEmptyPlacement(pugi::xml_node el); +EmptyPlacement parseEmptyPlacement(pugi::xml_node el, const ParseContext &context); + void parseEmptyPlacementContent(EmptyPlacement &out, pugi::xml_node el); +void parseEmptyPlacementContent(EmptyPlacement &out, pugi::xml_node el, const ParseContext &context); + void serializeEmptyPlacement(const EmptyPlacement &v, pugi::xml_node parent, const char *tag); void serializeEmptyPlacementContent(const EmptyPlacement &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/EmptyPlacementSmufl.cpp b/src/private/mx/core/generated/EmptyPlacementSmufl.cpp index 7253e6d37..93e4d6a01 100644 --- a/src/private/mx/core/generated/EmptyPlacementSmufl.cpp +++ b/src/private/mx/core/generated/EmptyPlacementSmufl.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/EmptyPlacementSmufl.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -121,6 +122,11 @@ void EmptyPlacementSmufl::setSmufl(std::optional value) } EmptyPlacementSmufl parseEmptyPlacementSmufl(pugi::xml_node el) +{ + return parseEmptyPlacementSmufl(el, ParseContext{}); +} + +EmptyPlacementSmufl parseEmptyPlacementSmufl(pugi::xml_node el, const ParseContext &context) { EmptyPlacementSmufl out; for (pugi::xml_attribute a : el.attributes()) @@ -132,60 +138,66 @@ EmptyPlacementSmufl parseEmptyPlacementSmufl(pugi::xml_node el) } if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else if (aname == "smufl") { - out.setSmufl(SmuflGlyphName::parse(a.value())); + out.setSmufl(parseValue(a.value(), context, el, "smufl")); } else { throwUnknownAttribute(el, a.name()); } } - parseEmptyPlacementSmuflContent(out, el); + parseEmptyPlacementSmuflContent(out, el, context); return out; } void parseEmptyPlacementSmuflContent(EmptyPlacementSmufl &out, pugi::xml_node el) +{ + parseEmptyPlacementSmuflContent(out, el, ParseContext{}); +} + +void parseEmptyPlacementSmuflContent(EmptyPlacementSmufl &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/EmptyPlacementSmufl.h b/src/private/mx/core/generated/EmptyPlacementSmufl.h index 0a8c28466..cd4161053 100644 --- a/src/private/mx/core/generated/EmptyPlacementSmufl.h +++ b/src/private/mx/core/generated/EmptyPlacementSmufl.h @@ -22,6 +22,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The empty-placement-smufl type represents an empty element with print-style, placement, and smufl /// attributes. class EmptyPlacementSmufl final @@ -67,8 +69,12 @@ class EmptyPlacementSmufl final EmptyPlacementSmufl parseEmptyPlacementSmufl(pugi::xml_node el); +EmptyPlacementSmufl parseEmptyPlacementSmufl(pugi::xml_node el, const ParseContext &context); + void parseEmptyPlacementSmuflContent(EmptyPlacementSmufl &out, pugi::xml_node el); +void parseEmptyPlacementSmuflContent(EmptyPlacementSmufl &out, pugi::xml_node el, const ParseContext &context); + void serializeEmptyPlacementSmufl(const EmptyPlacementSmufl &v, pugi::xml_node parent, const char *tag); void serializeEmptyPlacementSmuflContent(const EmptyPlacementSmufl &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/EmptyPrintObjectStyleAlign.cpp b/src/private/mx/core/generated/EmptyPrintObjectStyleAlign.cpp index dddc2c188..17c9ffb43 100644 --- a/src/private/mx/core/generated/EmptyPrintObjectStyleAlign.cpp +++ b/src/private/mx/core/generated/EmptyPrintObjectStyleAlign.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/EmptyPrintObjectStyleAlign.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -131,6 +132,11 @@ void EmptyPrintObjectStyleAlign::setValign(std::optional value) } EmptyPrintObjectStyleAlign parseEmptyPrintObjectStyleAlign(pugi::xml_node el) +{ + return parseEmptyPrintObjectStyleAlign(el, ParseContext{}); +} + +EmptyPrintObjectStyleAlign parseEmptyPrintObjectStyleAlign(pugi::xml_node el, const ParseContext &context) { EmptyPrintObjectStyleAlign out; for (pugi::xml_attribute a : el.attributes()) @@ -142,64 +148,71 @@ EmptyPrintObjectStyleAlign parseEmptyPrintObjectStyleAlign(pugi::xml_node el) } if (aname == "print-object") { - out.setPrintObject(YesNo::parse(a.value())); + out.setPrintObject(parseValue(a.value(), context, el, "print-object")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "halign") { - out.setHalign(LeftCenterRight::parse(a.value())); + out.setHalign(parseValue(a.value(), context, el, "halign")); } else if (aname == "valign") { - out.setValign(Valign::parse(a.value())); + out.setValign(parseValue(a.value(), context, el, "valign")); } else { throwUnknownAttribute(el, a.name()); } } - parseEmptyPrintObjectStyleAlignContent(out, el); + parseEmptyPrintObjectStyleAlignContent(out, el, context); return out; } void parseEmptyPrintObjectStyleAlignContent(EmptyPrintObjectStyleAlign &out, pugi::xml_node el) +{ + parseEmptyPrintObjectStyleAlignContent(out, el, ParseContext{}); +} + +void parseEmptyPrintObjectStyleAlignContent(EmptyPrintObjectStyleAlign &out, pugi::xml_node el, + const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/EmptyPrintObjectStyleAlign.h b/src/private/mx/core/generated/EmptyPrintObjectStyleAlign.h index 47b4f48e3..b83d87018 100644 --- a/src/private/mx/core/generated/EmptyPrintObjectStyleAlign.h +++ b/src/private/mx/core/generated/EmptyPrintObjectStyleAlign.h @@ -23,6 +23,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The empty-print-style-align-object type represents an empty element with print-object and /// print-style-align attribute groups. class EmptyPrintObjectStyleAlign final @@ -71,8 +73,13 @@ class EmptyPrintObjectStyleAlign final EmptyPrintObjectStyleAlign parseEmptyPrintObjectStyleAlign(pugi::xml_node el); +EmptyPrintObjectStyleAlign parseEmptyPrintObjectStyleAlign(pugi::xml_node el, const ParseContext &context); + void parseEmptyPrintObjectStyleAlignContent(EmptyPrintObjectStyleAlign &out, pugi::xml_node el); +void parseEmptyPrintObjectStyleAlignContent(EmptyPrintObjectStyleAlign &out, pugi::xml_node el, + const ParseContext &context); + void serializeEmptyPrintObjectStyleAlign(const EmptyPrintObjectStyleAlign &v, pugi::xml_node parent, const char *tag); void serializeEmptyPrintObjectStyleAlignContent(const EmptyPrintObjectStyleAlign &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/EmptyPrintStyleAlignID.cpp b/src/private/mx/core/generated/EmptyPrintStyleAlignID.cpp index 1c1c75512..3414ab500 100644 --- a/src/private/mx/core/generated/EmptyPrintStyleAlignID.cpp +++ b/src/private/mx/core/generated/EmptyPrintStyleAlignID.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/EmptyPrintStyleAlignID.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -131,6 +132,11 @@ void EmptyPrintStyleAlignID::setID(std::optional value) } EmptyPrintStyleAlignID parseEmptyPrintStyleAlignID(pugi::xml_node el) +{ + return parseEmptyPrintStyleAlignID(el, ParseContext{}); +} + +EmptyPrintStyleAlignID parseEmptyPrintStyleAlignID(pugi::xml_node el, const ParseContext &context) { EmptyPrintStyleAlignID out; for (pugi::xml_attribute a : el.attributes()) @@ -142,47 +148,47 @@ EmptyPrintStyleAlignID parseEmptyPrintStyleAlignID(pugi::xml_node el) } if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "halign") { - out.setHalign(LeftCenterRight::parse(a.value())); + out.setHalign(parseValue(a.value(), context, el, "halign")); } else if (aname == "valign") { - out.setValign(Valign::parse(a.value())); + out.setValign(parseValue(a.value(), context, el, "valign")); } else if (aname == "id") { @@ -193,13 +199,19 @@ EmptyPrintStyleAlignID parseEmptyPrintStyleAlignID(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseEmptyPrintStyleAlignIDContent(out, el); + parseEmptyPrintStyleAlignIDContent(out, el, context); return out; } void parseEmptyPrintStyleAlignIDContent(EmptyPrintStyleAlignID &out, pugi::xml_node el) +{ + parseEmptyPrintStyleAlignIDContent(out, el, ParseContext{}); +} + +void parseEmptyPrintStyleAlignIDContent(EmptyPrintStyleAlignID &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/EmptyPrintStyleAlignID.h b/src/private/mx/core/generated/EmptyPrintStyleAlignID.h index 2dafbd197..e72d9b55d 100644 --- a/src/private/mx/core/generated/EmptyPrintStyleAlignID.h +++ b/src/private/mx/core/generated/EmptyPrintStyleAlignID.h @@ -24,6 +24,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The empty-print-style-align-id type represents an empty element with print-style-align and /// optional-unique-id attribute groups. class EmptyPrintStyleAlignID final @@ -72,8 +74,12 @@ class EmptyPrintStyleAlignID final EmptyPrintStyleAlignID parseEmptyPrintStyleAlignID(pugi::xml_node el); +EmptyPrintStyleAlignID parseEmptyPrintStyleAlignID(pugi::xml_node el, const ParseContext &context); + void parseEmptyPrintStyleAlignIDContent(EmptyPrintStyleAlignID &out, pugi::xml_node el); +void parseEmptyPrintStyleAlignIDContent(EmptyPrintStyleAlignID &out, pugi::xml_node el, const ParseContext &context); + void serializeEmptyPrintStyleAlignID(const EmptyPrintStyleAlignID &v, pugi::xml_node parent, const char *tag); void serializeEmptyPrintStyleAlignIDContent(const EmptyPrintStyleAlignID &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/EmptyTrillSound.cpp b/src/private/mx/core/generated/EmptyTrillSound.cpp index da7fb3280..3c58694d2 100644 --- a/src/private/mx/core/generated/EmptyTrillSound.cpp +++ b/src/private/mx/core/generated/EmptyTrillSound.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/EmptyTrillSound.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -181,6 +182,11 @@ void EmptyTrillSound::setLastBeat(std::optional value) } EmptyTrillSound parseEmptyTrillSound(pugi::xml_node el) +{ + return parseEmptyTrillSound(el, ParseContext{}); +} + +EmptyTrillSound parseEmptyTrillSound(pugi::xml_node el, const ParseContext &context) { EmptyTrillSound out; for (pugi::xml_attribute a : el.attributes()) @@ -192,84 +198,90 @@ EmptyTrillSound parseEmptyTrillSound(pugi::xml_node el) } if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else if (aname == "start-note") { - out.setStartNote(StartNote::parse(a.value())); + out.setStartNote(parseValue(a.value(), context, el, "start-note")); } else if (aname == "trill-step") { - out.setTrillStep(TrillStep::parse(a.value())); + out.setTrillStep(parseValue(a.value(), context, el, "trill-step")); } else if (aname == "two-note-turn") { - out.setTwoNoteTurn(TwoNoteTurn::parse(a.value())); + out.setTwoNoteTurn(parseValue(a.value(), context, el, "two-note-turn")); } else if (aname == "accelerate") { - out.setAccelerate(YesNo::parse(a.value())); + out.setAccelerate(parseValue(a.value(), context, el, "accelerate")); } else if (aname == "beats") { - out.setBeats(TrillBeats::parse(a.value())); + out.setBeats(parseValue(a.value(), context, el, "beats")); } else if (aname == "second-beat") { - out.setSecondBeat(Percent::parse(a.value())); + out.setSecondBeat(parseValue(a.value(), context, el, "second-beat")); } else if (aname == "last-beat") { - out.setLastBeat(Percent::parse(a.value())); + out.setLastBeat(parseValue(a.value(), context, el, "last-beat")); } else { throwUnknownAttribute(el, a.name()); } } - parseEmptyTrillSoundContent(out, el); + parseEmptyTrillSoundContent(out, el, context); return out; } void parseEmptyTrillSoundContent(EmptyTrillSound &out, pugi::xml_node el) +{ + parseEmptyTrillSoundContent(out, el, ParseContext{}); +} + +void parseEmptyTrillSoundContent(EmptyTrillSound &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/EmptyTrillSound.h b/src/private/mx/core/generated/EmptyTrillSound.h index c241ce5e4..0312699f8 100644 --- a/src/private/mx/core/generated/EmptyTrillSound.h +++ b/src/private/mx/core/generated/EmptyTrillSound.h @@ -27,6 +27,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The empty-trill-sound type represents an empty element with print-style, placement, and /// trill-sound attributes. class EmptyTrillSound @@ -90,8 +92,12 @@ class EmptyTrillSound EmptyTrillSound parseEmptyTrillSound(pugi::xml_node el); +EmptyTrillSound parseEmptyTrillSound(pugi::xml_node el, const ParseContext &context); + void parseEmptyTrillSoundContent(EmptyTrillSound &out, pugi::xml_node el); +void parseEmptyTrillSoundContent(EmptyTrillSound &out, pugi::xml_node el, const ParseContext &context); + void serializeEmptyTrillSound(const EmptyTrillSound &v, pugi::xml_node parent, const char *tag); void serializeEmptyTrillSoundContent(const EmptyTrillSound &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/EnclosureShape.cpp b/src/private/mx/core/generated/EnclosureShape.cpp index 29beac6ad..64a12a37e 100644 --- a/src/private/mx/core/generated/EnclosureShape.cpp +++ b/src/private/mx/core/generated/EnclosureShape.cpp @@ -107,9 +107,15 @@ bool EnclosureShape::tryParse(std::string_view text, EnclosureShape &out) noexce } EnclosureShape EnclosureShape::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +EnclosureShape EnclosureShape::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { EnclosureShape v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/EnclosureShape.h b/src/private/mx/core/generated/EnclosureShape.h index b762b6217..2feab76f7 100644 --- a/src/private/mx/core/generated/EnclosureShape.h +++ b/src/private/mx/core/generated/EnclosureShape.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -69,6 +71,9 @@ class EnclosureShape final /// (the import leniency policy; never produces an invalid value). static EnclosureShape parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static EnclosureShape parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const EnclosureShape &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Encoding.cpp b/src/private/mx/core/generated/Encoding.cpp index 044c92455..499de23b5 100644 --- a/src/private/mx/core/generated/Encoding.cpp +++ b/src/private/mx/core/generated/Encoding.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Encoding.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -26,6 +27,11 @@ void Encoding::setChoice(std::vector value) } Encoding parseEncoding(pugi::xml_node el) +{ + return parseEncoding(el, ParseContext{}); +} + +Encoding parseEncoding(pugi::xml_node el, const ParseContext &context) { Encoding out; for (pugi::xml_attribute a : el.attributes()) @@ -37,18 +43,23 @@ Encoding parseEncoding(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseEncodingContent(out, el); + parseEncodingContent(out, el, context); return out; } void parseEncodingContent(Encoding &out, pugi::xml_node el) +{ + parseEncodingContent(out, el, ParseContext{}); +} + +void parseEncodingContent(Encoding &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); while (cursor && (cursorIs(cursor, "encoding-date") || cursorIs(cursor, "encoder") || cursorIs(cursor, "software") || cursorIs(cursor, "encoding-description") || cursorIs(cursor, "supports"))) { - out.addChoice(parseEncodingChoice(el, cursor)); + out.addChoice(parseEncodingChoice(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/Encoding.h b/src/private/mx/core/generated/Encoding.h index 320c61e98..4945e46fe 100644 --- a/src/private/mx/core/generated/Encoding.h +++ b/src/private/mx/core/generated/Encoding.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The encoding element contains information about who did the digital encoding, when, with what /// software, and in what aspects. Standard type values for the encoder element are music, words, and /// arrangement, but other types may be used. The type attribute is only needed when there are @@ -37,8 +39,12 @@ class Encoding final Encoding parseEncoding(pugi::xml_node el); +Encoding parseEncoding(pugi::xml_node el, const ParseContext &context); + void parseEncodingContent(Encoding &out, pugi::xml_node el); +void parseEncodingContent(Encoding &out, pugi::xml_node el, const ParseContext &context); + void serializeEncoding(const Encoding &v, pugi::xml_node parent, const char *tag); void serializeEncodingContent(const Encoding &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/EncodingChoice.cpp b/src/private/mx/core/generated/EncodingChoice.cpp index 9e13a10aa..5bc0c5b19 100644 --- a/src/private/mx/core/generated/EncodingChoice.cpp +++ b/src/private/mx/core/generated/EncodingChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/EncodingChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,16 +42,21 @@ EncodingChoice EncodingChoice::supports(Supports value) } EncodingChoice parseEncodingChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseEncodingChoice(el, cursor, ParseContext{}); +} + +EncodingChoice parseEncodingChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "encoding-date"))) { - YyyyMmDd value = YyyyMmDd::parse(childText(cursor)); + YyyyMmDd value = parseValue(childText(cursor), context, cursor, nullptr); cursor = nextElement(cursor); return EncodingChoice::encodingDate(std::move(value)); } if (cursor && (cursorIs(cursor, "encoder"))) { - TypedText value = parseTypedText(cursor); + TypedText value = parseTypedText(cursor, context); cursor = nextElement(cursor); return EncodingChoice::encoder(std::move(value)); } @@ -68,7 +74,7 @@ EncodingChoice parseEncodingChoice(pugi::xml_node el, pugi::xml_node &cursor) } if (cursor && (cursorIs(cursor, "supports"))) { - Supports value = parseSupports(cursor); + Supports value = parseSupports(cursor, context); cursor = nextElement(cursor); return EncodingChoice::supports(std::move(value)); } diff --git a/src/private/mx/core/generated/EncodingChoice.h b/src/private/mx/core/generated/EncodingChoice.h index 24e6c2fc4..b282da60e 100644 --- a/src/private/mx/core/generated/EncodingChoice.h +++ b/src/private/mx/core/generated/EncodingChoice.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -125,6 +127,8 @@ class EncodingChoice final /// the enclosing element, for error paths. EncodingChoice parseEncodingChoice(pugi::xml_node el, pugi::xml_node &cursor); +EncodingChoice parseEncodingChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeEncodingChoice(const EncodingChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/Ending.cpp b/src/private/mx/core/generated/Ending.cpp index 888c925e7..71a8db6b6 100644 --- a/src/private/mx/core/generated/Ending.cpp +++ b/src/private/mx/core/generated/Ending.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Ending.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -181,6 +182,11 @@ void Ending::setValue(std::string value) } Ending parseEnding(pugi::xml_node el) +{ + return parseEnding(el, ParseContext{}); +} + +Ending parseEnding(pugi::xml_node el, const ParseContext &context) { Ending out; bool seen_number = false; @@ -195,68 +201,68 @@ Ending parseEnding(pugi::xml_node el) if (aname == "number") { seen_number = true; - out.setNumber(EndingNumber::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else if (aname == "type") { seen_type = true; - out.setType(StartStopDiscontinue::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "end-length") { - out.setEndLength(Tenths::parse(a.value())); + out.setEndLength(parseValue(a.value(), context, el, "end-length")); } else if (aname == "text-x") { - out.setTextX(Tenths::parse(a.value())); + out.setTextX(parseValue(a.value(), context, el, "text-x")); } else if (aname == "text-y") { - out.setTextY(Tenths::parse(a.value())); + out.setTextY(parseValue(a.value(), context, el, "text-y")); } else if (aname == "print-object") { - out.setPrintObject(YesNo::parse(a.value())); + out.setPrintObject(parseValue(a.value(), context, el, "print-object")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "system") { - out.setSystem(SystemRelation::parse(a.value())); + out.setSystem(parseValue(a.value(), context, el, "system")); } else { @@ -271,11 +277,16 @@ Ending parseEnding(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseEndingContent(out, el); + parseEndingContent(out, el, context); return out; } void parseEndingContent(Ending &out, pugi::xml_node el) +{ + parseEndingContent(out, el, ParseContext{}); +} + +void parseEndingContent(Ending &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/Ending.h b/src/private/mx/core/generated/Ending.h index 298dca1ae..2bbb02918 100644 --- a/src/private/mx/core/generated/Ending.h +++ b/src/private/mx/core/generated/Ending.h @@ -24,6 +24,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The ending type represents multiple (e.g. first and second) endings. Typically, the start type is /// associated with the left barline of the first measure in an ending. The stop and discontinue /// types are associated with the right barline of the last measure in an ending. Stop is used when @@ -100,8 +102,12 @@ class Ending final Ending parseEnding(pugi::xml_node el); +Ending parseEnding(pugi::xml_node el, const ParseContext &context); + void parseEndingContent(Ending &out, pugi::xml_node el); +void parseEndingContent(Ending &out, pugi::xml_node el, const ParseContext &context); + void serializeEnding(const Ending &v, pugi::xml_node parent, const char *tag); void serializeEndingContent(const Ending &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Extend.cpp b/src/private/mx/core/generated/Extend.cpp index 91ed69cd4..e0ad130f5 100644 --- a/src/private/mx/core/generated/Extend.cpp +++ b/src/private/mx/core/generated/Extend.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Extend.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -71,6 +72,11 @@ void Extend::setColor(std::optional value) } Extend parseExtend(pugi::xml_node el) +{ + return parseExtend(el, ParseContext{}); +} + +Extend parseExtend(pugi::xml_node el, const ParseContext &context) { Extend out; for (pugi::xml_attribute a : el.attributes()) @@ -82,40 +88,46 @@ Extend parseExtend(pugi::xml_node el) } if (aname == "type") { - out.setType(StartStopContinue::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else { throwUnknownAttribute(el, a.name()); } } - parseExtendContent(out, el); + parseExtendContent(out, el, context); return out; } void parseExtendContent(Extend &out, pugi::xml_node el) +{ + parseExtendContent(out, el, ParseContext{}); +} + +void parseExtendContent(Extend &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Extend.h b/src/private/mx/core/generated/Extend.h index 223fa1db6..2ea659af1 100644 --- a/src/private/mx/core/generated/Extend.h +++ b/src/private/mx/core/generated/Extend.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The extend type represents lyric word extension / melisma lines as well as figured bass /// extensions. The optional type and position attributes are added in Version 3.0 to provide better /// formatting control. @@ -48,8 +50,12 @@ class Extend final Extend parseExtend(pugi::xml_node el); +Extend parseExtend(pugi::xml_node el, const ParseContext &context); + void parseExtendContent(Extend &out, pugi::xml_node el); +void parseExtendContent(Extend &out, pugi::xml_node el, const ParseContext &context); + void serializeExtend(const Extend &v, pugi::xml_node parent, const char *tag); void serializeExtendContent(const Extend &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Fan.cpp b/src/private/mx/core/generated/Fan.cpp index 6aea0f1fe..85c5d3c6f 100644 --- a/src/private/mx/core/generated/Fan.cpp +++ b/src/private/mx/core/generated/Fan.cpp @@ -48,9 +48,15 @@ bool Fan::tryParse(std::string_view text, Fan &out) noexcept } Fan Fan::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +Fan Fan::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { Fan v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/Fan.h b/src/private/mx/core/generated/Fan.h index 93362f6d0..513afa7da 100644 --- a/src/private/mx/core/generated/Fan.h +++ b/src/private/mx/core/generated/Fan.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -43,6 +45,9 @@ class Fan final /// (the import leniency policy; never produces an invalid value). static Fan parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static Fan parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const Fan &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Feature.cpp b/src/private/mx/core/generated/Feature.cpp index 9b459933c..98009ab6f 100644 --- a/src/private/mx/core/generated/Feature.cpp +++ b/src/private/mx/core/generated/Feature.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Feature.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void Feature::setValue(std::string value) } Feature parseFeature(pugi::xml_node el) +{ + return parseFeature(el, ParseContext{}); +} + +Feature parseFeature(pugi::xml_node el, const ParseContext &context) { Feature out; for (pugi::xml_attribute a : el.attributes()) @@ -49,11 +55,16 @@ Feature parseFeature(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseFeatureContent(out, el); + parseFeatureContent(out, el, context); return out; } void parseFeatureContent(Feature &out, pugi::xml_node el) +{ + parseFeatureContent(out, el, ParseContext{}); +} + +void parseFeatureContent(Feature &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/Feature.h b/src/private/mx/core/generated/Feature.h index b8fdb75ae..801780ed3 100644 --- a/src/private/mx/core/generated/Feature.h +++ b/src/private/mx/core/generated/Feature.h @@ -13,6 +13,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The feature type is a part of the grouping element used for musical analysis. The type attribute /// represents the type of the feature and the element content represents its value. This type is /// flexible to allow for different analyses. @@ -32,8 +34,12 @@ class Feature final Feature parseFeature(pugi::xml_node el); +Feature parseFeature(pugi::xml_node el, const ParseContext &context); + void parseFeatureContent(Feature &out, pugi::xml_node el); +void parseFeatureContent(Feature &out, pugi::xml_node el, const ParseContext &context); + void serializeFeature(const Feature &v, pugi::xml_node parent, const char *tag); void serializeFeatureContent(const Feature &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Fermata.cpp b/src/private/mx/core/generated/Fermata.cpp index 583ea5479..588c12c95 100644 --- a/src/private/mx/core/generated/Fermata.cpp +++ b/src/private/mx/core/generated/Fermata.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Fermata.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -131,6 +132,11 @@ void Fermata::setValue(FermataShape value) } Fermata parseFermata(pugi::xml_node el) +{ + return parseFermata(el, ParseContext{}); +} + +Fermata parseFermata(pugi::xml_node el, const ParseContext &context) { Fermata out; for (pugi::xml_attribute a : el.attributes()) @@ -142,43 +148,43 @@ Fermata parseFermata(pugi::xml_node el) } if (aname == "type") { - out.setType(UprightInverted::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "id") { @@ -189,13 +195,18 @@ Fermata parseFermata(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseFermataContent(out, el); + parseFermataContent(out, el, context); return out; } void parseFermataContent(Fermata &out, pugi::xml_node el) { - out.setValue(FermataShape::parse(childText(el))); + parseFermataContent(out, el, ParseContext{}); +} + +void parseFermataContent(Fermata &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Fermata.h b/src/private/mx/core/generated/Fermata.h index 8819db610..e645ecc40 100644 --- a/src/private/mx/core/generated/Fermata.h +++ b/src/private/mx/core/generated/Fermata.h @@ -24,6 +24,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The fermata text content represents the shape of the fermata sign. An empty fermata element /// represents a normal fermata. The fermata type is upright if not specified. class Fermata final @@ -72,8 +74,12 @@ class Fermata final Fermata parseFermata(pugi::xml_node el); +Fermata parseFermata(pugi::xml_node el, const ParseContext &context); + void parseFermataContent(Fermata &out, pugi::xml_node el); +void parseFermataContent(Fermata &out, pugi::xml_node el, const ParseContext &context); + void serializeFermata(const Fermata &v, pugi::xml_node parent, const char *tag); void serializeFermataContent(const Fermata &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/FermataShape.cpp b/src/private/mx/core/generated/FermataShape.cpp index b095d1b1b..4fa602c7d 100644 --- a/src/private/mx/core/generated/FermataShape.cpp +++ b/src/private/mx/core/generated/FermataShape.cpp @@ -76,9 +76,15 @@ bool FermataShape::tryParse(std::string_view text, FermataShape &out) noexcept } FermataShape FermataShape::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +FermataShape FermataShape::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { FermataShape v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/FermataShape.h b/src/private/mx/core/generated/FermataShape.h index 5957b944d..28fe3c553 100644 --- a/src/private/mx/core/generated/FermataShape.h +++ b/src/private/mx/core/generated/FermataShape.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -55,6 +57,9 @@ class FermataShape final /// (the import leniency policy; never produces an invalid value). static FermataShape parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static FermataShape parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const FermataShape &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Fifths.cpp b/src/private/mx/core/generated/Fifths.cpp index 2f30ff2bd..45dd30685 100644 --- a/src/private/mx/core/generated/Fifths.cpp +++ b/src/private/mx/core/generated/Fifths.cpp @@ -34,20 +34,33 @@ std::string Fifths::toString() const bool Fifths::tryParse(std::string_view text, Fifths &out) { - int v{}; - if (!tryParseInt(text, v)) + ValueParseOutcome outcome = ValueParseOutcome::valid; + Fifths parsed = parse(text, outcome); + if (outcome == ValueParseOutcome::invalid) { return false; } - out = Fifths{v}; + out = std::move(parsed); return true; } Fifths Fifths::parse(std::string_view text) { - Fifths v; - tryParse(text, v); - return v; + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +Fifths Fifths::parse(std::string_view text, ValueParseOutcome &outcome) +{ + int v{}; + if (!tryParseInt(text, v)) + { + outcome = ValueParseOutcome::invalid; + return Fifths{}; + } + Fifths out{v}; + outcome = out.value() == v ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; } } // namespace mx::core diff --git a/src/private/mx/core/generated/Fifths.h b/src/private/mx/core/generated/Fifths.h index 1b4cbf847..2c97cf7ad 100644 --- a/src/private/mx/core/generated/Fifths.h +++ b/src/private/mx/core/generated/Fifths.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -37,6 +39,9 @@ class Fifths final /// Lenient: non-numeric text yields the clamped zero. static Fifths parse(std::string_view text); + /// Lenient, and says whether the text was non-numeric or clamped. + static Fifths parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const Fifths &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Figure.cpp b/src/private/mx/core/generated/Figure.cpp index 9c03f88ac..954e78a1a 100644 --- a/src/private/mx/core/generated/Figure.cpp +++ b/src/private/mx/core/generated/Figure.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Figure.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -61,6 +62,11 @@ void Figure::setEditorial(EditorialGroup value) } Figure parseFigure(pugi::xml_node el) +{ + return parseFigure(el, ParseContext{}); +} + +Figure parseFigure(pugi::xml_node el, const ParseContext &context) { Figure out; for (pugi::xml_attribute a : el.attributes()) @@ -72,36 +78,41 @@ Figure parseFigure(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseFigureContent(out, el); + parseFigureContent(out, el, context); return out; } void parseFigureContent(Figure &out, pugi::xml_node el) +{ + parseFigureContent(out, el, ParseContext{}); +} + +void parseFigureContent(Figure &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "prefix")) { - out.setPrefix(parseStyleText(cursor)); + out.setPrefix(parseStyleText(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "figure-number")) { - out.setFigureNumber(parseStyleText(cursor)); + out.setFigureNumber(parseStyleText(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "suffix")) { - out.setSuffix(parseStyleText(cursor)); + out.setSuffix(parseStyleText(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "extend")) { - out.setExtend(parseExtend(cursor)); + out.setExtend(parseExtend(cursor, context)); cursor = nextElement(cursor); } if (cursor && (cursorIs(cursor, "footnote") || cursorIs(cursor, "level"))) { - out.setEditorial(parseEditorialGroup(el, cursor)); + out.setEditorial(parseEditorialGroup(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/Figure.h b/src/private/mx/core/generated/Figure.h index 82279fad6..e9ae5e3e2 100644 --- a/src/private/mx/core/generated/Figure.h +++ b/src/private/mx/core/generated/Figure.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The figure type represents a single figure within a figured-bass element. /// Content fields mirror the schema grammar in declaration order; the /// serializer walks them, so a wrong order is unrepresentable (plan ยง2.3). @@ -47,8 +49,12 @@ class Figure final Figure parseFigure(pugi::xml_node el); +Figure parseFigure(pugi::xml_node el, const ParseContext &context); + void parseFigureContent(Figure &out, pugi::xml_node el); +void parseFigureContent(Figure &out, pugi::xml_node el, const ParseContext &context); + void serializeFigure(const Figure &v, pugi::xml_node parent, const char *tag); void serializeFigureContent(const Figure &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/FiguredBass.cpp b/src/private/mx/core/generated/FiguredBass.cpp index 1062a7e32..3699b1fc4 100644 --- a/src/private/mx/core/generated/FiguredBass.cpp +++ b/src/private/mx/core/generated/FiguredBass.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/FiguredBass.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -226,6 +227,11 @@ void FiguredBass::setEditorial(EditorialGroup value) } FiguredBass parseFiguredBass(pugi::xml_node el) +{ + return parseFiguredBass(el, ParseContext{}); +} + +FiguredBass parseFiguredBass(pugi::xml_node el, const ParseContext &context) { FiguredBass out; for (pugi::xml_attribute a : el.attributes()) @@ -237,71 +243,71 @@ FiguredBass parseFiguredBass(pugi::xml_node el) } if (aname == "parentheses") { - out.setParentheses(YesNo::parse(a.value())); + out.setParentheses(parseValue(a.value(), context, el, "parentheses")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "halign") { - out.setHalign(LeftCenterRight::parse(a.value())); + out.setHalign(parseValue(a.value(), context, el, "halign")); } else if (aname == "valign") { - out.setValign(Valign::parse(a.value())); + out.setValign(parseValue(a.value(), context, el, "valign")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else if (aname == "print-dot") { - out.setPrintDot(YesNo::parse(a.value())); + out.setPrintDot(parseValue(a.value(), context, el, "print-dot")); } else if (aname == "print-lyric") { - out.setPrintLyric(YesNo::parse(a.value())); + out.setPrintLyric(parseValue(a.value(), context, el, "print-lyric")); } else if (aname == "print-object") { - out.setPrintObject(YesNo::parse(a.value())); + out.setPrintObject(parseValue(a.value(), context, el, "print-object")); } else if (aname == "print-spacing") { - out.setPrintSpacing(YesNo::parse(a.value())); + out.setPrintSpacing(parseValue(a.value(), context, el, "print-spacing")); } else if (aname == "id") { @@ -312,32 +318,37 @@ FiguredBass parseFiguredBass(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseFiguredBassContent(out, el); + parseFiguredBassContent(out, el, context); return out; } void parseFiguredBassContent(FiguredBass &out, pugi::xml_node el) +{ + parseFiguredBassContent(out, el, ParseContext{}); +} + +void parseFiguredBassContent(FiguredBass &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (!cursorIs(cursor, "figure")) { throwMissingOrMisplaced(el, cursor, "figure"); } - out.setFigure(OneOrMore
{parseFigure(cursor)}); + out.setFigure(OneOrMore
{parseFigure(cursor, context)}); cursor = nextElement(cursor); while (cursorIs(cursor, "figure")) { - out.addFigure(parseFigure(cursor)); + out.addFigure(parseFigure(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "duration")) { - out.setDuration(PositiveDivisions::parse(childText(cursor))); + out.setDuration(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (cursor && (cursorIs(cursor, "footnote") || cursorIs(cursor, "level"))) { - out.setEditorial(parseEditorialGroup(el, cursor)); + out.setEditorial(parseEditorialGroup(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/FiguredBass.h b/src/private/mx/core/generated/FiguredBass.h index 71b74c730..5ae63b372 100644 --- a/src/private/mx/core/generated/FiguredBass.h +++ b/src/private/mx/core/generated/FiguredBass.h @@ -32,6 +32,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The figured-bass element represents figured bass notation. Figured bass elements take their /// position from the first regular note (not a grace note or chord note) that follows in score /// order. The optional duration element is used to indicate changes of figures under a note. Figures @@ -112,8 +114,12 @@ class FiguredBass final FiguredBass parseFiguredBass(pugi::xml_node el); +FiguredBass parseFiguredBass(pugi::xml_node el, const ParseContext &context); + void parseFiguredBassContent(FiguredBass &out, pugi::xml_node el); +void parseFiguredBassContent(FiguredBass &out, pugi::xml_node el, const ParseContext &context); + void serializeFiguredBass(const FiguredBass &v, pugi::xml_node parent, const char *tag); void serializeFiguredBassContent(const FiguredBass &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Fingering.cpp b/src/private/mx/core/generated/Fingering.cpp index d998a1d2a..c781c67fb 100644 --- a/src/private/mx/core/generated/Fingering.cpp +++ b/src/private/mx/core/generated/Fingering.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Fingering.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -141,6 +142,11 @@ void Fingering::setValue(std::string value) } Fingering parseFingering(pugi::xml_node el) +{ + return parseFingering(el, ParseContext{}); +} + +Fingering parseFingering(pugi::xml_node el, const ParseContext &context) { Fingering out; for (pugi::xml_attribute a : el.attributes()) @@ -152,62 +158,67 @@ Fingering parseFingering(pugi::xml_node el) } if (aname == "substitution") { - out.setSubstitution(YesNo::parse(a.value())); + out.setSubstitution(parseValue(a.value(), context, el, "substitution")); } else if (aname == "alternate") { - out.setAlternate(YesNo::parse(a.value())); + out.setAlternate(parseValue(a.value(), context, el, "alternate")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else { throwUnknownAttribute(el, a.name()); } } - parseFingeringContent(out, el); + parseFingeringContent(out, el, context); return out; } void parseFingeringContent(Fingering &out, pugi::xml_node el) +{ + parseFingeringContent(out, el, ParseContext{}); +} + +void parseFingeringContent(Fingering &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/Fingering.h b/src/private/mx/core/generated/Fingering.h index 3ddac33e8..d31bac000 100644 --- a/src/private/mx/core/generated/Fingering.h +++ b/src/private/mx/core/generated/Fingering.h @@ -22,6 +22,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Fingering is typically indicated 1,2,3,4,5. Multiple fingerings may be given, typically to /// substitute fingerings in the middle of a note. The substitution and alternate values are "no" if /// the attribute is not present. For guitar and other fretted instruments, the fingering element @@ -75,8 +77,12 @@ class Fingering final Fingering parseFingering(pugi::xml_node el); +Fingering parseFingering(pugi::xml_node el, const ParseContext &context); + void parseFingeringContent(Fingering &out, pugi::xml_node el); +void parseFingeringContent(Fingering &out, pugi::xml_node el, const ParseContext &context); + void serializeFingering(const Fingering &v, pugi::xml_node parent, const char *tag); void serializeFingeringContent(const Fingering &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/FirstFret.cpp b/src/private/mx/core/generated/FirstFret.cpp index 0963321ca..da4c9a2ef 100644 --- a/src/private/mx/core/generated/FirstFret.cpp +++ b/src/private/mx/core/generated/FirstFret.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/FirstFret.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,6 +42,11 @@ void FirstFret::setValue(int value) } FirstFret parseFirstFret(pugi::xml_node el) +{ + return parseFirstFret(el, ParseContext{}); +} + +FirstFret parseFirstFret(pugi::xml_node el, const ParseContext &context) { FirstFret out; for (pugi::xml_attribute a : el.attributes()) @@ -56,20 +62,25 @@ FirstFret parseFirstFret(pugi::xml_node el) } else if (aname == "location") { - out.setLocation(LeftRight::parse(a.value())); + out.setLocation(parseValue(a.value(), context, el, "location")); } else { throwUnknownAttribute(el, a.name()); } } - parseFirstFretContent(out, el); + parseFirstFretContent(out, el, context); return out; } void parseFirstFretContent(FirstFret &out, pugi::xml_node el) { - out.setValue(parseInt(childText(el))); + parseFirstFretContent(out, el, ParseContext{}); +} + +void parseFirstFretContent(FirstFret &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseIntegerValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/FirstFret.h b/src/private/mx/core/generated/FirstFret.h index 321351d2d..b9b2867ab 100644 --- a/src/private/mx/core/generated/FirstFret.h +++ b/src/private/mx/core/generated/FirstFret.h @@ -15,6 +15,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The first-fret type indicates which fret is shown in the top space of the frame; it is fret 1 if /// the element is not present. The optional text attribute indicates how this is represented in the /// fret diagram, while the location attribute indicates whether the text appears to the left or @@ -38,8 +40,12 @@ class FirstFret final FirstFret parseFirstFret(pugi::xml_node el); +FirstFret parseFirstFret(pugi::xml_node el, const ParseContext &context); + void parseFirstFretContent(FirstFret &out, pugi::xml_node el); +void parseFirstFretContent(FirstFret &out, pugi::xml_node el, const ParseContext &context); + void serializeFirstFret(const FirstFret &v, pugi::xml_node parent, const char *tag); void serializeFirstFretContent(const FirstFret &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/FontSize.cpp b/src/private/mx/core/generated/FontSize.cpp index 0630465ad..c28f24e26 100644 --- a/src/private/mx/core/generated/FontSize.cpp +++ b/src/private/mx/core/generated/FontSize.cpp @@ -59,12 +59,20 @@ bool FontSize::tryParse(std::string_view text, FontSize &out) } FontSize FontSize::parse(std::string_view text) +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +FontSize FontSize::parse(std::string_view text, ValueParseOutcome &outcome) { FontSize out; if (tryParse(text, out)) { + outcome = ValueParseOutcome::valid; return out; } + outcome = ValueParseOutcome::invalid; return FontSize::decimal(Decimal::parse(text)); } diff --git a/src/private/mx/core/generated/FontSize.h b/src/private/mx/core/generated/FontSize.h index 7a90cdabb..4784d8924 100644 --- a/src/private/mx/core/generated/FontSize.h +++ b/src/private/mx/core/generated/FontSize.h @@ -3,6 +3,7 @@ #pragma once #include "mx/core/Decimal.h" +#include "mx/core/Lexical.h" #include "mx/core/generated/CSSFontSize.h" #include @@ -70,6 +71,10 @@ class FontSize final /// parse (never produces an invalid value). static FontSize parse(std::string_view text); + /// Lenient, and says whether no member matched or a matched number was + /// clamped. + static FontSize parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const FontSize &other) const = default; private: diff --git a/src/private/mx/core/generated/FontStyle.cpp b/src/private/mx/core/generated/FontStyle.cpp index 807a94f3c..dd79ef948 100644 --- a/src/private/mx/core/generated/FontStyle.cpp +++ b/src/private/mx/core/generated/FontStyle.cpp @@ -42,9 +42,15 @@ bool FontStyle::tryParse(std::string_view text, FontStyle &out) noexcept } FontStyle FontStyle::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +FontStyle FontStyle::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { FontStyle v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/FontStyle.h b/src/private/mx/core/generated/FontStyle.h index a40d9263f..b41c91066 100644 --- a/src/private/mx/core/generated/FontStyle.h +++ b/src/private/mx/core/generated/FontStyle.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -40,6 +42,9 @@ class FontStyle final /// (the import leniency policy; never produces an invalid value). static FontStyle parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static FontStyle parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const FontStyle &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/FontWeight.cpp b/src/private/mx/core/generated/FontWeight.cpp index 7494bbbe7..1521c9fb7 100644 --- a/src/private/mx/core/generated/FontWeight.cpp +++ b/src/private/mx/core/generated/FontWeight.cpp @@ -42,9 +42,15 @@ bool FontWeight::tryParse(std::string_view text, FontWeight &out) noexcept } FontWeight FontWeight::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +FontWeight FontWeight::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { FontWeight v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/FontWeight.h b/src/private/mx/core/generated/FontWeight.h index bfcd14f23..4abee5846 100644 --- a/src/private/mx/core/generated/FontWeight.h +++ b/src/private/mx/core/generated/FontWeight.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -40,6 +42,9 @@ class FontWeight final /// (the import leniency policy; never produces an invalid value). static FontWeight parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static FontWeight parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const FontWeight &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/ForPart.cpp b/src/private/mx/core/generated/ForPart.cpp index 51211180f..40bb4b7a2 100644 --- a/src/private/mx/core/generated/ForPart.cpp +++ b/src/private/mx/core/generated/ForPart.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/ForPart.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -51,6 +52,11 @@ void ForPart::setPartTranspose(PartTranspose value) } ForPart parseForPart(pugi::xml_node el) +{ + return parseForPart(el, ParseContext{}); +} + +ForPart parseForPart(pugi::xml_node el, const ParseContext &context) { ForPart out; for (pugi::xml_attribute a : el.attributes()) @@ -62,7 +68,7 @@ ForPart parseForPart(pugi::xml_node el) } if (aname == "number") { - out.setNumber(StaffNumber::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else if (aname == "id") { @@ -73,21 +79,26 @@ ForPart parseForPart(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseForPartContent(out, el); + parseForPartContent(out, el, context); return out; } void parseForPartContent(ForPart &out, pugi::xml_node el) +{ + parseForPartContent(out, el, ParseContext{}); +} + +void parseForPartContent(ForPart &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "part-clef")) { - out.setPartClef(parsePartClef(cursor)); + out.setPartClef(parsePartClef(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "part-transpose")) { - out.setPartTranspose(parsePartTranspose(cursor)); + out.setPartTranspose(parsePartTranspose(cursor, context)); cursor = nextElement(cursor); } else diff --git a/src/private/mx/core/generated/ForPart.h b/src/private/mx/core/generated/ForPart.h index 8f0292633..4f3089676 100644 --- a/src/private/mx/core/generated/ForPart.h +++ b/src/private/mx/core/generated/ForPart.h @@ -21,6 +21,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The for-part type is used in a concert score to indicate the transposition for a transposed part /// created from that score. It is only used in score files that contain a concert-score element in /// the defaults. This allows concert scores with transposed parts to be represented in a single @@ -50,8 +52,12 @@ class ForPart final ForPart parseForPart(pugi::xml_node el); +ForPart parseForPart(pugi::xml_node el, const ParseContext &context); + void parseForPartContent(ForPart &out, pugi::xml_node el); +void parseForPartContent(ForPart &out, pugi::xml_node el, const ParseContext &context); + void serializeForPart(const ForPart &v, pugi::xml_node parent, const char *tag); void serializeForPartContent(const ForPart &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/FormattedSymbolID.cpp b/src/private/mx/core/generated/FormattedSymbolID.cpp index d61544871..4f58b76e4 100644 --- a/src/private/mx/core/generated/FormattedSymbolID.cpp +++ b/src/private/mx/core/generated/FormattedSymbolID.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/FormattedSymbolID.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -231,6 +232,11 @@ void FormattedSymbolID::setValue(SmuflGlyphName value) } FormattedSymbolID parseFormattedSymbolID(pugi::xml_node el) +{ + return parseFormattedSymbolID(el, ParseContext{}); +} + +FormattedSymbolID parseFormattedSymbolID(pugi::xml_node el, const ParseContext &context) { FormattedSymbolID out; for (pugi::xml_attribute a : el.attributes()) @@ -242,83 +248,83 @@ FormattedSymbolID parseFormattedSymbolID(pugi::xml_node el) } if (aname == "justify") { - out.setJustify(LeftCenterRight::parse(a.value())); + out.setJustify(parseValue(a.value(), context, el, "justify")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "halign") { - out.setHalign(LeftCenterRight::parse(a.value())); + out.setHalign(parseValue(a.value(), context, el, "halign")); } else if (aname == "valign") { - out.setValign(Valign::parse(a.value())); + out.setValign(parseValue(a.value(), context, el, "valign")); } else if (aname == "underline") { - out.setUnderline(NumberOfLines::parse(a.value())); + out.setUnderline(parseValue(a.value(), context, el, "underline")); } else if (aname == "overline") { - out.setOverline(NumberOfLines::parse(a.value())); + out.setOverline(parseValue(a.value(), context, el, "overline")); } else if (aname == "line-through") { - out.setLineThrough(NumberOfLines::parse(a.value())); + out.setLineThrough(parseValue(a.value(), context, el, "line-through")); } else if (aname == "rotation") { - out.setRotation(RotationDegrees::parse(a.value())); + out.setRotation(parseValue(a.value(), context, el, "rotation")); } else if (aname == "letter-spacing") { - out.setLetterSpacing(NumberOrNormal::parse(a.value())); + out.setLetterSpacing(parseValue(a.value(), context, el, "letter-spacing")); } else if (aname == "line-height") { - out.setLineHeight(NumberOrNormal::parse(a.value())); + out.setLineHeight(parseValue(a.value(), context, el, "line-height")); } else if (aname == "dir") { - out.setDir(TextDirection::parse(a.value())); + out.setDir(parseValue(a.value(), context, el, "dir")); } else if (aname == "enclosure") { - out.setEnclosure(EnclosureShape::parse(a.value())); + out.setEnclosure(parseValue(a.value(), context, el, "enclosure")); } else if (aname == "id") { @@ -329,13 +335,18 @@ FormattedSymbolID parseFormattedSymbolID(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseFormattedSymbolIDContent(out, el); + parseFormattedSymbolIDContent(out, el, context); return out; } void parseFormattedSymbolIDContent(FormattedSymbolID &out, pugi::xml_node el) { - out.setValue(SmuflGlyphName::parse(childText(el))); + parseFormattedSymbolIDContent(out, el, ParseContext{}); +} + +void parseFormattedSymbolIDContent(FormattedSymbolID &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/FormattedSymbolID.h b/src/private/mx/core/generated/FormattedSymbolID.h index c38a99fe4..5e55f4bbc 100644 --- a/src/private/mx/core/generated/FormattedSymbolID.h +++ b/src/private/mx/core/generated/FormattedSymbolID.h @@ -30,6 +30,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The formatted-symbol-id type represents a SMuFL musical symbol element with formatting and id /// attributes. class FormattedSymbolID final @@ -108,8 +110,12 @@ class FormattedSymbolID final FormattedSymbolID parseFormattedSymbolID(pugi::xml_node el); +FormattedSymbolID parseFormattedSymbolID(pugi::xml_node el, const ParseContext &context); + void parseFormattedSymbolIDContent(FormattedSymbolID &out, pugi::xml_node el); +void parseFormattedSymbolIDContent(FormattedSymbolID &out, pugi::xml_node el, const ParseContext &context); + void serializeFormattedSymbolID(const FormattedSymbolID &v, pugi::xml_node parent, const char *tag); void serializeFormattedSymbolIDContent(const FormattedSymbolID &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/FormattedText.cpp b/src/private/mx/core/generated/FormattedText.cpp index 99fa081dc..0bcda494f 100644 --- a/src/private/mx/core/generated/FormattedText.cpp +++ b/src/private/mx/core/generated/FormattedText.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/FormattedText.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -241,6 +242,11 @@ void FormattedText::setValue(std::string value) } FormattedText parseFormattedText(pugi::xml_node el) +{ + return parseFormattedText(el, ParseContext{}); +} + +FormattedText parseFormattedText(pugi::xml_node el, const ParseContext &context) { FormattedText out; for (pugi::xml_attribute a : el.attributes()) @@ -260,94 +266,99 @@ FormattedText parseFormattedText(pugi::xml_node el) } else if (aname == "justify") { - out.setJustify(LeftCenterRight::parse(a.value())); + out.setJustify(parseValue(a.value(), context, el, "justify")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "halign") { - out.setHalign(LeftCenterRight::parse(a.value())); + out.setHalign(parseValue(a.value(), context, el, "halign")); } else if (aname == "valign") { - out.setValign(Valign::parse(a.value())); + out.setValign(parseValue(a.value(), context, el, "valign")); } else if (aname == "underline") { - out.setUnderline(NumberOfLines::parse(a.value())); + out.setUnderline(parseValue(a.value(), context, el, "underline")); } else if (aname == "overline") { - out.setOverline(NumberOfLines::parse(a.value())); + out.setOverline(parseValue(a.value(), context, el, "overline")); } else if (aname == "line-through") { - out.setLineThrough(NumberOfLines::parse(a.value())); + out.setLineThrough(parseValue(a.value(), context, el, "line-through")); } else if (aname == "rotation") { - out.setRotation(RotationDegrees::parse(a.value())); + out.setRotation(parseValue(a.value(), context, el, "rotation")); } else if (aname == "letter-spacing") { - out.setLetterSpacing(NumberOrNormal::parse(a.value())); + out.setLetterSpacing(parseValue(a.value(), context, el, "letter-spacing")); } else if (aname == "line-height") { - out.setLineHeight(NumberOrNormal::parse(a.value())); + out.setLineHeight(parseValue(a.value(), context, el, "line-height")); } else if (aname == "dir") { - out.setDir(TextDirection::parse(a.value())); + out.setDir(parseValue(a.value(), context, el, "dir")); } else if (aname == "enclosure") { - out.setEnclosure(EnclosureShape::parse(a.value())); + out.setEnclosure(parseValue(a.value(), context, el, "enclosure")); } else { throwUnknownAttribute(el, a.name()); } } - parseFormattedTextContent(out, el); + parseFormattedTextContent(out, el, context); return out; } void parseFormattedTextContent(FormattedText &out, pugi::xml_node el) +{ + parseFormattedTextContent(out, el, ParseContext{}); +} + +void parseFormattedTextContent(FormattedText &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/FormattedText.h b/src/private/mx/core/generated/FormattedText.h index 04905e01c..0a1205215 100644 --- a/src/private/mx/core/generated/FormattedText.h +++ b/src/private/mx/core/generated/FormattedText.h @@ -27,6 +27,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The formatted-text type represents a text element with text-formatting attributes. class FormattedText final { @@ -107,8 +109,12 @@ class FormattedText final FormattedText parseFormattedText(pugi::xml_node el); +FormattedText parseFormattedText(pugi::xml_node el, const ParseContext &context); + void parseFormattedTextContent(FormattedText &out, pugi::xml_node el); +void parseFormattedTextContent(FormattedText &out, pugi::xml_node el, const ParseContext &context); + void serializeFormattedText(const FormattedText &v, pugi::xml_node parent, const char *tag); void serializeFormattedTextContent(const FormattedText &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/FormattedTextID.cpp b/src/private/mx/core/generated/FormattedTextID.cpp index 82efb5156..1cf81365f 100644 --- a/src/private/mx/core/generated/FormattedTextID.cpp +++ b/src/private/mx/core/generated/FormattedTextID.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/FormattedTextID.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -251,6 +252,11 @@ void FormattedTextID::setValue(std::string value) } FormattedTextID parseFormattedTextID(pugi::xml_node el) +{ + return parseFormattedTextID(el, ParseContext{}); +} + +FormattedTextID parseFormattedTextID(pugi::xml_node el, const ParseContext &context) { FormattedTextID out; for (pugi::xml_attribute a : el.attributes()) @@ -270,83 +276,83 @@ FormattedTextID parseFormattedTextID(pugi::xml_node el) } else if (aname == "justify") { - out.setJustify(LeftCenterRight::parse(a.value())); + out.setJustify(parseValue(a.value(), context, el, "justify")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "halign") { - out.setHalign(LeftCenterRight::parse(a.value())); + out.setHalign(parseValue(a.value(), context, el, "halign")); } else if (aname == "valign") { - out.setValign(Valign::parse(a.value())); + out.setValign(parseValue(a.value(), context, el, "valign")); } else if (aname == "underline") { - out.setUnderline(NumberOfLines::parse(a.value())); + out.setUnderline(parseValue(a.value(), context, el, "underline")); } else if (aname == "overline") { - out.setOverline(NumberOfLines::parse(a.value())); + out.setOverline(parseValue(a.value(), context, el, "overline")); } else if (aname == "line-through") { - out.setLineThrough(NumberOfLines::parse(a.value())); + out.setLineThrough(parseValue(a.value(), context, el, "line-through")); } else if (aname == "rotation") { - out.setRotation(RotationDegrees::parse(a.value())); + out.setRotation(parseValue(a.value(), context, el, "rotation")); } else if (aname == "letter-spacing") { - out.setLetterSpacing(NumberOrNormal::parse(a.value())); + out.setLetterSpacing(parseValue(a.value(), context, el, "letter-spacing")); } else if (aname == "line-height") { - out.setLineHeight(NumberOrNormal::parse(a.value())); + out.setLineHeight(parseValue(a.value(), context, el, "line-height")); } else if (aname == "dir") { - out.setDir(TextDirection::parse(a.value())); + out.setDir(parseValue(a.value(), context, el, "dir")); } else if (aname == "enclosure") { - out.setEnclosure(EnclosureShape::parse(a.value())); + out.setEnclosure(parseValue(a.value(), context, el, "enclosure")); } else if (aname == "id") { @@ -357,11 +363,16 @@ FormattedTextID parseFormattedTextID(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseFormattedTextIDContent(out, el); + parseFormattedTextIDContent(out, el, context); return out; } void parseFormattedTextIDContent(FormattedTextID &out, pugi::xml_node el) +{ + parseFormattedTextIDContent(out, el, ParseContext{}); +} + +void parseFormattedTextIDContent(FormattedTextID &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/FormattedTextID.h b/src/private/mx/core/generated/FormattedTextID.h index efc1d2926..89d396fe3 100644 --- a/src/private/mx/core/generated/FormattedTextID.h +++ b/src/private/mx/core/generated/FormattedTextID.h @@ -29,6 +29,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The formatted-text-id type represents a text element with text-formatting and id attributes. class FormattedTextID final { @@ -112,8 +114,12 @@ class FormattedTextID final FormattedTextID parseFormattedTextID(pugi::xml_node el); +FormattedTextID parseFormattedTextID(pugi::xml_node el, const ParseContext &context); + void parseFormattedTextIDContent(FormattedTextID &out, pugi::xml_node el); +void parseFormattedTextIDContent(FormattedTextID &out, pugi::xml_node el, const ParseContext &context); + void serializeFormattedTextID(const FormattedTextID &v, pugi::xml_node parent, const char *tag); void serializeFormattedTextIDContent(const FormattedTextID &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Forward.cpp b/src/private/mx/core/generated/Forward.cpp index 8d1f1f07e..741c4746c 100644 --- a/src/private/mx/core/generated/Forward.cpp +++ b/src/private/mx/core/generated/Forward.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Forward.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,6 +42,11 @@ void Forward::setStaff(std::optional value) } Forward parseForward(pugi::xml_node el) +{ + return parseForward(el, ParseContext{}); +} + +Forward parseForward(pugi::xml_node el, const ParseContext &context) { Forward out; for (pugi::xml_attribute a : el.attributes()) @@ -52,16 +58,21 @@ Forward parseForward(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseForwardContent(out, el); + parseForwardContent(out, el, context); return out; } void parseForwardContent(Forward &out, pugi::xml_node el) +{ + parseForwardContent(out, el, ParseContext{}); +} + +void parseForwardContent(Forward &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "duration")) { - out.setDuration(PositiveDivisions::parse(childText(cursor))); + out.setDuration(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -70,11 +81,11 @@ void parseForwardContent(Forward &out, pugi::xml_node el) } if (cursor && (cursorIs(cursor, "footnote") || cursorIs(cursor, "level") || cursorIs(cursor, "voice"))) { - out.setEditorialVoice(parseEditorialVoiceGroup(el, cursor)); + out.setEditorialVoice(parseEditorialVoiceGroup(el, cursor, context)); } if (cursorIs(cursor, "staff")) { - out.setStaff(parseInt(childText(cursor))); + out.setStaff(parseIntegerValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/Forward.h b/src/private/mx/core/generated/Forward.h index fc2684157..a46fea183 100644 --- a/src/private/mx/core/generated/Forward.h +++ b/src/private/mx/core/generated/Forward.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The backup and forward elements are required to coordinate multiple voices in one part, including /// music on multiple staves. The forward element is generally used within voices and staves. /// Duration values should always be positive, and should not cross measure boundaries or mid-measure @@ -43,8 +45,12 @@ class Forward final Forward parseForward(pugi::xml_node el); +Forward parseForward(pugi::xml_node el, const ParseContext &context); + void parseForwardContent(Forward &out, pugi::xml_node el); +void parseForwardContent(Forward &out, pugi::xml_node el, const ParseContext &context); + void serializeForward(const Forward &v, pugi::xml_node parent, const char *tag); void serializeForwardContent(const Forward &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Frame.cpp b/src/private/mx/core/generated/Frame.cpp index 7a82f9323..9a39955fe 100644 --- a/src/private/mx/core/generated/Frame.cpp +++ b/src/private/mx/core/generated/Frame.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Frame.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -166,6 +167,11 @@ void Frame::setFrameNote(OneOrMore value) } Frame parseFrame(pugi::xml_node el) +{ + return parseFrame(el, ParseContext{}); +} + +Frame parseFrame(pugi::xml_node el, const ParseContext &context) { Frame out; for (pugi::xml_attribute a : el.attributes()) @@ -177,11 +183,11 @@ Frame parseFrame(pugi::xml_node el) } if (aname == "height") { - out.setHeight(Tenths::parse(a.value())); + out.setHeight(parseValue(a.value(), context, el, "height")); } else if (aname == "width") { - out.setWidth(Tenths::parse(a.value())); + out.setWidth(parseValue(a.value(), context, el, "width")); } else if (aname == "unplayed") { @@ -189,31 +195,31 @@ Frame parseFrame(pugi::xml_node el) } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "halign") { - out.setHalign(LeftCenterRight::parse(a.value())); + out.setHalign(parseValue(a.value(), context, el, "halign")); } else if (aname == "valign") { - out.setValign(ValignImage::parse(a.value())); + out.setValign(parseValue(a.value(), context, el, "valign")); } else if (aname == "id") { @@ -224,16 +230,21 @@ Frame parseFrame(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseFrameContent(out, el); + parseFrameContent(out, el, context); return out; } void parseFrameContent(Frame &out, pugi::xml_node el) +{ + parseFrameContent(out, el, ParseContext{}); +} + +void parseFrameContent(Frame &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "frame-strings")) { - out.setFrameStrings(parseInt(childText(cursor))); + out.setFrameStrings(parseIntegerValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -242,7 +253,7 @@ void parseFrameContent(Frame &out, pugi::xml_node el) } if (cursorIs(cursor, "frame-frets")) { - out.setFrameFrets(parseInt(childText(cursor))); + out.setFrameFrets(parseIntegerValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -251,18 +262,18 @@ void parseFrameContent(Frame &out, pugi::xml_node el) } if (cursorIs(cursor, "first-fret")) { - out.setFirstFret(parseFirstFret(cursor)); + out.setFirstFret(parseFirstFret(cursor, context)); cursor = nextElement(cursor); } if (!cursorIs(cursor, "frame-note")) { throwMissingOrMisplaced(el, cursor, "frame-note"); } - out.setFrameNote(OneOrMore{parseFrameNote(cursor)}); + out.setFrameNote(OneOrMore{parseFrameNote(cursor, context)}); cursor = nextElement(cursor); while (cursorIs(cursor, "frame-note")) { - out.addFrameNote(parseFrameNote(cursor)); + out.addFrameNote(parseFrameNote(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/Frame.h b/src/private/mx/core/generated/Frame.h index 61c2daa33..8a6d27419 100644 --- a/src/private/mx/core/generated/Frame.h +++ b/src/private/mx/core/generated/Frame.h @@ -25,6 +25,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The frame type represents a frame or fretboard diagram used together with a chord symbol. The /// representation is based on the NIFF guitar grid with additional information. The frame type's /// unplayed attribute indicates what to display above a string that has no associated frame-note @@ -88,8 +90,12 @@ class Frame final Frame parseFrame(pugi::xml_node el); +Frame parseFrame(pugi::xml_node el, const ParseContext &context); + void parseFrameContent(Frame &out, pugi::xml_node el); +void parseFrameContent(Frame &out, pugi::xml_node el, const ParseContext &context); + void serializeFrame(const Frame &v, pugi::xml_node parent, const char *tag); void serializeFrameContent(const Frame &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/FrameNote.cpp b/src/private/mx/core/generated/FrameNote.cpp index 96c1a1c08..34ad9bd03 100644 --- a/src/private/mx/core/generated/FrameNote.cpp +++ b/src/private/mx/core/generated/FrameNote.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/FrameNote.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -51,6 +52,11 @@ void FrameNote::setBarre(std::optional value) } FrameNote parseFrameNote(pugi::xml_node el) +{ + return parseFrameNote(el, ParseContext{}); +} + +FrameNote parseFrameNote(pugi::xml_node el, const ParseContext &context) { FrameNote out; for (pugi::xml_attribute a : el.attributes()) @@ -62,16 +68,21 @@ FrameNote parseFrameNote(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseFrameNoteContent(out, el); + parseFrameNoteContent(out, el, context); return out; } void parseFrameNoteContent(FrameNote &out, pugi::xml_node el) +{ + parseFrameNoteContent(out, el, ParseContext{}); +} + +void parseFrameNoteContent(FrameNote &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "string")) { - out.setString(parseString(cursor)); + out.setString(parseString(cursor, context)); cursor = nextElement(cursor); } else @@ -80,7 +91,7 @@ void parseFrameNoteContent(FrameNote &out, pugi::xml_node el) } if (cursorIs(cursor, "fret")) { - out.setFret(parseFret(cursor)); + out.setFret(parseFret(cursor, context)); cursor = nextElement(cursor); } else @@ -89,12 +100,12 @@ void parseFrameNoteContent(FrameNote &out, pugi::xml_node el) } if (cursorIs(cursor, "fingering")) { - out.setFingering(parseFingering(cursor)); + out.setFingering(parseFingering(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "barre")) { - out.setBarre(parseBarre(cursor)); + out.setBarre(parseBarre(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/FrameNote.h b/src/private/mx/core/generated/FrameNote.h index 7bc0191a4..9d44f6ef5 100644 --- a/src/private/mx/core/generated/FrameNote.h +++ b/src/private/mx/core/generated/FrameNote.h @@ -20,6 +20,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The frame-note type represents each note included in the frame. An open string will have a fret /// value of 0, while a muted string will not be associated with a frame-note element. /// Content fields mirror the schema grammar in declaration order; the @@ -46,8 +48,12 @@ class FrameNote final FrameNote parseFrameNote(pugi::xml_node el); +FrameNote parseFrameNote(pugi::xml_node el, const ParseContext &context); + void parseFrameNoteContent(FrameNote &out, pugi::xml_node el); +void parseFrameNoteContent(FrameNote &out, pugi::xml_node el, const ParseContext &context); + void serializeFrameNote(const FrameNote &v, pugi::xml_node parent, const char *tag); void serializeFrameNoteContent(const FrameNote &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Fret.cpp b/src/private/mx/core/generated/Fret.cpp index a68173f94..87f9d605e 100644 --- a/src/private/mx/core/generated/Fret.cpp +++ b/src/private/mx/core/generated/Fret.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Fret.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -71,6 +72,11 @@ void Fret::setValue(int value) } Fret parseFret(pugi::xml_node el) +{ + return parseFret(el, ParseContext{}); +} + +Fret parseFret(pugi::xml_node el, const ParseContext &context) { Fret out; for (pugi::xml_attribute a : el.attributes()) @@ -82,36 +88,41 @@ Fret parseFret(pugi::xml_node el) } if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else { throwUnknownAttribute(el, a.name()); } } - parseFretContent(out, el); + parseFretContent(out, el, context); return out; } void parseFretContent(Fret &out, pugi::xml_node el) { - out.setValue(parseInt(childText(el))); + parseFretContent(out, el, ParseContext{}); +} + +void parseFretContent(Fret &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseIntegerValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Fret.h b/src/private/mx/core/generated/Fret.h index 002176cbb..e5dbee518 100644 --- a/src/private/mx/core/generated/Fret.h +++ b/src/private/mx/core/generated/Fret.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The fret element is used with tablature notation and chord diagrams. Fret numbers start with 0 /// for an open string and 1 for the first fret. class Fret final @@ -49,8 +51,12 @@ class Fret final Fret parseFret(pugi::xml_node el); +Fret parseFret(pugi::xml_node el, const ParseContext &context); + void parseFretContent(Fret &out, pugi::xml_node el); +void parseFretContent(Fret &out, pugi::xml_node el, const ParseContext &context); + void serializeFret(const Fret &v, pugi::xml_node parent, const char *tag); void serializeFretContent(const Fret &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/FullNoteGroup.cpp b/src/private/mx/core/generated/FullNoteGroup.cpp index 0fe1b5681..4dd59f444 100644 --- a/src/private/mx/core/generated/FullNoteGroup.cpp +++ b/src/private/mx/core/generated/FullNoteGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/FullNoteGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,17 +32,22 @@ void FullNoteGroup::setChoice(FullNoteGroupChoice value) } FullNoteGroup parseFullNoteGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseFullNoteGroup(el, cursor, ParseContext{}); +} + +FullNoteGroup parseFullNoteGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { FullNoteGroup out; if (cursorIs(cursor, "chord")) { - parseEmpty(cursor); + parseEmpty(cursor, context); out.setChord(true); cursor = nextElement(cursor); } if (cursor && (cursorIs(cursor, "pitch") || cursorIs(cursor, "unpitched") || cursorIs(cursor, "rest"))) { - out.setChoice(parseFullNoteGroupChoice(el, cursor)); + out.setChoice(parseFullNoteGroupChoice(el, cursor, context)); } else { diff --git a/src/private/mx/core/generated/FullNoteGroup.h b/src/private/mx/core/generated/FullNoteGroup.h index e350ba824..54930541d 100644 --- a/src/private/mx/core/generated/FullNoteGroup.h +++ b/src/private/mx/core/generated/FullNoteGroup.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The full-note group is a sequence of the common note elements between cue/grace notes and regular /// (full) notes: pitch, chord, and rest information, but not duration (cue and grace notes do not /// have duration encoded). Unpitched elements are used for unpitched percussion, speaking voice, and @@ -42,6 +44,8 @@ class FullNoteGroup final /// is the enclosing element, for error paths. FullNoteGroup parseFullNoteGroup(pugi::xml_node el, pugi::xml_node &cursor); +FullNoteGroup parseFullNoteGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeFullNoteGroup(const FullNoteGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/FullNoteGroupChoice.cpp b/src/private/mx/core/generated/FullNoteGroupChoice.cpp index ae1b84705..1e56c25f6 100644 --- a/src/private/mx/core/generated/FullNoteGroupChoice.cpp +++ b/src/private/mx/core/generated/FullNoteGroupChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/FullNoteGroupChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,22 +32,27 @@ FullNoteGroupChoice FullNoteGroupChoice::rest(Rest value) } FullNoteGroupChoice parseFullNoteGroupChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseFullNoteGroupChoice(el, cursor, ParseContext{}); +} + +FullNoteGroupChoice parseFullNoteGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "pitch"))) { - Pitch value = parsePitch(cursor); + Pitch value = parsePitch(cursor, context); cursor = nextElement(cursor); return FullNoteGroupChoice::pitch(std::move(value)); } if (cursor && (cursorIs(cursor, "unpitched"))) { - Unpitched value = parseUnpitched(cursor); + Unpitched value = parseUnpitched(cursor, context); cursor = nextElement(cursor); return FullNoteGroupChoice::unpitched(std::move(value)); } if (cursor && (cursorIs(cursor, "rest"))) { - Rest value = parseRest(cursor); + Rest value = parseRest(cursor, context); cursor = nextElement(cursor); return FullNoteGroupChoice::rest(std::move(value)); } diff --git a/src/private/mx/core/generated/FullNoteGroupChoice.h b/src/private/mx/core/generated/FullNoteGroupChoice.h index 1c9a110b4..d447a28d2 100644 --- a/src/private/mx/core/generated/FullNoteGroupChoice.h +++ b/src/private/mx/core/generated/FullNoteGroupChoice.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -97,6 +99,8 @@ class FullNoteGroupChoice final /// the enclosing element, for error paths. FullNoteGroupChoice parseFullNoteGroupChoice(pugi::xml_node el, pugi::xml_node &cursor); +FullNoteGroupChoice parseFullNoteGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeFullNoteGroupChoice(const FullNoteGroupChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/Glass.cpp b/src/private/mx/core/generated/Glass.cpp index dede2fbd7..4e242f436 100644 --- a/src/private/mx/core/generated/Glass.cpp +++ b/src/private/mx/core/generated/Glass.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Glass.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void Glass::setValue(GlassValue value) } Glass parseGlass(pugi::xml_node el) +{ + return parseGlass(el, ParseContext{}); +} + +Glass parseGlass(pugi::xml_node el, const ParseContext &context) { Glass out; for (pugi::xml_attribute a : el.attributes()) @@ -42,20 +48,25 @@ Glass parseGlass(pugi::xml_node el) } if (aname == "smufl") { - out.setSmufl(SmuflPictogramGlyphName::parse(a.value())); + out.setSmufl(parseValue(a.value(), context, el, "smufl")); } else { throwUnknownAttribute(el, a.name()); } } - parseGlassContent(out, el); + parseGlassContent(out, el, context); return out; } void parseGlassContent(Glass &out, pugi::xml_node el) { - out.setValue(GlassValue::parse(childText(el))); + parseGlassContent(out, el, ParseContext{}); +} + +void parseGlassContent(Glass &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Glass.h b/src/private/mx/core/generated/Glass.h index 70999b28f..0681c8c9e 100644 --- a/src/private/mx/core/generated/Glass.h +++ b/src/private/mx/core/generated/Glass.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The glass type represents pictograms for glass percussion instruments. The smufl attribute is /// used to distinguish different SMuFL glyphs for wind chimes in the Chimes pictograms range, /// including those made of materials other than glass. @@ -35,8 +37,12 @@ class Glass final Glass parseGlass(pugi::xml_node el); +Glass parseGlass(pugi::xml_node el, const ParseContext &context); + void parseGlassContent(Glass &out, pugi::xml_node el); +void parseGlassContent(Glass &out, pugi::xml_node el, const ParseContext &context); + void serializeGlass(const Glass &v, pugi::xml_node parent, const char *tag); void serializeGlassContent(const Glass &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/GlassValue.cpp b/src/private/mx/core/generated/GlassValue.cpp index 766e25ab6..540946d72 100644 --- a/src/private/mx/core/generated/GlassValue.cpp +++ b/src/private/mx/core/generated/GlassValue.cpp @@ -48,9 +48,15 @@ bool GlassValue::tryParse(std::string_view text, GlassValue &out) noexcept } GlassValue GlassValue::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +GlassValue GlassValue::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { GlassValue v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/GlassValue.h b/src/private/mx/core/generated/GlassValue.h index a5159252e..52453dfb2 100644 --- a/src/private/mx/core/generated/GlassValue.h +++ b/src/private/mx/core/generated/GlassValue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -42,6 +44,9 @@ class GlassValue final /// (the import leniency policy; never produces an invalid value). static GlassValue parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static GlassValue parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const GlassValue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Glissando.cpp b/src/private/mx/core/generated/Glissando.cpp index 820050166..0c0ca1e65 100644 --- a/src/private/mx/core/generated/Glissando.cpp +++ b/src/private/mx/core/generated/Glissando.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Glissando.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -171,6 +172,11 @@ void Glissando::setValue(std::string value) } Glissando parseGlissando(pugi::xml_node el) +{ + return parseGlissando(el, ParseContext{}); +} + +Glissando parseGlissando(pugi::xml_node el, const ParseContext &context) { Glissando out; bool seen_type = false; @@ -184,59 +190,59 @@ Glissando parseGlissando(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(StartStop::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "number") { - out.setNumber(NumberLevel::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else if (aname == "line-type") { - out.setLineType(LineType::parse(a.value())); + out.setLineType(parseValue(a.value(), context, el, "line-type")); } else if (aname == "dash-length") { - out.setDashLength(Tenths::parse(a.value())); + out.setDashLength(parseValue(a.value(), context, el, "dash-length")); } else if (aname == "space-length") { - out.setSpaceLength(Tenths::parse(a.value())); + out.setSpaceLength(parseValue(a.value(), context, el, "space-length")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "id") { @@ -251,11 +257,16 @@ Glissando parseGlissando(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseGlissandoContent(out, el); + parseGlissandoContent(out, el, context); return out; } void parseGlissandoContent(Glissando &out, pugi::xml_node el) +{ + parseGlissandoContent(out, el, ParseContext{}); +} + +void parseGlissandoContent(Glissando &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/Glissando.h b/src/private/mx/core/generated/Glissando.h index 99bf6398e..46e57e251 100644 --- a/src/private/mx/core/generated/Glissando.h +++ b/src/private/mx/core/generated/Glissando.h @@ -25,6 +25,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Glissando and slide types both indicate rapidly moving from one pitch to the other so that /// individual notes are not discerned. A glissando sounds the distinct notes in between the two /// pitches and defaults to a wavy line. The optional text is printed alongside the line. @@ -86,8 +88,12 @@ class Glissando final Glissando parseGlissando(pugi::xml_node el); +Glissando parseGlissando(pugi::xml_node el, const ParseContext &context); + void parseGlissandoContent(Glissando &out, pugi::xml_node el); +void parseGlissandoContent(Glissando &out, pugi::xml_node el, const ParseContext &context); + void serializeGlissando(const Glissando &v, pugi::xml_node parent, const char *tag); void serializeGlissandoContent(const Glissando &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Glyph.cpp b/src/private/mx/core/generated/Glyph.cpp index b868a3833..b6d9eb321 100644 --- a/src/private/mx/core/generated/Glyph.cpp +++ b/src/private/mx/core/generated/Glyph.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Glyph.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void Glyph::setValue(SmuflGlyphName value) } Glyph parseGlyph(pugi::xml_node el) +{ + return parseGlyph(el, ParseContext{}); +} + +Glyph parseGlyph(pugi::xml_node el, const ParseContext &context) { Glyph out; bool seen_type = false; @@ -44,7 +50,7 @@ Glyph parseGlyph(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(GlyphType::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else { @@ -55,13 +61,18 @@ Glyph parseGlyph(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseGlyphContent(out, el); + parseGlyphContent(out, el, context); return out; } void parseGlyphContent(Glyph &out, pugi::xml_node el) { - out.setValue(SmuflGlyphName::parse(childText(el))); + parseGlyphContent(out, el, ParseContext{}); +} + +void parseGlyphContent(Glyph &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Glyph.h b/src/private/mx/core/generated/Glyph.h index 226b3a9f5..bd4de6ee2 100644 --- a/src/private/mx/core/generated/Glyph.h +++ b/src/private/mx/core/generated/Glyph.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The glyph element represents what SMuFL glyph should be used for different variations of symbols /// that are semantically identical. The type attribute specifies what type of glyph is being /// defined. The element value specifies what SMuFL glyph to use, including recommended stylistic @@ -39,8 +41,12 @@ class Glyph final Glyph parseGlyph(pugi::xml_node el); +Glyph parseGlyph(pugi::xml_node el, const ParseContext &context); + void parseGlyphContent(Glyph &out, pugi::xml_node el); +void parseGlyphContent(Glyph &out, pugi::xml_node el, const ParseContext &context); + void serializeGlyph(const Glyph &v, pugi::xml_node parent, const char *tag); void serializeGlyphContent(const Glyph &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/GlyphType.cpp b/src/private/mx/core/generated/GlyphType.cpp index 5451037f3..0d8f08c52 100644 --- a/src/private/mx/core/generated/GlyphType.cpp +++ b/src/private/mx/core/generated/GlyphType.cpp @@ -32,4 +32,11 @@ GlyphType GlyphType::parse(std::string_view text) return GlyphType{std::string{text}}; } +GlyphType GlyphType::parse(std::string_view text, ValueParseOutcome &outcome) +{ + GlyphType out{std::string{text}}; + outcome = out.value() == text ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; +} + } // namespace mx::core diff --git a/src/private/mx/core/generated/GlyphType.h b/src/private/mx/core/generated/GlyphType.h index c23a559f9..0abf73a40 100644 --- a/src/private/mx/core/generated/GlyphType.h +++ b/src/private/mx/core/generated/GlyphType.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -45,6 +47,9 @@ class GlyphType final static GlyphType parse(std::string_view text); + /// Says whether the text had to be repaired. + static GlyphType parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const GlyphType &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Grace.cpp b/src/private/mx/core/generated/Grace.cpp index 612a3f3f4..79aec44e8 100644 --- a/src/private/mx/core/generated/Grace.cpp +++ b/src/private/mx/core/generated/Grace.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Grace.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -51,6 +52,11 @@ void Grace::setSlash(std::optional value) } Grace parseGrace(pugi::xml_node el) +{ + return parseGrace(el, ParseContext{}); +} + +Grace parseGrace(pugi::xml_node el, const ParseContext &context) { Grace out; for (pugi::xml_attribute a : el.attributes()) @@ -62,32 +68,38 @@ Grace parseGrace(pugi::xml_node el) } if (aname == "steal-time-previous") { - out.setStealTimePrevious(Percent::parse(a.value())); + out.setStealTimePrevious(parseValue(a.value(), context, el, "steal-time-previous")); } else if (aname == "steal-time-following") { - out.setStealTimeFollowing(Percent::parse(a.value())); + out.setStealTimeFollowing(parseValue(a.value(), context, el, "steal-time-following")); } else if (aname == "make-time") { - out.setMakeTime(Divisions::parse(a.value())); + out.setMakeTime(parseValue(a.value(), context, el, "make-time")); } else if (aname == "slash") { - out.setSlash(YesNo::parse(a.value())); + out.setSlash(parseValue(a.value(), context, el, "slash")); } else { throwUnknownAttribute(el, a.name()); } } - parseGraceContent(out, el); + parseGraceContent(out, el, context); return out; } void parseGraceContent(Grace &out, pugi::xml_node el) +{ + parseGraceContent(out, el, ParseContext{}); +} + +void parseGraceContent(Grace &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Grace.h b/src/private/mx/core/generated/Grace.h index 7215102bb..fad129cd6 100644 --- a/src/private/mx/core/generated/Grace.h +++ b/src/private/mx/core/generated/Grace.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The grace type indicates the presence of a grace note. The slash attribute for a grace note is /// yes for slashed grace notes. The steal-time-previous attribute indicates the percentage of time /// to steal from the previous note for the grace note. The steal-time-following attribute indicates @@ -45,8 +47,12 @@ class Grace final Grace parseGrace(pugi::xml_node el); +Grace parseGrace(pugi::xml_node el, const ParseContext &context); + void parseGraceContent(Grace &out, pugi::xml_node el); +void parseGraceContent(Grace &out, pugi::xml_node el, const ParseContext &context); + void serializeGrace(const Grace &v, pugi::xml_node parent, const char *tag); void serializeGraceContent(const Grace &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/GraceCueNoteGroup.cpp b/src/private/mx/core/generated/GraceCueNoteGroup.cpp index 4bf75ae69..1ed667bd8 100644 --- a/src/private/mx/core/generated/GraceCueNoteGroup.cpp +++ b/src/private/mx/core/generated/GraceCueNoteGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/GraceCueNoteGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,11 +32,16 @@ void GraceCueNoteGroup::setFullNote(FullNoteGroup value) } GraceCueNoteGroup parseGraceCueNoteGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseGraceCueNoteGroup(el, cursor, ParseContext{}); +} + +GraceCueNoteGroup parseGraceCueNoteGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { GraceCueNoteGroup out; if (cursorIs(cursor, "cue")) { - out.setCue(parseEmpty(cursor)); + out.setCue(parseEmpty(cursor, context)); cursor = nextElement(cursor); } else @@ -45,7 +51,7 @@ GraceCueNoteGroup parseGraceCueNoteGroup(pugi::xml_node el, pugi::xml_node &curs if (cursor && (cursorIs(cursor, "chord") || cursorIs(cursor, "pitch") || cursorIs(cursor, "unpitched") || cursorIs(cursor, "rest"))) { - out.setFullNote(parseFullNoteGroup(el, cursor)); + out.setFullNote(parseFullNoteGroup(el, cursor, context)); } else { diff --git a/src/private/mx/core/generated/GraceCueNoteGroup.h b/src/private/mx/core/generated/GraceCueNoteGroup.h index 24b50793b..68c269c03 100644 --- a/src/private/mx/core/generated/GraceCueNoteGroup.h +++ b/src/private/mx/core/generated/GraceCueNoteGroup.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A shared content group (synthesized from an anonymous /// particle of the schema): transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -39,6 +41,8 @@ class GraceCueNoteGroup final /// is the enclosing element, for error paths. GraceCueNoteGroup parseGraceCueNoteGroup(pugi::xml_node el, pugi::xml_node &cursor); +GraceCueNoteGroup parseGraceCueNoteGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeGraceCueNoteGroup(const GraceCueNoteGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/GraceNormalNoteGroup.cpp b/src/private/mx/core/generated/GraceNormalNoteGroup.cpp index a60951a82..c9936c544 100644 --- a/src/private/mx/core/generated/GraceNormalNoteGroup.cpp +++ b/src/private/mx/core/generated/GraceNormalNoteGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/GraceNormalNoteGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,12 +42,17 @@ void GraceNormalNoteGroup::clearTie() noexcept } GraceNormalNoteGroup parseGraceNormalNoteGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseGraceNormalNoteGroup(el, cursor, ParseContext{}); +} + +GraceNormalNoteGroup parseGraceNormalNoteGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { GraceNormalNoteGroup out; if (cursor && (cursorIs(cursor, "chord") || cursorIs(cursor, "pitch") || cursorIs(cursor, "unpitched") || cursorIs(cursor, "rest"))) { - out.setFullNote(parseFullNoteGroup(el, cursor)); + out.setFullNote(parseFullNoteGroup(el, cursor, context)); } else { @@ -54,7 +60,7 @@ GraceNormalNoteGroup parseGraceNormalNoteGroup(pugi::xml_node el, pugi::xml_node } while (cursorIs(cursor, "tie")) { - if (!out.addTie(parseTie(cursor))) + if (!out.addTie(parseTie(cursor, context))) { throwTooManyElements(cursor); } diff --git a/src/private/mx/core/generated/GraceNormalNoteGroup.h b/src/private/mx/core/generated/GraceNormalNoteGroup.h index b3cf5ac8b..0bd0758cd 100644 --- a/src/private/mx/core/generated/GraceNormalNoteGroup.h +++ b/src/private/mx/core/generated/GraceNormalNoteGroup.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A shared content group (synthesized from an anonymous /// particle of the schema): transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -43,6 +45,8 @@ class GraceNormalNoteGroup final /// is the enclosing element, for error paths. GraceNormalNoteGroup parseGraceNormalNoteGroup(pugi::xml_node el, pugi::xml_node &cursor); +GraceNormalNoteGroup parseGraceNormalNoteGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeGraceNormalNoteGroup(const GraceNormalNoteGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/GraceNoteChoice.cpp b/src/private/mx/core/generated/GraceNoteChoice.cpp index e3deb3c75..b732a73d7 100644 --- a/src/private/mx/core/generated/GraceNoteChoice.cpp +++ b/src/private/mx/core/generated/GraceNoteChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/GraceNoteChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -26,15 +27,20 @@ GraceNoteChoice GraceNoteChoice::graceCueNoteGroup(GraceCueNoteGroup value) } GraceNoteChoice parseGraceNoteChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseGraceNoteChoice(el, cursor, ParseContext{}); +} + +GraceNoteChoice parseGraceNoteChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "chord") || cursorIs(cursor, "pitch") || cursorIs(cursor, "unpitched") || cursorIs(cursor, "rest"))) { - return GraceNoteChoice::graceNormalNoteGroup(parseGraceNormalNoteGroup(el, cursor)); + return GraceNoteChoice::graceNormalNoteGroup(parseGraceNormalNoteGroup(el, cursor, context)); } if (cursor && (cursorIs(cursor, "cue"))) { - return GraceNoteChoice::graceCueNoteGroup(parseGraceCueNoteGroup(el, cursor)); + return GraceNoteChoice::graceCueNoteGroup(parseGraceCueNoteGroup(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/GraceNoteChoice.h b/src/private/mx/core/generated/GraceNoteChoice.h index 2cb493e1a..c1dc2ca2e 100644 --- a/src/private/mx/core/generated/GraceNoteChoice.h +++ b/src/private/mx/core/generated/GraceNoteChoice.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -82,6 +84,8 @@ class GraceNoteChoice final /// the enclosing element, for error paths. GraceNoteChoice parseGraceNoteChoice(pugi::xml_node el, pugi::xml_node &cursor); +GraceNoteChoice parseGraceNoteChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeGraceNoteChoice(const GraceNoteChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/GraceNoteGroup.cpp b/src/private/mx/core/generated/GraceNoteGroup.cpp index 89e532f6b..63d50be74 100644 --- a/src/private/mx/core/generated/GraceNoteGroup.cpp +++ b/src/private/mx/core/generated/GraceNoteGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/GraceNoteGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,11 +32,16 @@ void GraceNoteGroup::setGraceNoteChoice(GraceNoteChoice value) } GraceNoteGroup parseGraceNoteGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseGraceNoteGroup(el, cursor, ParseContext{}); +} + +GraceNoteGroup parseGraceNoteGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { GraceNoteGroup out; if (cursorIs(cursor, "grace")) { - out.setGrace(parseGrace(cursor)); + out.setGrace(parseGrace(cursor, context)); cursor = nextElement(cursor); } else @@ -45,7 +51,7 @@ GraceNoteGroup parseGraceNoteGroup(pugi::xml_node el, pugi::xml_node &cursor) if (cursor && (cursorIs(cursor, "chord") || cursorIs(cursor, "pitch") || cursorIs(cursor, "unpitched") || cursorIs(cursor, "rest") || cursorIs(cursor, "cue"))) { - out.setGraceNoteChoice(parseGraceNoteChoice(el, cursor)); + out.setGraceNoteChoice(parseGraceNoteChoice(el, cursor, context)); } else { diff --git a/src/private/mx/core/generated/GraceNoteGroup.h b/src/private/mx/core/generated/GraceNoteGroup.h index d81c5661d..e25562a19 100644 --- a/src/private/mx/core/generated/GraceNoteGroup.h +++ b/src/private/mx/core/generated/GraceNoteGroup.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A shared content group (synthesized from an anonymous /// particle of the schema): transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -39,6 +41,8 @@ class GraceNoteGroup final /// is the enclosing element, for error paths. GraceNoteGroup parseGraceNoteGroup(pugi::xml_node el, pugi::xml_node &cursor); +GraceNoteGroup parseGraceNoteGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeGraceNoteGroup(const GraceNoteGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/GroupBarline.cpp b/src/private/mx/core/generated/GroupBarline.cpp index f0ff32d1e..594f4bdb2 100644 --- a/src/private/mx/core/generated/GroupBarline.cpp +++ b/src/private/mx/core/generated/GroupBarline.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/GroupBarline.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void GroupBarline::setValue(GroupBarlineValue value) } GroupBarline parseGroupBarline(pugi::xml_node el) +{ + return parseGroupBarline(el, ParseContext{}); +} + +GroupBarline parseGroupBarline(pugi::xml_node el, const ParseContext &context) { GroupBarline out; for (pugi::xml_attribute a : el.attributes()) @@ -42,20 +48,25 @@ GroupBarline parseGroupBarline(pugi::xml_node el) } if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else { throwUnknownAttribute(el, a.name()); } } - parseGroupBarlineContent(out, el); + parseGroupBarlineContent(out, el, context); return out; } void parseGroupBarlineContent(GroupBarline &out, pugi::xml_node el) { - out.setValue(GroupBarlineValue::parse(childText(el))); + parseGroupBarlineContent(out, el, ParseContext{}); +} + +void parseGroupBarlineContent(GroupBarline &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/GroupBarline.h b/src/private/mx/core/generated/GroupBarline.h index d154306b8..0de66b1a5 100644 --- a/src/private/mx/core/generated/GroupBarline.h +++ b/src/private/mx/core/generated/GroupBarline.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The group-barline type indicates if the group should have common barlines. class GroupBarline final { @@ -33,8 +35,12 @@ class GroupBarline final GroupBarline parseGroupBarline(pugi::xml_node el); +GroupBarline parseGroupBarline(pugi::xml_node el, const ParseContext &context); + void parseGroupBarlineContent(GroupBarline &out, pugi::xml_node el); +void parseGroupBarlineContent(GroupBarline &out, pugi::xml_node el, const ParseContext &context); + void serializeGroupBarline(const GroupBarline &v, pugi::xml_node parent, const char *tag); void serializeGroupBarlineContent(const GroupBarline &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/GroupBarlineValue.cpp b/src/private/mx/core/generated/GroupBarlineValue.cpp index f729cf41c..0b606c42a 100644 --- a/src/private/mx/core/generated/GroupBarlineValue.cpp +++ b/src/private/mx/core/generated/GroupBarlineValue.cpp @@ -48,9 +48,15 @@ bool GroupBarlineValue::tryParse(std::string_view text, GroupBarlineValue &out) } GroupBarlineValue GroupBarlineValue::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +GroupBarlineValue GroupBarlineValue::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { GroupBarlineValue v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/GroupBarlineValue.h b/src/private/mx/core/generated/GroupBarlineValue.h index 1a2db6ebf..916ce9449 100644 --- a/src/private/mx/core/generated/GroupBarlineValue.h +++ b/src/private/mx/core/generated/GroupBarlineValue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -42,6 +44,9 @@ class GroupBarlineValue final /// (the import leniency policy; never produces an invalid value). static GroupBarlineValue parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static GroupBarlineValue parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const GroupBarlineValue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/GroupName.cpp b/src/private/mx/core/generated/GroupName.cpp index adfb2857e..52ab90753 100644 --- a/src/private/mx/core/generated/GroupName.cpp +++ b/src/private/mx/core/generated/GroupName.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/GroupName.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -121,6 +122,11 @@ void GroupName::setValue(std::string value) } GroupName parseGroupName(pugi::xml_node el) +{ + return parseGroupName(el, ParseContext{}); +} + +GroupName parseGroupName(pugi::xml_node el, const ParseContext &context) { GroupName out; for (pugi::xml_attribute a : el.attributes()) @@ -132,54 +138,59 @@ GroupName parseGroupName(pugi::xml_node el) } if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "justify") { - out.setJustify(LeftCenterRight::parse(a.value())); + out.setJustify(parseValue(a.value(), context, el, "justify")); } else { throwUnknownAttribute(el, a.name()); } } - parseGroupNameContent(out, el); + parseGroupNameContent(out, el, context); return out; } void parseGroupNameContent(GroupName &out, pugi::xml_node el) +{ + parseGroupNameContent(out, el, ParseContext{}); +} + +void parseGroupNameContent(GroupName &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/GroupName.h b/src/private/mx/core/generated/GroupName.h index acaa9599a..ad810daea 100644 --- a/src/private/mx/core/generated/GroupName.h +++ b/src/private/mx/core/generated/GroupName.h @@ -21,6 +21,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The group-name type describes the name or abbreviation of a part-group element. Formatting /// attributes in the group-name type are deprecated in Version 2.0 in favor of the new /// group-name-display and group-abbreviation-display elements. @@ -67,8 +69,12 @@ class GroupName final GroupName parseGroupName(pugi::xml_node el); +GroupName parseGroupName(pugi::xml_node el, const ParseContext &context); + void parseGroupNameContent(GroupName &out, pugi::xml_node el); +void parseGroupNameContent(GroupName &out, pugi::xml_node el, const ParseContext &context); + void serializeGroupName(const GroupName &v, pugi::xml_node parent, const char *tag); void serializeGroupNameContent(const GroupName &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/GroupSymbol.cpp b/src/private/mx/core/generated/GroupSymbol.cpp index 6e8d65d77..b8ec0c6ff 100644 --- a/src/private/mx/core/generated/GroupSymbol.cpp +++ b/src/private/mx/core/generated/GroupSymbol.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/GroupSymbol.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -71,6 +72,11 @@ void GroupSymbol::setValue(GroupSymbolValue value) } GroupSymbol parseGroupSymbol(pugi::xml_node el) +{ + return parseGroupSymbol(el, ParseContext{}); +} + +GroupSymbol parseGroupSymbol(pugi::xml_node el, const ParseContext &context) { GroupSymbol out; for (pugi::xml_attribute a : el.attributes()) @@ -82,36 +88,41 @@ GroupSymbol parseGroupSymbol(pugi::xml_node el) } if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else { throwUnknownAttribute(el, a.name()); } } - parseGroupSymbolContent(out, el); + parseGroupSymbolContent(out, el, context); return out; } void parseGroupSymbolContent(GroupSymbol &out, pugi::xml_node el) { - out.setValue(GroupSymbolValue::parse(childText(el))); + parseGroupSymbolContent(out, el, ParseContext{}); +} + +void parseGroupSymbolContent(GroupSymbol &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/GroupSymbol.h b/src/private/mx/core/generated/GroupSymbol.h index 1de49702d..0f96d3bd7 100644 --- a/src/private/mx/core/generated/GroupSymbol.h +++ b/src/private/mx/core/generated/GroupSymbol.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The group-symbol type indicates how the symbol for a group is indicated in the score. It is none /// if not specified. class GroupSymbol final @@ -47,8 +49,12 @@ class GroupSymbol final GroupSymbol parseGroupSymbol(pugi::xml_node el); +GroupSymbol parseGroupSymbol(pugi::xml_node el, const ParseContext &context); + void parseGroupSymbolContent(GroupSymbol &out, pugi::xml_node el); +void parseGroupSymbolContent(GroupSymbol &out, pugi::xml_node el, const ParseContext &context); + void serializeGroupSymbol(const GroupSymbol &v, pugi::xml_node parent, const char *tag); void serializeGroupSymbolContent(const GroupSymbol &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/GroupSymbolValue.cpp b/src/private/mx/core/generated/GroupSymbolValue.cpp index c3c5d4b6d..e0be8a243 100644 --- a/src/private/mx/core/generated/GroupSymbolValue.cpp +++ b/src/private/mx/core/generated/GroupSymbolValue.cpp @@ -56,9 +56,15 @@ bool GroupSymbolValue::tryParse(std::string_view text, GroupSymbolValue &out) no } GroupSymbolValue GroupSymbolValue::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +GroupSymbolValue GroupSymbolValue::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { GroupSymbolValue v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/GroupSymbolValue.h b/src/private/mx/core/generated/GroupSymbolValue.h index 2b2d3bc0f..4080cacb4 100644 --- a/src/private/mx/core/generated/GroupSymbolValue.h +++ b/src/private/mx/core/generated/GroupSymbolValue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -47,6 +49,9 @@ class GroupSymbolValue final /// (the import leniency policy; never produces an invalid value). static GroupSymbolValue parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static GroupSymbolValue parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const GroupSymbolValue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Grouping.cpp b/src/private/mx/core/generated/Grouping.cpp index 50c7f4b38..02fc4b8ab 100644 --- a/src/private/mx/core/generated/Grouping.cpp +++ b/src/private/mx/core/generated/Grouping.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Grouping.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -66,6 +67,11 @@ void Grouping::setFeature(std::vector value) } Grouping parseGrouping(pugi::xml_node el) +{ + return parseGrouping(el, ParseContext{}); +} + +Grouping parseGrouping(pugi::xml_node el, const ParseContext &context) { Grouping out; bool seen_type = false; @@ -79,7 +85,7 @@ Grouping parseGrouping(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(StartStopSingle::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "number") { @@ -102,16 +108,21 @@ Grouping parseGrouping(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseGroupingContent(out, el); + parseGroupingContent(out, el, context); return out; } void parseGroupingContent(Grouping &out, pugi::xml_node el) +{ + parseGroupingContent(out, el, ParseContext{}); +} + +void parseGroupingContent(Grouping &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); while (cursorIs(cursor, "feature")) { - out.addFeature(parseFeature(cursor)); + out.addFeature(parseFeature(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/Grouping.h b/src/private/mx/core/generated/Grouping.h index 70851e360..e77c70ef0 100644 --- a/src/private/mx/core/generated/Grouping.h +++ b/src/private/mx/core/generated/Grouping.h @@ -20,6 +20,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The grouping type is used for musical analysis. When the type attribute is "start" or "single", /// it usually contains one or more feature elements. The number attribute is used for distinguishing /// between overlapping and hierarchical groupings. The member-of attribute allows for easy @@ -55,8 +57,12 @@ class Grouping final Grouping parseGrouping(pugi::xml_node el); +Grouping parseGrouping(pugi::xml_node el, const ParseContext &context); + void parseGroupingContent(Grouping &out, pugi::xml_node el); +void parseGroupingContent(Grouping &out, pugi::xml_node el, const ParseContext &context); + void serializeGrouping(const Grouping &v, pugi::xml_node parent, const char *tag); void serializeGroupingContent(const Grouping &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/HammerOnPullOff.cpp b/src/private/mx/core/generated/HammerOnPullOff.cpp index b2642275f..d59622745 100644 --- a/src/private/mx/core/generated/HammerOnPullOff.cpp +++ b/src/private/mx/core/generated/HammerOnPullOff.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/HammerOnPullOff.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -141,6 +142,11 @@ void HammerOnPullOff::setValue(std::string value) } HammerOnPullOff parseHammerOnPullOff(pugi::xml_node el) +{ + return parseHammerOnPullOff(el, ParseContext{}); +} + +HammerOnPullOff parseHammerOnPullOff(pugi::xml_node el, const ParseContext &context) { HammerOnPullOff out; bool seen_type = false; @@ -154,51 +160,51 @@ HammerOnPullOff parseHammerOnPullOff(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(StartStop::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "number") { - out.setNumber(NumberLevel::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else { @@ -209,11 +215,16 @@ HammerOnPullOff parseHammerOnPullOff(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseHammerOnPullOffContent(out, el); + parseHammerOnPullOffContent(out, el, context); return out; } void parseHammerOnPullOffContent(HammerOnPullOff &out, pugi::xml_node el) +{ + parseHammerOnPullOffContent(out, el, ParseContext{}); +} + +void parseHammerOnPullOffContent(HammerOnPullOff &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/HammerOnPullOff.h b/src/private/mx/core/generated/HammerOnPullOff.h index e1f1e8ae1..99f0ad5ac 100644 --- a/src/private/mx/core/generated/HammerOnPullOff.h +++ b/src/private/mx/core/generated/HammerOnPullOff.h @@ -23,6 +23,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The hammer-on and pull-off elements are used in guitar and fretted instrument notation. Since a /// single slur can be marked over many notes, the hammer-on and pull-off elements are separate so /// the individual pair of notes can be specified. The element content can be used to specify how the @@ -77,8 +79,12 @@ class HammerOnPullOff final HammerOnPullOff parseHammerOnPullOff(pugi::xml_node el); +HammerOnPullOff parseHammerOnPullOff(pugi::xml_node el, const ParseContext &context); + void parseHammerOnPullOffContent(HammerOnPullOff &out, pugi::xml_node el); +void parseHammerOnPullOffContent(HammerOnPullOff &out, pugi::xml_node el, const ParseContext &context); + void serializeHammerOnPullOff(const HammerOnPullOff &v, pugi::xml_node parent, const char *tag); void serializeHammerOnPullOffContent(const HammerOnPullOff &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Handbell.cpp b/src/private/mx/core/generated/Handbell.cpp index 2f2cf003d..a5ae68b60 100644 --- a/src/private/mx/core/generated/Handbell.cpp +++ b/src/private/mx/core/generated/Handbell.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Handbell.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -121,6 +122,11 @@ void Handbell::setValue(HandbellValue value) } Handbell parseHandbell(pugi::xml_node el) +{ + return parseHandbell(el, ParseContext{}); +} + +Handbell parseHandbell(pugi::xml_node el, const ParseContext &context) { Handbell out; for (pugi::xml_attribute a : el.attributes()) @@ -132,56 +138,61 @@ Handbell parseHandbell(pugi::xml_node el) } if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else { throwUnknownAttribute(el, a.name()); } } - parseHandbellContent(out, el); + parseHandbellContent(out, el, context); return out; } void parseHandbellContent(Handbell &out, pugi::xml_node el) { - out.setValue(HandbellValue::parse(childText(el))); + parseHandbellContent(out, el, ParseContext{}); +} + +void parseHandbellContent(Handbell &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Handbell.h b/src/private/mx/core/generated/Handbell.h index ffc1386f9..ea21ce2b8 100644 --- a/src/private/mx/core/generated/Handbell.h +++ b/src/private/mx/core/generated/Handbell.h @@ -22,6 +22,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The handbell element represents notation for various techniques used in handbell and handchime /// music. class Handbell final @@ -67,8 +69,12 @@ class Handbell final Handbell parseHandbell(pugi::xml_node el); +Handbell parseHandbell(pugi::xml_node el, const ParseContext &context); + void parseHandbellContent(Handbell &out, pugi::xml_node el); +void parseHandbellContent(Handbell &out, pugi::xml_node el, const ParseContext &context); + void serializeHandbell(const Handbell &v, pugi::xml_node parent, const char *tag); void serializeHandbellContent(const Handbell &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/HandbellValue.cpp b/src/private/mx/core/generated/HandbellValue.cpp index d8b4051aa..04b7fa4b8 100644 --- a/src/private/mx/core/generated/HandbellValue.cpp +++ b/src/private/mx/core/generated/HandbellValue.cpp @@ -102,9 +102,15 @@ bool HandbellValue::tryParse(std::string_view text, HandbellValue &out) noexcept } HandbellValue HandbellValue::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +HandbellValue HandbellValue::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { HandbellValue v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/HandbellValue.h b/src/private/mx/core/generated/HandbellValue.h index d66f84585..621b83fbf 100644 --- a/src/private/mx/core/generated/HandbellValue.h +++ b/src/private/mx/core/generated/HandbellValue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -60,6 +62,9 @@ class HandbellValue final /// (the import leniency policy; never produces an invalid value). static HandbellValue parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static HandbellValue parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const HandbellValue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/HarmonClosed.cpp b/src/private/mx/core/generated/HarmonClosed.cpp index bfa8864b9..9a3368d59 100644 --- a/src/private/mx/core/generated/HarmonClosed.cpp +++ b/src/private/mx/core/generated/HarmonClosed.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/HarmonClosed.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void HarmonClosed::setValue(HarmonClosedValue value) } HarmonClosed parseHarmonClosed(pugi::xml_node el) +{ + return parseHarmonClosed(el, ParseContext{}); +} + +HarmonClosed parseHarmonClosed(pugi::xml_node el, const ParseContext &context) { HarmonClosed out; for (pugi::xml_attribute a : el.attributes()) @@ -42,20 +48,25 @@ HarmonClosed parseHarmonClosed(pugi::xml_node el) } if (aname == "location") { - out.setLocation(HarmonClosedLocation::parse(a.value())); + out.setLocation(parseValue(a.value(), context, el, "location")); } else { throwUnknownAttribute(el, a.name()); } } - parseHarmonClosedContent(out, el); + parseHarmonClosedContent(out, el, context); return out; } void parseHarmonClosedContent(HarmonClosed &out, pugi::xml_node el) { - out.setValue(HarmonClosedValue::parse(childText(el))); + parseHarmonClosedContent(out, el, ParseContext{}); +} + +void parseHarmonClosedContent(HarmonClosed &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/HarmonClosed.h b/src/private/mx/core/generated/HarmonClosed.h index c37689d27..7484989cd 100644 --- a/src/private/mx/core/generated/HarmonClosed.h +++ b/src/private/mx/core/generated/HarmonClosed.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The harmon-closed type represents whether the harmon mute is closed, open, or half-open. The /// optional location attribute indicates which portion of the symbol is filled in when the element /// value is half. @@ -35,8 +37,12 @@ class HarmonClosed final HarmonClosed parseHarmonClosed(pugi::xml_node el); +HarmonClosed parseHarmonClosed(pugi::xml_node el, const ParseContext &context); + void parseHarmonClosedContent(HarmonClosed &out, pugi::xml_node el); +void parseHarmonClosedContent(HarmonClosed &out, pugi::xml_node el, const ParseContext &context); + void serializeHarmonClosed(const HarmonClosed &v, pugi::xml_node parent, const char *tag); void serializeHarmonClosedContent(const HarmonClosed &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/HarmonClosedLocation.cpp b/src/private/mx/core/generated/HarmonClosedLocation.cpp index 45de7e0f8..a3967f41c 100644 --- a/src/private/mx/core/generated/HarmonClosedLocation.cpp +++ b/src/private/mx/core/generated/HarmonClosedLocation.cpp @@ -54,9 +54,15 @@ bool HarmonClosedLocation::tryParse(std::string_view text, HarmonClosedLocation } HarmonClosedLocation HarmonClosedLocation::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +HarmonClosedLocation HarmonClosedLocation::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { HarmonClosedLocation v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/HarmonClosedLocation.h b/src/private/mx/core/generated/HarmonClosedLocation.h index 2a5d71d6b..b9bdc9cb8 100644 --- a/src/private/mx/core/generated/HarmonClosedLocation.h +++ b/src/private/mx/core/generated/HarmonClosedLocation.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -45,6 +47,9 @@ class HarmonClosedLocation final /// (the import leniency policy; never produces an invalid value). static HarmonClosedLocation parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static HarmonClosedLocation parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const HarmonClosedLocation &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/HarmonClosedValue.cpp b/src/private/mx/core/generated/HarmonClosedValue.cpp index c6f7afac6..2fcff6ed8 100644 --- a/src/private/mx/core/generated/HarmonClosedValue.cpp +++ b/src/private/mx/core/generated/HarmonClosedValue.cpp @@ -48,9 +48,15 @@ bool HarmonClosedValue::tryParse(std::string_view text, HarmonClosedValue &out) } HarmonClosedValue HarmonClosedValue::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +HarmonClosedValue HarmonClosedValue::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { HarmonClosedValue v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/HarmonClosedValue.h b/src/private/mx/core/generated/HarmonClosedValue.h index 2bd938620..41d4b29f6 100644 --- a/src/private/mx/core/generated/HarmonClosedValue.h +++ b/src/private/mx/core/generated/HarmonClosedValue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -42,6 +44,9 @@ class HarmonClosedValue final /// (the import leniency policy; never produces an invalid value). static HarmonClosedValue parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static HarmonClosedValue parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const HarmonClosedValue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/HarmonMute.cpp b/src/private/mx/core/generated/HarmonMute.cpp index 5f793f23b..65a1edfe8 100644 --- a/src/private/mx/core/generated/HarmonMute.cpp +++ b/src/private/mx/core/generated/HarmonMute.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/HarmonMute.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -121,6 +122,11 @@ void HarmonMute::setHarmonClosed(HarmonClosed value) } HarmonMute parseHarmonMute(pugi::xml_node el) +{ + return parseHarmonMute(el, ParseContext{}); +} + +HarmonMute parseHarmonMute(pugi::xml_node el, const ParseContext &context) { HarmonMute out; for (pugi::xml_attribute a : el.attributes()) @@ -132,59 +138,64 @@ HarmonMute parseHarmonMute(pugi::xml_node el) } if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else { throwUnknownAttribute(el, a.name()); } } - parseHarmonMuteContent(out, el); + parseHarmonMuteContent(out, el, context); return out; } void parseHarmonMuteContent(HarmonMute &out, pugi::xml_node el) +{ + parseHarmonMuteContent(out, el, ParseContext{}); +} + +void parseHarmonMuteContent(HarmonMute &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "harmon-closed")) { - out.setHarmonClosed(parseHarmonClosed(cursor)); + out.setHarmonClosed(parseHarmonClosed(cursor, context)); cursor = nextElement(cursor); } else diff --git a/src/private/mx/core/generated/HarmonMute.h b/src/private/mx/core/generated/HarmonMute.h index 89c7794ce..fe216ec78 100644 --- a/src/private/mx/core/generated/HarmonMute.h +++ b/src/private/mx/core/generated/HarmonMute.h @@ -24,6 +24,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The harmon-mute type represents the symbols used for harmon mutes in brass notation. /// Content fields mirror the schema grammar in declaration order; the /// serializer walks them, so a wrong order is unrepresentable (plan ยง2.3). @@ -70,8 +72,12 @@ class HarmonMute final HarmonMute parseHarmonMute(pugi::xml_node el); +HarmonMute parseHarmonMute(pugi::xml_node el, const ParseContext &context); + void parseHarmonMuteContent(HarmonMute &out, pugi::xml_node el); +void parseHarmonMuteContent(HarmonMute &out, pugi::xml_node el, const ParseContext &context); + void serializeHarmonMute(const HarmonMute &v, pugi::xml_node parent, const char *tag); void serializeHarmonMuteContent(const HarmonMute &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Harmonic.cpp b/src/private/mx/core/generated/Harmonic.cpp index 8673d41f0..0d5112d7e 100644 --- a/src/private/mx/core/generated/Harmonic.cpp +++ b/src/private/mx/core/generated/Harmonic.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Harmonic.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -141,6 +142,11 @@ void Harmonic::setChoice2(std::optional value) } Harmonic parseHarmonic(pugi::xml_node el) +{ + return parseHarmonic(el, ParseContext{}); +} + +Harmonic parseHarmonic(pugi::xml_node el, const ParseContext &context) { Harmonic out; for (pugi::xml_attribute a : el.attributes()) @@ -152,68 +158,73 @@ Harmonic parseHarmonic(pugi::xml_node el) } if (aname == "print-object") { - out.setPrintObject(YesNo::parse(a.value())); + out.setPrintObject(parseValue(a.value(), context, el, "print-object")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else { throwUnknownAttribute(el, a.name()); } } - parseHarmonicContent(out, el); + parseHarmonicContent(out, el, context); return out; } void parseHarmonicContent(Harmonic &out, pugi::xml_node el) +{ + parseHarmonicContent(out, el, ParseContext{}); +} + +void parseHarmonicContent(Harmonic &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "natural") || cursorIs(cursor, "artificial"))) { - out.setChoice(parseHarmonicChoice(el, cursor)); + out.setChoice(parseHarmonicChoice(el, cursor, context)); } if (cursor && (cursorIs(cursor, "base-pitch") || cursorIs(cursor, "touching-pitch") || cursorIs(cursor, "sounding-pitch"))) { - out.setChoice2(parseHarmonicChoice2(el, cursor)); + out.setChoice2(parseHarmonicChoice2(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/Harmonic.h b/src/private/mx/core/generated/Harmonic.h index d256331d7..3b750fab0 100644 --- a/src/private/mx/core/generated/Harmonic.h +++ b/src/private/mx/core/generated/Harmonic.h @@ -26,6 +26,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The harmonic type indicates natural and artificial harmonics. Allowing the type of pitch to be /// specified, combined with controls for appearance/playback differences, allows both the notation /// and the sound to be represented. Artificial harmonics can add a notated touching pitch; @@ -83,8 +85,12 @@ class Harmonic final Harmonic parseHarmonic(pugi::xml_node el); +Harmonic parseHarmonic(pugi::xml_node el, const ParseContext &context); + void parseHarmonicContent(Harmonic &out, pugi::xml_node el); +void parseHarmonicContent(Harmonic &out, pugi::xml_node el, const ParseContext &context); + void serializeHarmonic(const Harmonic &v, pugi::xml_node parent, const char *tag); void serializeHarmonicContent(const Harmonic &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/HarmonicChoice.cpp b/src/private/mx/core/generated/HarmonicChoice.cpp index 17ce02f2a..fa4a9fab4 100644 --- a/src/private/mx/core/generated/HarmonicChoice.cpp +++ b/src/private/mx/core/generated/HarmonicChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/HarmonicChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -26,16 +27,21 @@ HarmonicChoice HarmonicChoice::artificial(Empty value) } HarmonicChoice parseHarmonicChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseHarmonicChoice(el, cursor, ParseContext{}); +} + +HarmonicChoice parseHarmonicChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "natural"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return HarmonicChoice::natural(std::move(value)); } if (cursor && (cursorIs(cursor, "artificial"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return HarmonicChoice::artificial(std::move(value)); } diff --git a/src/private/mx/core/generated/HarmonicChoice.h b/src/private/mx/core/generated/HarmonicChoice.h index 81690b955..e6290374f 100644 --- a/src/private/mx/core/generated/HarmonicChoice.h +++ b/src/private/mx/core/generated/HarmonicChoice.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -81,6 +83,8 @@ class HarmonicChoice final /// the enclosing element, for error paths. HarmonicChoice parseHarmonicChoice(pugi::xml_node el, pugi::xml_node &cursor); +HarmonicChoice parseHarmonicChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeHarmonicChoice(const HarmonicChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/HarmonicChoice2.cpp b/src/private/mx/core/generated/HarmonicChoice2.cpp index 6119401e6..61dbca832 100644 --- a/src/private/mx/core/generated/HarmonicChoice2.cpp +++ b/src/private/mx/core/generated/HarmonicChoice2.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/HarmonicChoice2.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,22 +32,27 @@ HarmonicChoice2 HarmonicChoice2::soundingPitch(Empty value) } HarmonicChoice2 parseHarmonicChoice2(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseHarmonicChoice2(el, cursor, ParseContext{}); +} + +HarmonicChoice2 parseHarmonicChoice2(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "base-pitch"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return HarmonicChoice2::basePitch(std::move(value)); } if (cursor && (cursorIs(cursor, "touching-pitch"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return HarmonicChoice2::touchingPitch(std::move(value)); } if (cursor && (cursorIs(cursor, "sounding-pitch"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return HarmonicChoice2::soundingPitch(std::move(value)); } diff --git a/src/private/mx/core/generated/HarmonicChoice2.h b/src/private/mx/core/generated/HarmonicChoice2.h index 87dace623..3f37e3484 100644 --- a/src/private/mx/core/generated/HarmonicChoice2.h +++ b/src/private/mx/core/generated/HarmonicChoice2.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -95,6 +97,8 @@ class HarmonicChoice2 final /// the enclosing element, for error paths. HarmonicChoice2 parseHarmonicChoice2(pugi::xml_node el, pugi::xml_node &cursor); +HarmonicChoice2 parseHarmonicChoice2(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeHarmonicChoice2(const HarmonicChoice2 &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/Harmony.cpp b/src/private/mx/core/generated/Harmony.cpp index 7a6b977d3..0045514dd 100644 --- a/src/private/mx/core/generated/Harmony.cpp +++ b/src/private/mx/core/generated/Harmony.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Harmony.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -226,6 +227,11 @@ void Harmony::setStaff(std::optional value) } Harmony parseHarmony(pugi::xml_node el) +{ + return parseHarmony(el, ParseContext{}); +} + +Harmony parseHarmony(pugi::xml_node el, const ParseContext &context) { Harmony out; for (pugi::xml_attribute a : el.attributes()) @@ -237,63 +243,63 @@ Harmony parseHarmony(pugi::xml_node el) } if (aname == "type") { - out.setType(HarmonyType::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "print-frame") { - out.setPrintFrame(YesNo::parse(a.value())); + out.setPrintFrame(parseValue(a.value(), context, el, "print-frame")); } else if (aname == "arrangement") { - out.setArrangement(HarmonyArrangement::parse(a.value())); + out.setArrangement(parseValue(a.value(), context, el, "arrangement")); } else if (aname == "print-object") { - out.setPrintObject(YesNo::parse(a.value())); + out.setPrintObject(parseValue(a.value(), context, el, "print-object")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else if (aname == "system") { - out.setSystem(SystemRelation::parse(a.value())); + out.setSystem(parseValue(a.value(), context, el, "system")); } else if (aname == "id") { @@ -304,39 +310,44 @@ Harmony parseHarmony(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseHarmonyContent(out, el); + parseHarmonyContent(out, el, context); return out; } void parseHarmonyContent(Harmony &out, pugi::xml_node el) +{ + parseHarmonyContent(out, el, ParseContext{}); +} + +void parseHarmonyContent(Harmony &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (!(cursor && (cursorIs(cursor, "root") || cursorIs(cursor, "numeral") || cursorIs(cursor, "function")))) { throwMissingElement(el, "root"); } - out.setHarmonyChord(OneOrMore{parseHarmonyChordGroup(el, cursor)}); + out.setHarmonyChord(OneOrMore{parseHarmonyChordGroup(el, cursor, context)}); while (cursor && (cursorIs(cursor, "root") || cursorIs(cursor, "numeral") || cursorIs(cursor, "function"))) { - out.addHarmonyChord(parseHarmonyChordGroup(el, cursor)); + out.addHarmonyChord(parseHarmonyChordGroup(el, cursor, context)); } if (cursorIs(cursor, "frame")) { - out.setFrame(parseFrame(cursor)); + out.setFrame(parseFrame(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "offset")) { - out.setOffset(parseOffset(cursor)); + out.setOffset(parseOffset(cursor, context)); cursor = nextElement(cursor); } if (cursor && (cursorIs(cursor, "footnote") || cursorIs(cursor, "level"))) { - out.setEditorial(parseEditorialGroup(el, cursor)); + out.setEditorial(parseEditorialGroup(el, cursor, context)); } if (cursorIs(cursor, "staff")) { - out.setStaff(parseInt(childText(cursor))); + out.setStaff(parseIntegerValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/Harmony.h b/src/private/mx/core/generated/Harmony.h index 00549a563..6645f3b14 100644 --- a/src/private/mx/core/generated/Harmony.h +++ b/src/private/mx/core/generated/Harmony.h @@ -34,6 +34,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The harmony type represents harmony analysis, including chord symbols in popular music as well as /// functional harmony analysis in classical music. If there are alternate harmonies possible, this /// can be specified using multiple harmony elements differentiated by type. Explicit harmonies have @@ -121,8 +123,12 @@ class Harmony final Harmony parseHarmony(pugi::xml_node el); +Harmony parseHarmony(pugi::xml_node el, const ParseContext &context); + void parseHarmonyContent(Harmony &out, pugi::xml_node el); +void parseHarmonyContent(Harmony &out, pugi::xml_node el, const ParseContext &context); + void serializeHarmony(const Harmony &v, pugi::xml_node parent, const char *tag); void serializeHarmonyContent(const Harmony &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/HarmonyAlter.cpp b/src/private/mx/core/generated/HarmonyAlter.cpp index 6221dbda2..9180f65d9 100644 --- a/src/private/mx/core/generated/HarmonyAlter.cpp +++ b/src/private/mx/core/generated/HarmonyAlter.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/HarmonyAlter.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -131,6 +132,11 @@ void HarmonyAlter::setValue(Semitones value) } HarmonyAlter parseHarmonyAlter(pugi::xml_node el) +{ + return parseHarmonyAlter(el, ParseContext{}); +} + +HarmonyAlter parseHarmonyAlter(pugi::xml_node el, const ParseContext &context) { HarmonyAlter out; for (pugi::xml_attribute a : el.attributes()) @@ -142,60 +148,65 @@ HarmonyAlter parseHarmonyAlter(pugi::xml_node el) } if (aname == "location") { - out.setLocation(LeftRight::parse(a.value())); + out.setLocation(parseValue(a.value(), context, el, "location")); } else if (aname == "print-object") { - out.setPrintObject(YesNo::parse(a.value())); + out.setPrintObject(parseValue(a.value(), context, el, "print-object")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else { throwUnknownAttribute(el, a.name()); } } - parseHarmonyAlterContent(out, el); + parseHarmonyAlterContent(out, el, context); return out; } void parseHarmonyAlterContent(HarmonyAlter &out, pugi::xml_node el) { - out.setValue(Semitones::parse(childText(el))); + parseHarmonyAlterContent(out, el, ParseContext{}); +} + +void parseHarmonyAlterContent(HarmonyAlter &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/HarmonyAlter.h b/src/private/mx/core/generated/HarmonyAlter.h index 8d96b1e43..520be4cfc 100644 --- a/src/private/mx/core/generated/HarmonyAlter.h +++ b/src/private/mx/core/generated/HarmonyAlter.h @@ -23,6 +23,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The harmony-alter type represents the chromatic alteration of the root, numeral, or bass of the /// current harmony-chord group within the harmony element. In some chord styles, the text of the /// preceding element may include alteration information. In that case, the print-object attribute of @@ -74,8 +76,12 @@ class HarmonyAlter final HarmonyAlter parseHarmonyAlter(pugi::xml_node el); +HarmonyAlter parseHarmonyAlter(pugi::xml_node el, const ParseContext &context); + void parseHarmonyAlterContent(HarmonyAlter &out, pugi::xml_node el); +void parseHarmonyAlterContent(HarmonyAlter &out, pugi::xml_node el, const ParseContext &context); + void serializeHarmonyAlter(const HarmonyAlter &v, pugi::xml_node parent, const char *tag); void serializeHarmonyAlterContent(const HarmonyAlter &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/HarmonyArrangement.cpp b/src/private/mx/core/generated/HarmonyArrangement.cpp index 20aae3fc0..a38d6fb50 100644 --- a/src/private/mx/core/generated/HarmonyArrangement.cpp +++ b/src/private/mx/core/generated/HarmonyArrangement.cpp @@ -48,9 +48,15 @@ bool HarmonyArrangement::tryParse(std::string_view text, HarmonyArrangement &out } HarmonyArrangement HarmonyArrangement::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +HarmonyArrangement HarmonyArrangement::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { HarmonyArrangement v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/HarmonyArrangement.h b/src/private/mx/core/generated/HarmonyArrangement.h index dbf9801c5..5caaf2d73 100644 --- a/src/private/mx/core/generated/HarmonyArrangement.h +++ b/src/private/mx/core/generated/HarmonyArrangement.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -46,6 +48,9 @@ class HarmonyArrangement final /// (the import leniency policy; never produces an invalid value). static HarmonyArrangement parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static HarmonyArrangement parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const HarmonyArrangement &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/HarmonyChordGroup.cpp b/src/private/mx/core/generated/HarmonyChordGroup.cpp index e00d04a69..f7c583f9b 100644 --- a/src/private/mx/core/generated/HarmonyChordGroup.cpp +++ b/src/private/mx/core/generated/HarmonyChordGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/HarmonyChordGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -66,11 +67,16 @@ void HarmonyChordGroup::setDegree(std::vector value) } HarmonyChordGroup parseHarmonyChordGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseHarmonyChordGroup(el, cursor, ParseContext{}); +} + +HarmonyChordGroup parseHarmonyChordGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { HarmonyChordGroup out; if (cursor && (cursorIs(cursor, "root") || cursorIs(cursor, "numeral") || cursorIs(cursor, "function"))) { - out.setChoice(parseHarmonyChordGroupChoice(el, cursor)); + out.setChoice(parseHarmonyChordGroupChoice(el, cursor, context)); } else { @@ -78,7 +84,7 @@ HarmonyChordGroup parseHarmonyChordGroup(pugi::xml_node el, pugi::xml_node &curs } if (cursorIs(cursor, "kind")) { - out.setKind(parseKind(cursor)); + out.setKind(parseKind(cursor, context)); cursor = nextElement(cursor); } else @@ -87,17 +93,17 @@ HarmonyChordGroup parseHarmonyChordGroup(pugi::xml_node el, pugi::xml_node &curs } if (cursorIs(cursor, "inversion")) { - out.setInversion(parseInversion(cursor)); + out.setInversion(parseInversion(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "bass")) { - out.setBass(parseBass(cursor)); + out.setBass(parseBass(cursor, context)); cursor = nextElement(cursor); } while (cursorIs(cursor, "degree")) { - out.addDegree(parseDegree(cursor)); + out.addDegree(parseDegree(cursor, context)); cursor = nextElement(cursor); } return out; diff --git a/src/private/mx/core/generated/HarmonyChordGroup.h b/src/private/mx/core/generated/HarmonyChordGroup.h index 984587219..551b8a8e1 100644 --- a/src/private/mx/core/generated/HarmonyChordGroup.h +++ b/src/private/mx/core/generated/HarmonyChordGroup.h @@ -21,6 +21,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A harmony element can contain many stacked chords (e.g. V of II). A sequence of harmony-chord /// groups is used for this type of secondary function, where V of II would be represented by a /// harmony-chord with a 5 numeral followed by a harmony-chord with a 2 numeral. A root is a pitch @@ -59,6 +61,8 @@ class HarmonyChordGroup final /// is the enclosing element, for error paths. HarmonyChordGroup parseHarmonyChordGroup(pugi::xml_node el, pugi::xml_node &cursor); +HarmonyChordGroup parseHarmonyChordGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeHarmonyChordGroup(const HarmonyChordGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/HarmonyChordGroupChoice.cpp b/src/private/mx/core/generated/HarmonyChordGroupChoice.cpp index 237044ca5..9503cd5c8 100644 --- a/src/private/mx/core/generated/HarmonyChordGroupChoice.cpp +++ b/src/private/mx/core/generated/HarmonyChordGroupChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/HarmonyChordGroupChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,22 +32,28 @@ HarmonyChordGroupChoice HarmonyChordGroupChoice::function(StyleText value) } HarmonyChordGroupChoice parseHarmonyChordGroupChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseHarmonyChordGroupChoice(el, cursor, ParseContext{}); +} + +HarmonyChordGroupChoice parseHarmonyChordGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context) { if (cursor && (cursorIs(cursor, "root"))) { - Root value = parseRoot(cursor); + Root value = parseRoot(cursor, context); cursor = nextElement(cursor); return HarmonyChordGroupChoice::root(std::move(value)); } if (cursor && (cursorIs(cursor, "numeral"))) { - Numeral value = parseNumeral(cursor); + Numeral value = parseNumeral(cursor, context); cursor = nextElement(cursor); return HarmonyChordGroupChoice::numeral(std::move(value)); } if (cursor && (cursorIs(cursor, "function"))) { - StyleText value = parseStyleText(cursor); + StyleText value = parseStyleText(cursor, context); cursor = nextElement(cursor); return HarmonyChordGroupChoice::function(std::move(value)); } diff --git a/src/private/mx/core/generated/HarmonyChordGroupChoice.h b/src/private/mx/core/generated/HarmonyChordGroupChoice.h index 86adac49f..98821d09e 100644 --- a/src/private/mx/core/generated/HarmonyChordGroupChoice.h +++ b/src/private/mx/core/generated/HarmonyChordGroupChoice.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -97,6 +99,9 @@ class HarmonyChordGroupChoice final /// the enclosing element, for error paths. HarmonyChordGroupChoice parseHarmonyChordGroupChoice(pugi::xml_node el, pugi::xml_node &cursor); +HarmonyChordGroupChoice parseHarmonyChordGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context); + void serializeHarmonyChordGroupChoice(const HarmonyChordGroupChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/HarmonyType.cpp b/src/private/mx/core/generated/HarmonyType.cpp index cc18287cc..3ffcf7648 100644 --- a/src/private/mx/core/generated/HarmonyType.cpp +++ b/src/private/mx/core/generated/HarmonyType.cpp @@ -48,9 +48,15 @@ bool HarmonyType::tryParse(std::string_view text, HarmonyType &out) noexcept } HarmonyType HarmonyType::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +HarmonyType HarmonyType::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { HarmonyType v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/HarmonyType.h b/src/private/mx/core/generated/HarmonyType.h index f79f44c42..2962630f3 100644 --- a/src/private/mx/core/generated/HarmonyType.h +++ b/src/private/mx/core/generated/HarmonyType.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -44,6 +46,9 @@ class HarmonyType final /// (the import leniency policy; never produces an invalid value). static HarmonyType parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static HarmonyType parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const HarmonyType &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/HarpPedals.cpp b/src/private/mx/core/generated/HarpPedals.cpp index a9e8b971a..762df8f29 100644 --- a/src/private/mx/core/generated/HarpPedals.cpp +++ b/src/private/mx/core/generated/HarpPedals.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/HarpPedals.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -146,6 +147,11 @@ void HarpPedals::setPedalTuning(OneOrMore value) } HarpPedals parseHarpPedals(pugi::xml_node el) +{ + return parseHarpPedals(el, ParseContext{}); +} + +HarpPedals parseHarpPedals(pugi::xml_node el, const ParseContext &context) { HarpPedals out; for (pugi::xml_attribute a : el.attributes()) @@ -157,47 +163,47 @@ HarpPedals parseHarpPedals(pugi::xml_node el) } if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "halign") { - out.setHalign(LeftCenterRight::parse(a.value())); + out.setHalign(parseValue(a.value(), context, el, "halign")); } else if (aname == "valign") { - out.setValign(Valign::parse(a.value())); + out.setValign(parseValue(a.value(), context, el, "valign")); } else if (aname == "id") { @@ -208,22 +214,27 @@ HarpPedals parseHarpPedals(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseHarpPedalsContent(out, el); + parseHarpPedalsContent(out, el, context); return out; } void parseHarpPedalsContent(HarpPedals &out, pugi::xml_node el) +{ + parseHarpPedalsContent(out, el, ParseContext{}); +} + +void parseHarpPedalsContent(HarpPedals &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (!cursorIs(cursor, "pedal-tuning")) { throwMissingOrMisplaced(el, cursor, "pedal-tuning"); } - out.setPedalTuning(OneOrMore{parsePedalTuning(cursor)}); + out.setPedalTuning(OneOrMore{parsePedalTuning(cursor, context)}); cursor = nextElement(cursor); while (cursorIs(cursor, "pedal-tuning")) { - out.addPedalTuning(parsePedalTuning(cursor)); + out.addPedalTuning(parsePedalTuning(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/HarpPedals.h b/src/private/mx/core/generated/HarpPedals.h index 08792a3ba..c4ba49421 100644 --- a/src/private/mx/core/generated/HarpPedals.h +++ b/src/private/mx/core/generated/HarpPedals.h @@ -28,6 +28,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The harp-pedals type is used to create harp pedal diagrams. The pedal-step and pedal-alter /// elements use the same values as the step and alter elements. For easiest reading, the /// pedal-tuning elements should follow standard harp pedal order, with pedal-step values of D, C, B, @@ -84,8 +86,12 @@ class HarpPedals final HarpPedals parseHarpPedals(pugi::xml_node el); +HarpPedals parseHarpPedals(pugi::xml_node el, const ParseContext &context); + void parseHarpPedalsContent(HarpPedals &out, pugi::xml_node el); +void parseHarpPedalsContent(HarpPedals &out, pugi::xml_node el, const ParseContext &context); + void serializeHarpPedals(const HarpPedals &v, pugi::xml_node parent, const char *tag); void serializeHarpPedalsContent(const HarpPedals &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/HeelToe.cpp b/src/private/mx/core/generated/HeelToe.cpp index a38182115..79f4c1239 100644 --- a/src/private/mx/core/generated/HeelToe.cpp +++ b/src/private/mx/core/generated/HeelToe.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/HeelToe.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -21,6 +22,11 @@ void HeelToe::setSubstitution(std::optional value) } HeelToe parseHeelToe(pugi::xml_node el) +{ + return parseHeelToe(el, ParseContext{}); +} + +HeelToe parseHeelToe(pugi::xml_node el, const ParseContext &context) { HeelToe out; for (pugi::xml_attribute a : el.attributes()) @@ -32,54 +38,54 @@ HeelToe parseHeelToe(pugi::xml_node el) } if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else if (aname == "substitution") { - out.setSubstitution(YesNo::parse(a.value())); + out.setSubstitution(parseValue(a.value(), context, el, "substitution")); } else { throwUnknownAttribute(el, a.name()); } } - parseEmptyPlacementContent(out, el); + parseEmptyPlacementContent(out, el, context); return out; } diff --git a/src/private/mx/core/generated/HeelToe.h b/src/private/mx/core/generated/HeelToe.h index 58e3b0b6d..ae38618dc 100644 --- a/src/private/mx/core/generated/HeelToe.h +++ b/src/private/mx/core/generated/HeelToe.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The heel and toe elements are used with organ pedals. The substitution value is "no" if the /// attribute is not present. /// The schema's complexContent extension: non-polymorphic public @@ -33,6 +35,8 @@ class HeelToe : public EmptyPlacement HeelToe parseHeelToe(pugi::xml_node el); +HeelToe parseHeelToe(pugi::xml_node el, const ParseContext &context); + void serializeHeelToe(const HeelToe &v, pugi::xml_node parent, const char *tag); } // namespace mx::core diff --git a/src/private/mx/core/generated/Hole.cpp b/src/private/mx/core/generated/Hole.cpp index b0670004d..6fa4fe15a 100644 --- a/src/private/mx/core/generated/Hole.cpp +++ b/src/private/mx/core/generated/Hole.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Hole.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -141,6 +142,11 @@ void Hole::setHoleShape(std::optional value) } Hole parseHole(pugi::xml_node el) +{ + return parseHole(el, ParseContext{}); +} + +Hole parseHole(pugi::xml_node el, const ParseContext &context) { Hole out; for (pugi::xml_attribute a : el.attributes()) @@ -152,54 +158,59 @@ Hole parseHole(pugi::xml_node el) } if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else { throwUnknownAttribute(el, a.name()); } } - parseHoleContent(out, el); + parseHoleContent(out, el, context); return out; } void parseHoleContent(Hole &out, pugi::xml_node el) +{ + parseHoleContent(out, el, ParseContext{}); +} + +void parseHoleContent(Hole &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "hole-type")) @@ -209,7 +220,7 @@ void parseHoleContent(Hole &out, pugi::xml_node el) } if (cursorIs(cursor, "hole-closed")) { - out.setHoleClosed(parseHoleClosed(cursor)); + out.setHoleClosed(parseHoleClosed(cursor, context)); cursor = nextElement(cursor); } else diff --git a/src/private/mx/core/generated/Hole.h b/src/private/mx/core/generated/Hole.h index 2b11c296f..748bafc73 100644 --- a/src/private/mx/core/generated/Hole.h +++ b/src/private/mx/core/generated/Hole.h @@ -24,6 +24,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The hole type represents the symbols used for woodwind and brass fingerings as well as other /// notations. /// Content fields mirror the schema grammar in declaration order; the @@ -77,8 +79,12 @@ class Hole final Hole parseHole(pugi::xml_node el); +Hole parseHole(pugi::xml_node el, const ParseContext &context); + void parseHoleContent(Hole &out, pugi::xml_node el); +void parseHoleContent(Hole &out, pugi::xml_node el, const ParseContext &context); + void serializeHole(const Hole &v, pugi::xml_node parent, const char *tag); void serializeHoleContent(const Hole &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/HoleClosed.cpp b/src/private/mx/core/generated/HoleClosed.cpp index 8c8b8df06..9d0a73ed4 100644 --- a/src/private/mx/core/generated/HoleClosed.cpp +++ b/src/private/mx/core/generated/HoleClosed.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/HoleClosed.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void HoleClosed::setValue(HoleClosedValue value) } HoleClosed parseHoleClosed(pugi::xml_node el) +{ + return parseHoleClosed(el, ParseContext{}); +} + +HoleClosed parseHoleClosed(pugi::xml_node el, const ParseContext &context) { HoleClosed out; for (pugi::xml_attribute a : el.attributes()) @@ -42,20 +48,25 @@ HoleClosed parseHoleClosed(pugi::xml_node el) } if (aname == "location") { - out.setLocation(HoleClosedLocation::parse(a.value())); + out.setLocation(parseValue(a.value(), context, el, "location")); } else { throwUnknownAttribute(el, a.name()); } } - parseHoleClosedContent(out, el); + parseHoleClosedContent(out, el, context); return out; } void parseHoleClosedContent(HoleClosed &out, pugi::xml_node el) { - out.setValue(HoleClosedValue::parse(childText(el))); + parseHoleClosedContent(out, el, ParseContext{}); +} + +void parseHoleClosedContent(HoleClosed &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/HoleClosed.h b/src/private/mx/core/generated/HoleClosed.h index e12c478de..a57301ea2 100644 --- a/src/private/mx/core/generated/HoleClosed.h +++ b/src/private/mx/core/generated/HoleClosed.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The hole-closed type represents whether the hole is closed, open, or half-open. The optional /// location attribute indicates which portion of the hole is filled in when the element value is /// half. @@ -35,8 +37,12 @@ class HoleClosed final HoleClosed parseHoleClosed(pugi::xml_node el); +HoleClosed parseHoleClosed(pugi::xml_node el, const ParseContext &context); + void parseHoleClosedContent(HoleClosed &out, pugi::xml_node el); +void parseHoleClosedContent(HoleClosed &out, pugi::xml_node el, const ParseContext &context); + void serializeHoleClosed(const HoleClosed &v, pugi::xml_node parent, const char *tag); void serializeHoleClosedContent(const HoleClosed &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/HoleClosedLocation.cpp b/src/private/mx/core/generated/HoleClosedLocation.cpp index 41383ca0d..a6e56f8eb 100644 --- a/src/private/mx/core/generated/HoleClosedLocation.cpp +++ b/src/private/mx/core/generated/HoleClosedLocation.cpp @@ -54,9 +54,15 @@ bool HoleClosedLocation::tryParse(std::string_view text, HoleClosedLocation &out } HoleClosedLocation HoleClosedLocation::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +HoleClosedLocation HoleClosedLocation::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { HoleClosedLocation v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/HoleClosedLocation.h b/src/private/mx/core/generated/HoleClosedLocation.h index e9ba43d58..8d3b82a4d 100644 --- a/src/private/mx/core/generated/HoleClosedLocation.h +++ b/src/private/mx/core/generated/HoleClosedLocation.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -45,6 +47,9 @@ class HoleClosedLocation final /// (the import leniency policy; never produces an invalid value). static HoleClosedLocation parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static HoleClosedLocation parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const HoleClosedLocation &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/HoleClosedValue.cpp b/src/private/mx/core/generated/HoleClosedValue.cpp index 6d86cef50..170ef6d85 100644 --- a/src/private/mx/core/generated/HoleClosedValue.cpp +++ b/src/private/mx/core/generated/HoleClosedValue.cpp @@ -48,9 +48,15 @@ bool HoleClosedValue::tryParse(std::string_view text, HoleClosedValue &out) noex } HoleClosedValue HoleClosedValue::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +HoleClosedValue HoleClosedValue::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { HoleClosedValue v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/HoleClosedValue.h b/src/private/mx/core/generated/HoleClosedValue.h index 6c015a95c..31973bb5f 100644 --- a/src/private/mx/core/generated/HoleClosedValue.h +++ b/src/private/mx/core/generated/HoleClosedValue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -42,6 +44,9 @@ class HoleClosedValue final /// (the import leniency policy; never produces an invalid value). static HoleClosedValue parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static HoleClosedValue parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const HoleClosedValue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/HorizontalTurn.cpp b/src/private/mx/core/generated/HorizontalTurn.cpp index 2efb4e60b..806d467ab 100644 --- a/src/private/mx/core/generated/HorizontalTurn.cpp +++ b/src/private/mx/core/generated/HorizontalTurn.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/HorizontalTurn.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -191,6 +192,11 @@ void HorizontalTurn::setLastBeat(std::optional value) } HorizontalTurn parseHorizontalTurn(pugi::xml_node el) +{ + return parseHorizontalTurn(el, ParseContext{}); +} + +HorizontalTurn parseHorizontalTurn(pugi::xml_node el, const ParseContext &context) { HorizontalTurn out; for (pugi::xml_attribute a : el.attributes()) @@ -202,88 +208,94 @@ HorizontalTurn parseHorizontalTurn(pugi::xml_node el) } if (aname == "slash") { - out.setSlash(YesNo::parse(a.value())); + out.setSlash(parseValue(a.value(), context, el, "slash")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else if (aname == "start-note") { - out.setStartNote(StartNote::parse(a.value())); + out.setStartNote(parseValue(a.value(), context, el, "start-note")); } else if (aname == "trill-step") { - out.setTrillStep(TrillStep::parse(a.value())); + out.setTrillStep(parseValue(a.value(), context, el, "trill-step")); } else if (aname == "two-note-turn") { - out.setTwoNoteTurn(TwoNoteTurn::parse(a.value())); + out.setTwoNoteTurn(parseValue(a.value(), context, el, "two-note-turn")); } else if (aname == "accelerate") { - out.setAccelerate(YesNo::parse(a.value())); + out.setAccelerate(parseValue(a.value(), context, el, "accelerate")); } else if (aname == "beats") { - out.setBeats(TrillBeats::parse(a.value())); + out.setBeats(parseValue(a.value(), context, el, "beats")); } else if (aname == "second-beat") { - out.setSecondBeat(Percent::parse(a.value())); + out.setSecondBeat(parseValue(a.value(), context, el, "second-beat")); } else if (aname == "last-beat") { - out.setLastBeat(Percent::parse(a.value())); + out.setLastBeat(parseValue(a.value(), context, el, "last-beat")); } else { throwUnknownAttribute(el, a.name()); } } - parseHorizontalTurnContent(out, el); + parseHorizontalTurnContent(out, el, context); return out; } void parseHorizontalTurnContent(HorizontalTurn &out, pugi::xml_node el) +{ + parseHorizontalTurnContent(out, el, ParseContext{}); +} + +void parseHorizontalTurnContent(HorizontalTurn &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/HorizontalTurn.h b/src/private/mx/core/generated/HorizontalTurn.h index 2a58360b5..0cf5ec7a7 100644 --- a/src/private/mx/core/generated/HorizontalTurn.h +++ b/src/private/mx/core/generated/HorizontalTurn.h @@ -27,6 +27,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The horizontal-turn type represents turn elements that are horizontal rather than vertical. These /// are empty elements with print-style, placement, trill-sound, and slash attributes. If the slash /// attribute is yes, then a vertical line is used to slash the turn. It is no if not specified. @@ -94,8 +96,12 @@ class HorizontalTurn final HorizontalTurn parseHorizontalTurn(pugi::xml_node el); +HorizontalTurn parseHorizontalTurn(pugi::xml_node el, const ParseContext &context); + void parseHorizontalTurnContent(HorizontalTurn &out, pugi::xml_node el); +void parseHorizontalTurnContent(HorizontalTurn &out, pugi::xml_node el, const ParseContext &context); + void serializeHorizontalTurn(const HorizontalTurn &v, pugi::xml_node parent, const char *tag); void serializeHorizontalTurnContent(const HorizontalTurn &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Identification.cpp b/src/private/mx/core/generated/Identification.cpp index 01b3aba09..ee1de1bc2 100644 --- a/src/private/mx/core/generated/Identification.cpp +++ b/src/private/mx/core/generated/Identification.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Identification.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -86,6 +87,11 @@ void Identification::setMiscellaneous(std::optional value) } Identification parseIdentification(pugi::xml_node el) +{ + return parseIdentification(el, ParseContext{}); +} + +Identification parseIdentification(pugi::xml_node el, const ParseContext &context) { Identification out; for (pugi::xml_attribute a : el.attributes()) @@ -97,26 +103,31 @@ Identification parseIdentification(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseIdentificationContent(out, el); + parseIdentificationContent(out, el, context); return out; } void parseIdentificationContent(Identification &out, pugi::xml_node el) +{ + parseIdentificationContent(out, el, ParseContext{}); +} + +void parseIdentificationContent(Identification &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); while (cursorIs(cursor, "creator")) { - out.addCreator(parseTypedText(cursor)); + out.addCreator(parseTypedText(cursor, context)); cursor = nextElement(cursor); } while (cursorIs(cursor, "rights")) { - out.addRights(parseTypedText(cursor)); + out.addRights(parseTypedText(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "encoding")) { - out.setEncoding(parseEncoding(cursor)); + out.setEncoding(parseEncoding(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "source")) @@ -126,12 +137,12 @@ void parseIdentificationContent(Identification &out, pugi::xml_node el) } while (cursorIs(cursor, "relation")) { - out.addRelation(parseTypedText(cursor)); + out.addRelation(parseTypedText(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "miscellaneous")) { - out.setMiscellaneous(parseMiscellaneous(cursor)); + out.setMiscellaneous(parseMiscellaneous(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/Identification.h b/src/private/mx/core/generated/Identification.h index 198699082..e8641dd2e 100644 --- a/src/private/mx/core/generated/Identification.h +++ b/src/private/mx/core/generated/Identification.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Identification contains basic metadata about the score. It includes information that may apply at /// a score-wide, movement-wide, or part-wide level. The creator, rights, source, and relation /// elements are based on Dublin Core. @@ -55,8 +57,12 @@ class Identification final Identification parseIdentification(pugi::xml_node el); +Identification parseIdentification(pugi::xml_node el, const ParseContext &context); + void parseIdentificationContent(Identification &out, pugi::xml_node el); +void parseIdentificationContent(Identification &out, pugi::xml_node el, const ParseContext &context); + void serializeIdentification(const Identification &v, pugi::xml_node parent, const char *tag); void serializeIdentificationContent(const Identification &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Image.cpp b/src/private/mx/core/generated/Image.cpp index f19babe16..bff3c5ea7 100644 --- a/src/private/mx/core/generated/Image.cpp +++ b/src/private/mx/core/generated/Image.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Image.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -121,6 +122,11 @@ void Image::setID(std::optional value) } Image parseImage(pugi::xml_node el) +{ + return parseImage(el, ParseContext{}); +} + +Image parseImage(pugi::xml_node el, const ParseContext &context) { Image out; bool seen_source = false; @@ -144,35 +150,35 @@ Image parseImage(pugi::xml_node el) } else if (aname == "height") { - out.setHeight(Tenths::parse(a.value())); + out.setHeight(parseValue(a.value(), context, el, "height")); } else if (aname == "width") { - out.setWidth(Tenths::parse(a.value())); + out.setWidth(parseValue(a.value(), context, el, "width")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "halign") { - out.setHalign(LeftCenterRight::parse(a.value())); + out.setHalign(parseValue(a.value(), context, el, "halign")); } else if (aname == "valign") { - out.setValign(ValignImage::parse(a.value())); + out.setValign(parseValue(a.value(), context, el, "valign")); } else if (aname == "id") { @@ -191,13 +197,19 @@ Image parseImage(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseImageContent(out, el); + parseImageContent(out, el, context); return out; } void parseImageContent(Image &out, pugi::xml_node el) +{ + parseImageContent(out, el, ParseContext{}); +} + +void parseImageContent(Image &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Image.h b/src/private/mx/core/generated/Image.h index 7cd1bc684..7f8bf17c7 100644 --- a/src/private/mx/core/generated/Image.h +++ b/src/private/mx/core/generated/Image.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The image type is used to include graphical images in a score. class Image final { @@ -63,8 +65,12 @@ class Image final Image parseImage(pugi::xml_node el); +Image parseImage(pugi::xml_node el, const ParseContext &context); + void parseImageContent(Image &out, pugi::xml_node el); +void parseImageContent(Image &out, pugi::xml_node el, const ParseContext &context); + void serializeImage(const Image &v, pugi::xml_node parent, const char *tag); void serializeImageContent(const Image &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Instrument.cpp b/src/private/mx/core/generated/Instrument.cpp index ec72a97a6..f41526d23 100644 --- a/src/private/mx/core/generated/Instrument.cpp +++ b/src/private/mx/core/generated/Instrument.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Instrument.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -21,6 +22,11 @@ void Instrument::setID(Token value) } Instrument parseInstrument(pugi::xml_node el) +{ + return parseInstrument(el, ParseContext{}); +} + +Instrument parseInstrument(pugi::xml_node el, const ParseContext &context) { Instrument out; bool seen_id = false; @@ -45,13 +51,19 @@ Instrument parseInstrument(pugi::xml_node el) { throwMissingAttribute(el, "id"); } - parseInstrumentContent(out, el); + parseInstrumentContent(out, el, context); return out; } void parseInstrumentContent(Instrument &out, pugi::xml_node el) +{ + parseInstrumentContent(out, el, ParseContext{}); +} + +void parseInstrumentContent(Instrument &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Instrument.h b/src/private/mx/core/generated/Instrument.h index 201ac77b2..3d9d8734e 100644 --- a/src/private/mx/core/generated/Instrument.h +++ b/src/private/mx/core/generated/Instrument.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The instrument type distinguishes between score-instrument elements in a score-part. The id /// attribute is an IDREF back to the score-instrument ID. If multiple score-instruments are /// specified in a score-part, there should be an instrument element for each note in the part. Notes @@ -33,8 +35,12 @@ class Instrument final Instrument parseInstrument(pugi::xml_node el); +Instrument parseInstrument(pugi::xml_node el, const ParseContext &context); + void parseInstrumentContent(Instrument &out, pugi::xml_node el); +void parseInstrumentContent(Instrument &out, pugi::xml_node el, const ParseContext &context); + void serializeInstrument(const Instrument &v, pugi::xml_node parent, const char *tag); void serializeInstrumentContent(const Instrument &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/InstrumentChange.cpp b/src/private/mx/core/generated/InstrumentChange.cpp index 034b01976..811d477ce 100644 --- a/src/private/mx/core/generated/InstrumentChange.cpp +++ b/src/private/mx/core/generated/InstrumentChange.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/InstrumentChange.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void InstrumentChange::setVirtualInstrumentData(VirtualInstrumentDataGroup value } InstrumentChange parseInstrumentChange(pugi::xml_node el) +{ + return parseInstrumentChange(el, ParseContext{}); +} + +InstrumentChange parseInstrumentChange(pugi::xml_node el, const ParseContext &context) { InstrumentChange out; bool seen_id = false; @@ -55,17 +61,22 @@ InstrumentChange parseInstrumentChange(pugi::xml_node el) { throwMissingAttribute(el, "id"); } - parseInstrumentChangeContent(out, el); + parseInstrumentChangeContent(out, el, context); return out; } void parseInstrumentChangeContent(InstrumentChange &out, pugi::xml_node el) +{ + parseInstrumentChangeContent(out, el, ParseContext{}); +} + +void parseInstrumentChangeContent(InstrumentChange &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "instrument-sound") || cursorIs(cursor, "solo") || cursorIs(cursor, "ensemble") || cursorIs(cursor, "virtual-instrument"))) { - out.setVirtualInstrumentData(parseVirtualInstrumentDataGroup(el, cursor)); + out.setVirtualInstrumentData(parseVirtualInstrumentDataGroup(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/InstrumentChange.h b/src/private/mx/core/generated/InstrumentChange.h index cdb7ee51e..3b1b584bf 100644 --- a/src/private/mx/core/generated/InstrumentChange.h +++ b/src/private/mx/core/generated/InstrumentChange.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The instrument-change element type represents a change to the virtual instrument sound for a /// given score-instrument. The id attribute refers to the score-instrument affected by the change. /// All instrument-change child elements can also be initially specified within the score-instrument @@ -41,8 +43,12 @@ class InstrumentChange final InstrumentChange parseInstrumentChange(pugi::xml_node el); +InstrumentChange parseInstrumentChange(pugi::xml_node el, const ParseContext &context); + void parseInstrumentChangeContent(InstrumentChange &out, pugi::xml_node el); +void parseInstrumentChangeContent(InstrumentChange &out, pugi::xml_node el, const ParseContext &context); + void serializeInstrumentChange(const InstrumentChange &v, pugi::xml_node parent, const char *tag); void serializeInstrumentChangeContent(const InstrumentChange &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/InstrumentLink.cpp b/src/private/mx/core/generated/InstrumentLink.cpp index b6cee8096..dc6d61e6d 100644 --- a/src/private/mx/core/generated/InstrumentLink.cpp +++ b/src/private/mx/core/generated/InstrumentLink.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/InstrumentLink.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -21,6 +22,11 @@ void InstrumentLink::setID(Token value) } InstrumentLink parseInstrumentLink(pugi::xml_node el) +{ + return parseInstrumentLink(el, ParseContext{}); +} + +InstrumentLink parseInstrumentLink(pugi::xml_node el, const ParseContext &context) { InstrumentLink out; bool seen_id = false; @@ -45,13 +51,19 @@ InstrumentLink parseInstrumentLink(pugi::xml_node el) { throwMissingAttribute(el, "id"); } - parseInstrumentLinkContent(out, el); + parseInstrumentLinkContent(out, el, context); return out; } void parseInstrumentLinkContent(InstrumentLink &out, pugi::xml_node el) +{ + parseInstrumentLinkContent(out, el, ParseContext{}); +} + +void parseInstrumentLinkContent(InstrumentLink &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/InstrumentLink.h b/src/private/mx/core/generated/InstrumentLink.h index a7549666a..a7160b7e4 100644 --- a/src/private/mx/core/generated/InstrumentLink.h +++ b/src/private/mx/core/generated/InstrumentLink.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Multiple part-link elements can link a condensed part within a score file to multiple MusicXML /// parts files. For example, a "Clarinet 1 and 2" part in a score file could link to separate /// "Clarinet 1" and "Clarinet 2" part files. The instrument-link type distinguish which of the @@ -34,8 +36,12 @@ class InstrumentLink final InstrumentLink parseInstrumentLink(pugi::xml_node el); +InstrumentLink parseInstrumentLink(pugi::xml_node el, const ParseContext &context); + void parseInstrumentLinkContent(InstrumentLink &out, pugi::xml_node el); +void parseInstrumentLinkContent(InstrumentLink &out, pugi::xml_node el, const ParseContext &context); + void serializeInstrumentLink(const InstrumentLink &v, pugi::xml_node parent, const char *tag); void serializeInstrumentLinkContent(const InstrumentLink &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/InstrumentSound.cpp b/src/private/mx/core/generated/InstrumentSound.cpp index d30cd30d9..a77e0be71 100644 --- a/src/private/mx/core/generated/InstrumentSound.cpp +++ b/src/private/mx/core/generated/InstrumentSound.cpp @@ -53,12 +53,20 @@ bool InstrumentSound::tryParse(std::string_view text, InstrumentSound &out) } InstrumentSound InstrumentSound::parse(std::string_view text) +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +InstrumentSound InstrumentSound::parse(std::string_view text, ValueParseOutcome &outcome) { InstrumentSound out; if (tryParse(text, out)) { + outcome = ValueParseOutcome::valid; return out; } + outcome = ValueParseOutcome::invalid; return InstrumentSound::soundID(SoundID::parse(text)); } diff --git a/src/private/mx/core/generated/InstrumentSound.h b/src/private/mx/core/generated/InstrumentSound.h index a471abb9a..3c1f355d8 100644 --- a/src/private/mx/core/generated/InstrumentSound.h +++ b/src/private/mx/core/generated/InstrumentSound.h @@ -2,6 +2,7 @@ #pragma once +#include "mx/core/Lexical.h" #include "mx/core/generated/SoundID.h" #include @@ -69,6 +70,10 @@ class InstrumentSound final /// parse (never produces an invalid value). static InstrumentSound parse(std::string_view text); + /// Lenient, and says whether no member matched or a matched number was + /// clamped. + static InstrumentSound parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const InstrumentSound &other) const = default; private: diff --git a/src/private/mx/core/generated/Interchangeable.cpp b/src/private/mx/core/generated/Interchangeable.cpp index 903e36be3..145dcab28 100644 --- a/src/private/mx/core/generated/Interchangeable.cpp +++ b/src/private/mx/core/generated/Interchangeable.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Interchangeable.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -56,6 +57,11 @@ void Interchangeable::setTimeSignature(OneOrMore value) } Interchangeable parseInterchangeable(pugi::xml_node el) +{ + return parseInterchangeable(el, ParseContext{}); +} + +Interchangeable parseInterchangeable(pugi::xml_node el, const ParseContext &context) { Interchangeable out; for (pugi::xml_attribute a : el.attributes()) @@ -67,37 +73,42 @@ Interchangeable parseInterchangeable(pugi::xml_node el) } if (aname == "symbol") { - out.setSymbol(TimeSymbol::parse(a.value())); + out.setSymbol(parseValue(a.value(), context, el, "symbol")); } else if (aname == "separator") { - out.setSeparator(TimeSeparator::parse(a.value())); + out.setSeparator(parseValue(a.value(), context, el, "separator")); } else { throwUnknownAttribute(el, a.name()); } } - parseInterchangeableContent(out, el); + parseInterchangeableContent(out, el, context); return out; } void parseInterchangeableContent(Interchangeable &out, pugi::xml_node el) +{ + parseInterchangeableContent(out, el, ParseContext{}); +} + +void parseInterchangeableContent(Interchangeable &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "time-relation")) { - out.setTimeRelation(TimeRelation::parse(childText(cursor))); + out.setTimeRelation(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (!(cursor && (cursorIs(cursor, "beats")))) { throwMissingElement(el, "beats"); } - out.setTimeSignature(OneOrMore{parseTimeSignatureGroup(el, cursor)}); + out.setTimeSignature(OneOrMore{parseTimeSignatureGroup(el, cursor, context)}); while (cursor && (cursorIs(cursor, "beats"))) { - out.addTimeSignature(parseTimeSignatureGroup(el, cursor)); + out.addTimeSignature(parseTimeSignatureGroup(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/Interchangeable.h b/src/private/mx/core/generated/Interchangeable.h index c9c0494d4..f3313c9d0 100644 --- a/src/private/mx/core/generated/Interchangeable.h +++ b/src/private/mx/core/generated/Interchangeable.h @@ -21,6 +21,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The interchangeable type is used to represent the second in a pair of interchangeable dual time /// signatures, such as the 6/8 in 3/4 (6/8). A separate symbol attribute value is available compared /// to the time element's symbol attribute, which applies to the first of the dual time signatures. @@ -49,8 +51,12 @@ class Interchangeable final Interchangeable parseInterchangeable(pugi::xml_node el); +Interchangeable parseInterchangeable(pugi::xml_node el, const ParseContext &context); + void parseInterchangeableContent(Interchangeable &out, pugi::xml_node el); +void parseInterchangeableContent(Interchangeable &out, pugi::xml_node el, const ParseContext &context); + void serializeInterchangeable(const Interchangeable &v, pugi::xml_node parent, const char *tag); void serializeInterchangeableContent(const Interchangeable &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Inversion.cpp b/src/private/mx/core/generated/Inversion.cpp index 150c89c9a..dce0b9a7d 100644 --- a/src/private/mx/core/generated/Inversion.cpp +++ b/src/private/mx/core/generated/Inversion.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Inversion.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -121,6 +122,11 @@ void Inversion::setValue(int value) } Inversion parseInversion(pugi::xml_node el) +{ + return parseInversion(el, ParseContext{}); +} + +Inversion parseInversion(pugi::xml_node el, const ParseContext &context) { Inversion out; for (pugi::xml_attribute a : el.attributes()) @@ -136,52 +142,57 @@ Inversion parseInversion(pugi::xml_node el) } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else { throwUnknownAttribute(el, a.name()); } } - parseInversionContent(out, el); + parseInversionContent(out, el, context); return out; } void parseInversionContent(Inversion &out, pugi::xml_node el) { - out.setValue(parseInt(childText(el))); + parseInversionContent(out, el, ParseContext{}); +} + +void parseInversionContent(Inversion &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseIntegerValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Inversion.h b/src/private/mx/core/generated/Inversion.h index 341c719a7..70cdc599d 100644 --- a/src/private/mx/core/generated/Inversion.h +++ b/src/private/mx/core/generated/Inversion.h @@ -20,6 +20,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The inversion type represents harmony inversions. The value is a number indicating which /// inversion is used: 0 for root position, 1 for first inversion, etc. The text attribute indicates /// how the inversion should be displayed in a score. @@ -66,8 +68,12 @@ class Inversion final Inversion parseInversion(pugi::xml_node el); +Inversion parseInversion(pugi::xml_node el, const ParseContext &context); + void parseInversionContent(Inversion &out, pugi::xml_node el); +void parseInversionContent(Inversion &out, pugi::xml_node el, const ParseContext &context); + void serializeInversion(const Inversion &v, pugi::xml_node parent, const char *tag); void serializeInversionContent(const Inversion &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Key.cpp b/src/private/mx/core/generated/Key.cpp index 56cb8cb1f..da1cacb50 100644 --- a/src/private/mx/core/generated/Key.cpp +++ b/src/private/mx/core/generated/Key.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Key.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -156,6 +157,11 @@ void Key::setKeyOctave(std::vector value) } Key parseKey(pugi::xml_node el) +{ + return parseKey(el, ParseContext{}); +} + +Key parseKey(pugi::xml_node el, const ParseContext &context) { Key out; for (pugi::xml_attribute a : el.attributes()) @@ -167,47 +173,47 @@ Key parseKey(pugi::xml_node el) } if (aname == "number") { - out.setNumber(StaffNumber::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "print-object") { - out.setPrintObject(YesNo::parse(a.value())); + out.setPrintObject(parseValue(a.value(), context, el, "print-object")); } else if (aname == "id") { @@ -218,20 +224,25 @@ Key parseKey(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseKeyContent(out, el); + parseKeyContent(out, el, context); return out; } void parseKeyContent(Key &out, pugi::xml_node el) +{ + parseKeyContent(out, el, ParseContext{}); +} + +void parseKeyContent(Key &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "cancel") || cursorIs(cursor, "fifths") || cursorIs(cursor, "key-step"))) { - out.setChoice(parseKeyChoice(el, cursor)); + out.setChoice(parseKeyChoice(el, cursor, context)); } while (cursorIs(cursor, "key-octave")) { - out.addKeyOctave(parseKeyOctave(cursor)); + out.addKeyOctave(parseKeyOctave(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/Key.h b/src/private/mx/core/generated/Key.h index f1bda620d..13741805e 100644 --- a/src/private/mx/core/generated/Key.h +++ b/src/private/mx/core/generated/Key.h @@ -28,6 +28,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The key type represents a key signature. Both traditional and non-traditional key signatures are /// supported. The optional number attribute refers to staff numbers. If absent, the key signature /// applies to all staves in the part. Key signatures appear at the start of each system unless the @@ -87,8 +89,12 @@ class Key final Key parseKey(pugi::xml_node el); +Key parseKey(pugi::xml_node el, const ParseContext &context); + void parseKeyContent(Key &out, pugi::xml_node el); +void parseKeyContent(Key &out, pugi::xml_node el, const ParseContext &context); + void serializeKey(const Key &v, pugi::xml_node parent, const char *tag); void serializeKeyContent(const Key &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/KeyAccidental.cpp b/src/private/mx/core/generated/KeyAccidental.cpp index 092bad9f9..e1661a6ee 100644 --- a/src/private/mx/core/generated/KeyAccidental.cpp +++ b/src/private/mx/core/generated/KeyAccidental.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/KeyAccidental.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void KeyAccidental::setValue(AccidentalValue value) } KeyAccidental parseKeyAccidental(pugi::xml_node el) +{ + return parseKeyAccidental(el, ParseContext{}); +} + +KeyAccidental parseKeyAccidental(pugi::xml_node el, const ParseContext &context) { KeyAccidental out; for (pugi::xml_attribute a : el.attributes()) @@ -42,20 +48,25 @@ KeyAccidental parseKeyAccidental(pugi::xml_node el) } if (aname == "smufl") { - out.setSmufl(SmuflAccidentalGlyphName::parse(a.value())); + out.setSmufl(parseValue(a.value(), context, el, "smufl")); } else { throwUnknownAttribute(el, a.name()); } } - parseKeyAccidentalContent(out, el); + parseKeyAccidentalContent(out, el, context); return out; } void parseKeyAccidentalContent(KeyAccidental &out, pugi::xml_node el) { - out.setValue(AccidentalValue::parse(childText(el))); + parseKeyAccidentalContent(out, el, ParseContext{}); +} + +void parseKeyAccidentalContent(KeyAccidental &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/KeyAccidental.h b/src/private/mx/core/generated/KeyAccidental.h index e36711d48..aa17976fa 100644 --- a/src/private/mx/core/generated/KeyAccidental.h +++ b/src/private/mx/core/generated/KeyAccidental.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The key-accidental type indicates the accidental to be displayed in a non-traditional key /// signature, represented in the same manner as the accidental type without the formatting /// attributes. @@ -35,8 +37,12 @@ class KeyAccidental final KeyAccidental parseKeyAccidental(pugi::xml_node el); +KeyAccidental parseKeyAccidental(pugi::xml_node el, const ParseContext &context); + void parseKeyAccidentalContent(KeyAccidental &out, pugi::xml_node el); +void parseKeyAccidentalContent(KeyAccidental &out, pugi::xml_node el, const ParseContext &context); + void serializeKeyAccidental(const KeyAccidental &v, pugi::xml_node parent, const char *tag); void serializeKeyAccidentalContent(const KeyAccidental &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/KeyChoice.cpp b/src/private/mx/core/generated/KeyChoice.cpp index ef89e7ac3..936e88e16 100644 --- a/src/private/mx/core/generated/KeyChoice.cpp +++ b/src/private/mx/core/generated/KeyChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/KeyChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -26,17 +27,22 @@ KeyChoice KeyChoice::nonTraditionalKey(std::vector value } KeyChoice parseKeyChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseKeyChoice(el, cursor, ParseContext{}); +} + +KeyChoice parseKeyChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "cancel") || cursorIs(cursor, "fifths"))) { - return KeyChoice::traditionalKey(parseTraditionalKeyGroup(el, cursor)); + return KeyChoice::traditionalKey(parseTraditionalKeyGroup(el, cursor, context)); } if (cursor && (cursorIs(cursor, "key-step"))) { std::vector items; while (cursor && (cursorIs(cursor, "key-step"))) { - items.push_back(parseNonTraditionalKeyGroup(el, cursor)); + items.push_back(parseNonTraditionalKeyGroup(el, cursor, context)); } return KeyChoice::nonTraditionalKey(std::move(items)); } diff --git a/src/private/mx/core/generated/KeyChoice.h b/src/private/mx/core/generated/KeyChoice.h index 0c970b174..6aba2d631 100644 --- a/src/private/mx/core/generated/KeyChoice.h +++ b/src/private/mx/core/generated/KeyChoice.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -83,6 +85,8 @@ class KeyChoice final /// the enclosing element, for error paths. KeyChoice parseKeyChoice(pugi::xml_node el, pugi::xml_node &cursor); +KeyChoice parseKeyChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeKeyChoice(const KeyChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/KeyOctave.cpp b/src/private/mx/core/generated/KeyOctave.cpp index a9d6d4d59..e6dee9bc5 100644 --- a/src/private/mx/core/generated/KeyOctave.cpp +++ b/src/private/mx/core/generated/KeyOctave.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/KeyOctave.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,6 +42,11 @@ void KeyOctave::setValue(Octave value) } KeyOctave parseKeyOctave(pugi::xml_node el) +{ + return parseKeyOctave(el, ParseContext{}); +} + +KeyOctave parseKeyOctave(pugi::xml_node el, const ParseContext &context) { KeyOctave out; bool seen_number = false; @@ -54,11 +60,11 @@ KeyOctave parseKeyOctave(pugi::xml_node el) if (aname == "number") { seen_number = true; - out.setNumber(parseInt(a.value())); + out.setNumber(parseIntegerValue(a.value(), context, el, "number")); } else if (aname == "cancel") { - out.setCancel(YesNo::parse(a.value())); + out.setCancel(parseValue(a.value(), context, el, "cancel")); } else { @@ -69,13 +75,18 @@ KeyOctave parseKeyOctave(pugi::xml_node el) { throwMissingAttribute(el, "number"); } - parseKeyOctaveContent(out, el); + parseKeyOctaveContent(out, el, context); return out; } void parseKeyOctaveContent(KeyOctave &out, pugi::xml_node el) { - out.setValue(Octave::parse(childText(el))); + parseKeyOctaveContent(out, el, ParseContext{}); +} + +void parseKeyOctaveContent(KeyOctave &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/KeyOctave.h b/src/private/mx/core/generated/KeyOctave.h index 830f6cb10..de9f09228 100644 --- a/src/private/mx/core/generated/KeyOctave.h +++ b/src/private/mx/core/generated/KeyOctave.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The key-octave type specifies in which octave an element of a key signature appears. The content /// specifies the octave value using the same values as the display-octave element. The number /// attribute is a positive integer that refers to the key signature element in left-to-right order. @@ -42,8 +44,12 @@ class KeyOctave final KeyOctave parseKeyOctave(pugi::xml_node el); +KeyOctave parseKeyOctave(pugi::xml_node el, const ParseContext &context); + void parseKeyOctaveContent(KeyOctave &out, pugi::xml_node el); +void parseKeyOctaveContent(KeyOctave &out, pugi::xml_node el, const ParseContext &context); + void serializeKeyOctave(const KeyOctave &v, pugi::xml_node parent, const char *tag); void serializeKeyOctaveContent(const KeyOctave &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Kind.cpp b/src/private/mx/core/generated/Kind.cpp index 17154de25..d88f42614 100644 --- a/src/private/mx/core/generated/Kind.cpp +++ b/src/private/mx/core/generated/Kind.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Kind.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -181,6 +182,11 @@ void Kind::setValue(KindValue value) } Kind parseKind(pugi::xml_node el) +{ + return parseKind(el, ParseContext{}); +} + +Kind parseKind(pugi::xml_node el, const ParseContext &context) { Kind out; for (pugi::xml_attribute a : el.attributes()) @@ -192,7 +198,7 @@ Kind parseKind(pugi::xml_node el) } if (aname == "use-symbols") { - out.setUseSymbols(YesNo::parse(a.value())); + out.setUseSymbols(parseValue(a.value(), context, el, "use-symbols")); } else if (aname == "text") { @@ -200,72 +206,77 @@ Kind parseKind(pugi::xml_node el) } else if (aname == "stack-degrees") { - out.setStackDegrees(YesNo::parse(a.value())); + out.setStackDegrees(parseValue(a.value(), context, el, "stack-degrees")); } else if (aname == "parentheses-degrees") { - out.setParenthesesDegrees(YesNo::parse(a.value())); + out.setParenthesesDegrees(parseValue(a.value(), context, el, "parentheses-degrees")); } else if (aname == "bracket-degrees") { - out.setBracketDegrees(YesNo::parse(a.value())); + out.setBracketDegrees(parseValue(a.value(), context, el, "bracket-degrees")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "halign") { - out.setHalign(LeftCenterRight::parse(a.value())); + out.setHalign(parseValue(a.value(), context, el, "halign")); } else if (aname == "valign") { - out.setValign(Valign::parse(a.value())); + out.setValign(parseValue(a.value(), context, el, "valign")); } else { throwUnknownAttribute(el, a.name()); } } - parseKindContent(out, el); + parseKindContent(out, el, context); return out; } void parseKindContent(Kind &out, pugi::xml_node el) { - out.setValue(KindValue::parse(childText(el))); + parseKindContent(out, el, ParseContext{}); +} + +void parseKindContent(Kind &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Kind.h b/src/private/mx/core/generated/Kind.h index a9c18cf83..e54ecbf0d 100644 --- a/src/private/mx/core/generated/Kind.h +++ b/src/private/mx/core/generated/Kind.h @@ -24,6 +24,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Kind indicates the type of chord. Degree elements can then add, subtract, or alter from these /// starting points The attributes are used to indicate the formatting of the symbol. Since the kind /// element is the constant in all the harmony-chord groups that can make up a polychord, many @@ -104,8 +106,12 @@ class Kind final Kind parseKind(pugi::xml_node el); +Kind parseKind(pugi::xml_node el, const ParseContext &context); + void parseKindContent(Kind &out, pugi::xml_node el); +void parseKindContent(Kind &out, pugi::xml_node el, const ParseContext &context); + void serializeKind(const Kind &v, pugi::xml_node parent, const char *tag); void serializeKindContent(const Kind &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/KindValue.cpp b/src/private/mx/core/generated/KindValue.cpp index a679ded82..6a7a83b7e 100644 --- a/src/private/mx/core/generated/KindValue.cpp +++ b/src/private/mx/core/generated/KindValue.cpp @@ -228,9 +228,15 @@ bool KindValue::tryParse(std::string_view text, KindValue &out) noexcept } KindValue KindValue::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +KindValue KindValue::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { KindValue v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/KindValue.h b/src/private/mx/core/generated/KindValue.h index b2fb72f81..33c53b844 100644 --- a/src/private/mx/core/generated/KindValue.h +++ b/src/private/mx/core/generated/KindValue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -121,6 +123,9 @@ class KindValue final /// (the import leniency policy; never produces an invalid value). static KindValue parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static KindValue parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const KindValue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/LayoutGroup.cpp b/src/private/mx/core/generated/LayoutGroup.cpp index e2d9faf62..a66e483aa 100644 --- a/src/private/mx/core/generated/LayoutGroup.cpp +++ b/src/private/mx/core/generated/LayoutGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/LayoutGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -46,21 +47,26 @@ void LayoutGroup::setStaffLayout(std::vector value) } LayoutGroup parseLayoutGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseLayoutGroup(el, cursor, ParseContext{}); +} + +LayoutGroup parseLayoutGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { LayoutGroup out; if (cursorIs(cursor, "page-layout")) { - out.setPageLayout(parsePageLayout(cursor)); + out.setPageLayout(parsePageLayout(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "system-layout")) { - out.setSystemLayout(parseSystemLayout(cursor)); + out.setSystemLayout(parseSystemLayout(cursor, context)); cursor = nextElement(cursor); } while (cursorIs(cursor, "staff-layout")) { - out.addStaffLayout(parseStaffLayout(cursor)); + out.addStaffLayout(parseStaffLayout(cursor, context)); cursor = nextElement(cursor); } return out; diff --git a/src/private/mx/core/generated/LayoutGroup.h b/src/private/mx/core/generated/LayoutGroup.h index 7b9a67b8d..01f6d7123 100644 --- a/src/private/mx/core/generated/LayoutGroup.h +++ b/src/private/mx/core/generated/LayoutGroup.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The layout group specifies the sequence of page, system, and staff layout elements that is common /// to both the defaults and print elements. /// A shared content group: transparent on the wire, its @@ -45,6 +47,8 @@ class LayoutGroup final /// is the enclosing element, for error paths. LayoutGroup parseLayoutGroup(pugi::xml_node el, pugi::xml_node &cursor); +LayoutGroup parseLayoutGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeLayoutGroup(const LayoutGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/LeftCenterRight.cpp b/src/private/mx/core/generated/LeftCenterRight.cpp index b171598e7..ce877b777 100644 --- a/src/private/mx/core/generated/LeftCenterRight.cpp +++ b/src/private/mx/core/generated/LeftCenterRight.cpp @@ -48,9 +48,15 @@ bool LeftCenterRight::tryParse(std::string_view text, LeftCenterRight &out) noex } LeftCenterRight LeftCenterRight::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +LeftCenterRight LeftCenterRight::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { LeftCenterRight v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/LeftCenterRight.h b/src/private/mx/core/generated/LeftCenterRight.h index 6e18240d6..663ef67d2 100644 --- a/src/private/mx/core/generated/LeftCenterRight.h +++ b/src/private/mx/core/generated/LeftCenterRight.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -42,6 +44,9 @@ class LeftCenterRight final /// (the import leniency policy; never produces an invalid value). static LeftCenterRight parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static LeftCenterRight parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const LeftCenterRight &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/LeftRight.cpp b/src/private/mx/core/generated/LeftRight.cpp index 341a3c5db..1f361c57b 100644 --- a/src/private/mx/core/generated/LeftRight.cpp +++ b/src/private/mx/core/generated/LeftRight.cpp @@ -42,9 +42,15 @@ bool LeftRight::tryParse(std::string_view text, LeftRight &out) noexcept } LeftRight LeftRight::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +LeftRight LeftRight::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { LeftRight v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/LeftRight.h b/src/private/mx/core/generated/LeftRight.h index 0826331fe..4a672722d 100644 --- a/src/private/mx/core/generated/LeftRight.h +++ b/src/private/mx/core/generated/LeftRight.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -41,6 +43,9 @@ class LeftRight final /// (the import leniency policy; never produces an invalid value). static LeftRight parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static LeftRight parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const LeftRight &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/LeftRightMarginsGroup.cpp b/src/private/mx/core/generated/LeftRightMarginsGroup.cpp index 1d6881a4f..9d3f7d624 100644 --- a/src/private/mx/core/generated/LeftRightMarginsGroup.cpp +++ b/src/private/mx/core/generated/LeftRightMarginsGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/LeftRightMarginsGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,11 +32,16 @@ void LeftRightMarginsGroup::setRightMargin(Tenths value) } LeftRightMarginsGroup parseLeftRightMarginsGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseLeftRightMarginsGroup(el, cursor, ParseContext{}); +} + +LeftRightMarginsGroup parseLeftRightMarginsGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { LeftRightMarginsGroup out; if (cursorIs(cursor, "left-margin")) { - out.setLeftMargin(Tenths::parse(childText(cursor))); + out.setLeftMargin(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -44,7 +50,7 @@ LeftRightMarginsGroup parseLeftRightMarginsGroup(pugi::xml_node el, pugi::xml_no } if (cursorIs(cursor, "right-margin")) { - out.setRightMargin(Tenths::parse(childText(cursor))); + out.setRightMargin(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else diff --git a/src/private/mx/core/generated/LeftRightMarginsGroup.h b/src/private/mx/core/generated/LeftRightMarginsGroup.h index 16b6197f2..f54462f3f 100644 --- a/src/private/mx/core/generated/LeftRightMarginsGroup.h +++ b/src/private/mx/core/generated/LeftRightMarginsGroup.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The left-right-margins group specifies horizontal margins in tenths. /// A shared content group: transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -38,6 +40,9 @@ class LeftRightMarginsGroup final /// is the enclosing element, for error paths. LeftRightMarginsGroup parseLeftRightMarginsGroup(pugi::xml_node el, pugi::xml_node &cursor); +LeftRightMarginsGroup parseLeftRightMarginsGroup(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context); + void serializeLeftRightMarginsGroup(const LeftRightMarginsGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/Level.cpp b/src/private/mx/core/generated/Level.cpp index 2e868fe24..2aa8dc957 100644 --- a/src/private/mx/core/generated/Level.cpp +++ b/src/private/mx/core/generated/Level.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Level.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -71,6 +72,11 @@ void Level::setValue(std::string value) } Level parseLevel(pugi::xml_node el) +{ + return parseLevel(el, ParseContext{}); +} + +Level parseLevel(pugi::xml_node el, const ParseContext &context) { Level out; for (pugi::xml_attribute a : el.attributes()) @@ -82,34 +88,39 @@ Level parseLevel(pugi::xml_node el) } if (aname == "reference") { - out.setReference(YesNo::parse(a.value())); + out.setReference(parseValue(a.value(), context, el, "reference")); } else if (aname == "type") { - out.setType(StartStopSingle::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "parentheses") { - out.setParentheses(YesNo::parse(a.value())); + out.setParentheses(parseValue(a.value(), context, el, "parentheses")); } else if (aname == "bracket") { - out.setBracket(YesNo::parse(a.value())); + out.setBracket(parseValue(a.value(), context, el, "bracket")); } else if (aname == "size") { - out.setSize(SymbolSize::parse(a.value())); + out.setSize(parseValue(a.value(), context, el, "size")); } else { throwUnknownAttribute(el, a.name()); } } - parseLevelContent(out, el); + parseLevelContent(out, el, context); return out; } void parseLevelContent(Level &out, pugi::xml_node el) +{ + parseLevelContent(out, el, ParseContext{}); +} + +void parseLevelContent(Level &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/Level.h b/src/private/mx/core/generated/Level.h index 3cf4c9090..e0e6d4650 100644 --- a/src/private/mx/core/generated/Level.h +++ b/src/private/mx/core/generated/Level.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The level type is used to specify editorial information for different MusicXML elements. The /// content contains identifying and/or descriptive text about the editorial status of the parent /// element. If the reference attribute is yes, this indicates editorial information that is for @@ -53,8 +55,12 @@ class Level final Level parseLevel(pugi::xml_node el); +Level parseLevel(pugi::xml_node el, const ParseContext &context); + void parseLevelContent(Level &out, pugi::xml_node el); +void parseLevelContent(Level &out, pugi::xml_node el, const ParseContext &context); + void serializeLevel(const Level &v, pugi::xml_node parent, const char *tag); void serializeLevelContent(const Level &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/LineDetail.cpp b/src/private/mx/core/generated/LineDetail.cpp index 5f55796a2..6aa1995b8 100644 --- a/src/private/mx/core/generated/LineDetail.cpp +++ b/src/private/mx/core/generated/LineDetail.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/LineDetail.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -61,6 +62,11 @@ void LineDetail::setPrintObject(std::optional value) } LineDetail parseLineDetail(pugi::xml_node el) +{ + return parseLineDetail(el, ParseContext{}); +} + +LineDetail parseLineDetail(pugi::xml_node el, const ParseContext &context) { LineDetail out; bool seen_line = false; @@ -74,23 +80,23 @@ LineDetail parseLineDetail(pugi::xml_node el) if (aname == "line") { seen_line = true; - out.setLine(StaffLine::parse(a.value())); + out.setLine(parseValue(a.value(), context, el, "line")); } else if (aname == "width") { - out.setWidth(Tenths::parse(a.value())); + out.setWidth(parseValue(a.value(), context, el, "width")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "line-type") { - out.setLineType(LineType::parse(a.value())); + out.setLineType(parseValue(a.value(), context, el, "line-type")); } else if (aname == "print-object") { - out.setPrintObject(YesNo::parse(a.value())); + out.setPrintObject(parseValue(a.value(), context, el, "print-object")); } else { @@ -101,13 +107,19 @@ LineDetail parseLineDetail(pugi::xml_node el) { throwMissingAttribute(el, "line"); } - parseLineDetailContent(out, el); + parseLineDetailContent(out, el, context); return out; } void parseLineDetailContent(LineDetail &out, pugi::xml_node el) +{ + parseLineDetailContent(out, el, ParseContext{}); +} + +void parseLineDetailContent(LineDetail &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/LineDetail.h b/src/private/mx/core/generated/LineDetail.h index de27d3105..fc222f99c 100644 --- a/src/private/mx/core/generated/LineDetail.h +++ b/src/private/mx/core/generated/LineDetail.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// If the staff-lines element is present, the appearance of each line may be individually specified /// with a line-detail type. Staff lines are numbered from bottom to top. The print-object attribute /// allows lines to be hidden within a staff. This is used in special situations such as a @@ -51,8 +53,12 @@ class LineDetail final LineDetail parseLineDetail(pugi::xml_node el); +LineDetail parseLineDetail(pugi::xml_node el, const ParseContext &context); + void parseLineDetailContent(LineDetail &out, pugi::xml_node el); +void parseLineDetailContent(LineDetail &out, pugi::xml_node el, const ParseContext &context); + void serializeLineDetail(const LineDetail &v, pugi::xml_node parent, const char *tag); void serializeLineDetailContent(const LineDetail &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/LineEnd.cpp b/src/private/mx/core/generated/LineEnd.cpp index 89a16b59b..078c87467 100644 --- a/src/private/mx/core/generated/LineEnd.cpp +++ b/src/private/mx/core/generated/LineEnd.cpp @@ -56,9 +56,15 @@ bool LineEnd::tryParse(std::string_view text, LineEnd &out) noexcept } LineEnd LineEnd::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +LineEnd LineEnd::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { LineEnd v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/LineEnd.h b/src/private/mx/core/generated/LineEnd.h index a383333ed..a66a95d0d 100644 --- a/src/private/mx/core/generated/LineEnd.h +++ b/src/private/mx/core/generated/LineEnd.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -47,6 +49,9 @@ class LineEnd final /// (the import leniency policy; never produces an invalid value). static LineEnd parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static LineEnd parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const LineEnd &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/LineLength.cpp b/src/private/mx/core/generated/LineLength.cpp index 3367d1f0b..e691b1dde 100644 --- a/src/private/mx/core/generated/LineLength.cpp +++ b/src/private/mx/core/generated/LineLength.cpp @@ -48,9 +48,15 @@ bool LineLength::tryParse(std::string_view text, LineLength &out) noexcept } LineLength LineLength::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +LineLength LineLength::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { LineLength v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/LineLength.h b/src/private/mx/core/generated/LineLength.h index 479e090f1..da2e7050c 100644 --- a/src/private/mx/core/generated/LineLength.h +++ b/src/private/mx/core/generated/LineLength.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -43,6 +45,9 @@ class LineLength final /// (the import leniency policy; never produces an invalid value). static LineLength parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static LineLength parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const LineLength &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/LineShape.cpp b/src/private/mx/core/generated/LineShape.cpp index 9b202405b..80844191e 100644 --- a/src/private/mx/core/generated/LineShape.cpp +++ b/src/private/mx/core/generated/LineShape.cpp @@ -42,9 +42,15 @@ bool LineShape::tryParse(std::string_view text, LineShape &out) noexcept } LineShape LineShape::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +LineShape LineShape::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { LineShape v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/LineShape.h b/src/private/mx/core/generated/LineShape.h index c87596ae2..7f262468d 100644 --- a/src/private/mx/core/generated/LineShape.h +++ b/src/private/mx/core/generated/LineShape.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -40,6 +42,9 @@ class LineShape final /// (the import leniency policy; never produces an invalid value). static LineShape parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static LineShape parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const LineShape &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/LineType.cpp b/src/private/mx/core/generated/LineType.cpp index cd878b70b..cbc6e2a68 100644 --- a/src/private/mx/core/generated/LineType.cpp +++ b/src/private/mx/core/generated/LineType.cpp @@ -54,9 +54,15 @@ bool LineType::tryParse(std::string_view text, LineType &out) noexcept } LineType LineType::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +LineType LineType::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { LineType v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/LineType.h b/src/private/mx/core/generated/LineType.h index b26bd7b6f..bc6687f30 100644 --- a/src/private/mx/core/generated/LineType.h +++ b/src/private/mx/core/generated/LineType.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -44,6 +46,9 @@ class LineType final /// (the import leniency policy; never produces an invalid value). static LineType parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static LineType parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const LineType &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/LineWidth.cpp b/src/private/mx/core/generated/LineWidth.cpp index 372546138..f442128ab 100644 --- a/src/private/mx/core/generated/LineWidth.cpp +++ b/src/private/mx/core/generated/LineWidth.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/LineWidth.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void LineWidth::setValue(Tenths value) } LineWidth parseLineWidth(pugi::xml_node el) +{ + return parseLineWidth(el, ParseContext{}); +} + +LineWidth parseLineWidth(pugi::xml_node el, const ParseContext &context) { LineWidth out; bool seen_type = false; @@ -44,7 +50,7 @@ LineWidth parseLineWidth(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(LineWidthType::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else { @@ -55,13 +61,18 @@ LineWidth parseLineWidth(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseLineWidthContent(out, el); + parseLineWidthContent(out, el, context); return out; } void parseLineWidthContent(LineWidth &out, pugi::xml_node el) { - out.setValue(Tenths::parse(childText(el))); + parseLineWidthContent(out, el, ParseContext{}); +} + +void parseLineWidthContent(LineWidth &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/LineWidth.h b/src/private/mx/core/generated/LineWidth.h index 8a3ee1157..9cbdcb27a 100644 --- a/src/private/mx/core/generated/LineWidth.h +++ b/src/private/mx/core/generated/LineWidth.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The line-width type indicates the width of a line type in tenths. The type attribute defines what /// type of line is being defined. Values include beam, bracket, dashes, enclosure, ending, extend, /// heavy barline, leger, light barline, octave shift, pedal, slur middle, slur tip, staff, stem, tie @@ -36,8 +38,12 @@ class LineWidth final LineWidth parseLineWidth(pugi::xml_node el); +LineWidth parseLineWidth(pugi::xml_node el, const ParseContext &context); + void parseLineWidthContent(LineWidth &out, pugi::xml_node el); +void parseLineWidthContent(LineWidth &out, pugi::xml_node el, const ParseContext &context); + void serializeLineWidth(const LineWidth &v, pugi::xml_node parent, const char *tag); void serializeLineWidthContent(const LineWidth &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/LineWidthType.cpp b/src/private/mx/core/generated/LineWidthType.cpp index 3804343ae..4f31ab1cd 100644 --- a/src/private/mx/core/generated/LineWidthType.cpp +++ b/src/private/mx/core/generated/LineWidthType.cpp @@ -32,4 +32,11 @@ LineWidthType LineWidthType::parse(std::string_view text) return LineWidthType{std::string{text}}; } +LineWidthType LineWidthType::parse(std::string_view text, ValueParseOutcome &outcome) +{ + LineWidthType out{std::string{text}}; + outcome = out.value() == text ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; +} + } // namespace mx::core diff --git a/src/private/mx/core/generated/LineWidthType.h b/src/private/mx/core/generated/LineWidthType.h index 13cb46ba1..06784226f 100644 --- a/src/private/mx/core/generated/LineWidthType.h +++ b/src/private/mx/core/generated/LineWidthType.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -38,6 +40,9 @@ class LineWidthType final static LineWidthType parse(std::string_view text); + /// Says whether the text had to be repaired. + static LineWidthType parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const LineWidthType &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Link.cpp b/src/private/mx/core/generated/Link.cpp index defca5d1a..c8ab249af 100644 --- a/src/private/mx/core/generated/Link.cpp +++ b/src/private/mx/core/generated/Link.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Link.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -141,6 +142,11 @@ void Link::setRelativeY(std::optional value) } Link parseLink(pugi::xml_node el) +{ + return parseLink(el, ParseContext{}); +} + +Link parseLink(pugi::xml_node el, const ParseContext &context) { Link out; bool seen_xlinkHref = false; @@ -186,23 +192,23 @@ Link parseLink(pugi::xml_node el) } else if (aname == "position") { - out.setPosition(parseInt(a.value())); + out.setPosition(parseIntegerValue(a.value(), context, el, "position")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else { @@ -213,13 +219,19 @@ Link parseLink(pugi::xml_node el) { throwMissingAttribute(el, "xlink:href"); } - parseLinkContent(out, el); + parseLinkContent(out, el, context); return out; } void parseLinkContent(Link &out, pugi::xml_node el) +{ + parseLinkContent(out, el, ParseContext{}); +} + +void parseLinkContent(Link &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Link.h b/src/private/mx/core/generated/Link.h index 5adf7f6ca..54f5088d4 100644 --- a/src/private/mx/core/generated/Link.h +++ b/src/private/mx/core/generated/Link.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The link type serves as an outgoing simple XLink. If a relative link is used within a document /// that is part of a compressed MusicXML file, the link is relative to the root folder of the zip /// file. @@ -69,8 +71,12 @@ class Link final Link parseLink(pugi::xml_node el); +Link parseLink(pugi::xml_node el, const ParseContext &context); + void parseLinkContent(Link &out, pugi::xml_node el); +void parseLinkContent(Link &out, pugi::xml_node el, const ParseContext &context); + void serializeLink(const Link &v, pugi::xml_node parent, const char *tag); void serializeLinkContent(const Link &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Listen.cpp b/src/private/mx/core/generated/Listen.cpp index d56bcffd5..57fcfe8bf 100644 --- a/src/private/mx/core/generated/Listen.cpp +++ b/src/private/mx/core/generated/Listen.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Listen.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -26,6 +27,11 @@ void Listen::setChoice(OneOrMore value) } Listen parseListen(pugi::xml_node el) +{ + return parseListen(el, ParseContext{}); +} + +Listen parseListen(pugi::xml_node el, const ParseContext &context) { Listen out; for (pugi::xml_attribute a : el.attributes()) @@ -37,21 +43,26 @@ Listen parseListen(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseListenContent(out, el); + parseListenContent(out, el, context); return out; } void parseListenContent(Listen &out, pugi::xml_node el) +{ + parseListenContent(out, el, ParseContext{}); +} + +void parseListenContent(Listen &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (!(cursor && (cursorIs(cursor, "assess") || cursorIs(cursor, "wait") || cursorIs(cursor, "other-listen")))) { throwMissingElement(el, "assess"); } - out.setChoice(OneOrMore{parseListenChoice(el, cursor)}); + out.setChoice(OneOrMore{parseListenChoice(el, cursor, context)}); while (cursor && (cursorIs(cursor, "assess") || cursorIs(cursor, "wait") || cursorIs(cursor, "other-listen"))) { - out.addChoice(parseListenChoice(el, cursor)); + out.addChoice(parseListenChoice(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/Listen.h b/src/private/mx/core/generated/Listen.h index c390b3c6b..6a876eb48 100644 --- a/src/private/mx/core/generated/Listen.h +++ b/src/private/mx/core/generated/Listen.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The listen and listening types, new in Version 4.0, specify different ways that a score following /// or machine listening application can interact with a performer. The listen type handles /// interactions that are specific to a note. If multiple child elements of the same type are @@ -38,8 +40,12 @@ class Listen final Listen parseListen(pugi::xml_node el); +Listen parseListen(pugi::xml_node el, const ParseContext &context); + void parseListenContent(Listen &out, pugi::xml_node el); +void parseListenContent(Listen &out, pugi::xml_node el, const ParseContext &context); + void serializeListen(const Listen &v, pugi::xml_node parent, const char *tag); void serializeListenContent(const Listen &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/ListenChoice.cpp b/src/private/mx/core/generated/ListenChoice.cpp index 266555008..dbf2c0585 100644 --- a/src/private/mx/core/generated/ListenChoice.cpp +++ b/src/private/mx/core/generated/ListenChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/ListenChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,22 +32,27 @@ ListenChoice ListenChoice::otherListen(OtherListening value) } ListenChoice parseListenChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseListenChoice(el, cursor, ParseContext{}); +} + +ListenChoice parseListenChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "assess"))) { - Assess value = parseAssess(cursor); + Assess value = parseAssess(cursor, context); cursor = nextElement(cursor); return ListenChoice::assess(std::move(value)); } if (cursor && (cursorIs(cursor, "wait"))) { - Wait value = parseWait(cursor); + Wait value = parseWait(cursor, context); cursor = nextElement(cursor); return ListenChoice::wait(std::move(value)); } if (cursor && (cursorIs(cursor, "other-listen"))) { - OtherListening value = parseOtherListening(cursor); + OtherListening value = parseOtherListening(cursor, context); cursor = nextElement(cursor); return ListenChoice::otherListen(std::move(value)); } diff --git a/src/private/mx/core/generated/ListenChoice.h b/src/private/mx/core/generated/ListenChoice.h index ba51d47e0..cf367f768 100644 --- a/src/private/mx/core/generated/ListenChoice.h +++ b/src/private/mx/core/generated/ListenChoice.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -97,6 +99,8 @@ class ListenChoice final /// the enclosing element, for error paths. ListenChoice parseListenChoice(pugi::xml_node el, pugi::xml_node &cursor); +ListenChoice parseListenChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeListenChoice(const ListenChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/Listening.cpp b/src/private/mx/core/generated/Listening.cpp index 8703b1a2d..87e0c27eb 100644 --- a/src/private/mx/core/generated/Listening.cpp +++ b/src/private/mx/core/generated/Listening.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Listening.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -36,6 +37,11 @@ void Listening::setOffset(std::optional value) } Listening parseListening(pugi::xml_node el) +{ + return parseListening(el, ParseContext{}); +} + +Listening parseListening(pugi::xml_node el, const ParseContext &context) { Listening out; for (pugi::xml_attribute a : el.attributes()) @@ -47,25 +53,30 @@ Listening parseListening(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseListeningContent(out, el); + parseListeningContent(out, el, context); return out; } void parseListeningContent(Listening &out, pugi::xml_node el) +{ + parseListeningContent(out, el, ParseContext{}); +} + +void parseListeningContent(Listening &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (!(cursor && (cursorIs(cursor, "sync") || cursorIs(cursor, "other-listening")))) { throwMissingElement(el, "sync"); } - out.setChoice(OneOrMore{parseListeningChoice(el, cursor)}); + out.setChoice(OneOrMore{parseListeningChoice(el, cursor, context)}); while (cursor && (cursorIs(cursor, "sync") || cursorIs(cursor, "other-listening"))) { - out.addChoice(parseListeningChoice(el, cursor)); + out.addChoice(parseListeningChoice(el, cursor, context)); } if (cursorIs(cursor, "offset")) { - out.setOffset(parseOffset(cursor)); + out.setOffset(parseOffset(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/Listening.h b/src/private/mx/core/generated/Listening.h index 5043d007b..d25e32d6e 100644 --- a/src/private/mx/core/generated/Listening.h +++ b/src/private/mx/core/generated/Listening.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The listen and listening types, new in Version 4.0, specify different ways that a score following /// or machine listening application can interact with a performer. The listening type handles /// interactions that change the state of the listening application from the specified point in the @@ -48,8 +50,12 @@ class Listening final Listening parseListening(pugi::xml_node el); +Listening parseListening(pugi::xml_node el, const ParseContext &context); + void parseListeningContent(Listening &out, pugi::xml_node el); +void parseListeningContent(Listening &out, pugi::xml_node el, const ParseContext &context); + void serializeListening(const Listening &v, pugi::xml_node parent, const char *tag); void serializeListeningContent(const Listening &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/ListeningChoice.cpp b/src/private/mx/core/generated/ListeningChoice.cpp index 48c80e406..10b88d183 100644 --- a/src/private/mx/core/generated/ListeningChoice.cpp +++ b/src/private/mx/core/generated/ListeningChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/ListeningChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -26,16 +27,21 @@ ListeningChoice ListeningChoice::otherListening(OtherListening value) } ListeningChoice parseListeningChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseListeningChoice(el, cursor, ParseContext{}); +} + +ListeningChoice parseListeningChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "sync"))) { - Sync value = parseSync(cursor); + Sync value = parseSync(cursor, context); cursor = nextElement(cursor); return ListeningChoice::sync(std::move(value)); } if (cursor && (cursorIs(cursor, "other-listening"))) { - OtherListening value = parseOtherListening(cursor); + OtherListening value = parseOtherListening(cursor, context); cursor = nextElement(cursor); return ListeningChoice::otherListening(std::move(value)); } diff --git a/src/private/mx/core/generated/ListeningChoice.h b/src/private/mx/core/generated/ListeningChoice.h index ec68b2db6..dd871436f 100644 --- a/src/private/mx/core/generated/ListeningChoice.h +++ b/src/private/mx/core/generated/ListeningChoice.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -82,6 +84,8 @@ class ListeningChoice final /// the enclosing element, for error paths. ListeningChoice parseListeningChoice(pugi::xml_node el, pugi::xml_node &cursor); +ListeningChoice parseListeningChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeListeningChoice(const ListeningChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/Lyric.cpp b/src/private/mx/core/generated/Lyric.cpp index 5eabb022d..8403c3307 100644 --- a/src/private/mx/core/generated/Lyric.cpp +++ b/src/private/mx/core/generated/Lyric.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Lyric.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -171,6 +172,11 @@ void Lyric::setEditorial(EditorialGroup value) } Lyric parseLyric(pugi::xml_node el) +{ + return parseLyric(el, ParseContext{}); +} + +Lyric parseLyric(pugi::xml_node el, const ParseContext &context) { Lyric out; for (pugi::xml_attribute a : el.attributes()) @@ -190,39 +196,39 @@ Lyric parseLyric(pugi::xml_node el) } else if (aname == "time-only") { - out.setTimeOnly(TimeOnly::parse(a.value())); + out.setTimeOnly(parseValue(a.value(), context, el, "time-only")); } else if (aname == "justify") { - out.setJustify(LeftCenterRight::parse(a.value())); + out.setJustify(parseValue(a.value(), context, el, "justify")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "print-object") { - out.setPrintObject(YesNo::parse(a.value())); + out.setPrintObject(parseValue(a.value(), context, el, "print-object")); } else if (aname == "id") { @@ -233,17 +239,22 @@ Lyric parseLyric(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseLyricContent(out, el); + parseLyricContent(out, el, context); return out; } void parseLyricContent(Lyric &out, pugi::xml_node el) +{ + parseLyricContent(out, el, ParseContext{}); +} + +void parseLyricContent(Lyric &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "syllabic") || cursorIs(cursor, "text") || cursorIs(cursor, "extend") || cursorIs(cursor, "laughing") || cursorIs(cursor, "humming"))) { - out.setChoice(parseLyricChoice(el, cursor)); + out.setChoice(parseLyricChoice(el, cursor, context)); } else { @@ -251,19 +262,19 @@ void parseLyricContent(Lyric &out, pugi::xml_node el) } if (cursorIs(cursor, "end-line")) { - parseEmpty(cursor); + parseEmpty(cursor, context); out.setEndLine(true); cursor = nextElement(cursor); } if (cursorIs(cursor, "end-paragraph")) { - parseEmpty(cursor); + parseEmpty(cursor, context); out.setEndParagraph(true); cursor = nextElement(cursor); } if (cursor && (cursorIs(cursor, "footnote") || cursorIs(cursor, "level"))) { - out.setEditorial(parseEditorialGroup(el, cursor)); + out.setEditorial(parseEditorialGroup(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/Lyric.h b/src/private/mx/core/generated/Lyric.h index 7d9b00c00..a1daec469 100644 --- a/src/private/mx/core/generated/Lyric.h +++ b/src/private/mx/core/generated/Lyric.h @@ -27,6 +27,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The lyric type represents text underlays for lyrics. Two text elements that are not separated by /// an elision element are part of the same syllable, but may have different text formatting. The /// MusicXML XSD is more strict than the DTD in enforcing this by disallowing a second syllabic @@ -97,8 +99,12 @@ class Lyric final Lyric parseLyric(pugi::xml_node el); +Lyric parseLyric(pugi::xml_node el, const ParseContext &context); + void parseLyricContent(Lyric &out, pugi::xml_node el); +void parseLyricContent(Lyric &out, pugi::xml_node el, const ParseContext &context); + void serializeLyric(const Lyric &v, pugi::xml_node parent, const char *tag); void serializeLyricContent(const Lyric &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/LyricChoice.cpp b/src/private/mx/core/generated/LyricChoice.cpp index f80d6db44..f64d5a0f6 100644 --- a/src/private/mx/core/generated/LyricChoice.cpp +++ b/src/private/mx/core/generated/LyricChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/LyricChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -36,26 +37,31 @@ LyricChoice LyricChoice::humming(Empty value) } LyricChoice parseLyricChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseLyricChoice(el, cursor, ParseContext{}); +} + +LyricChoice parseLyricChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "syllabic") || cursorIs(cursor, "text"))) { - return LyricChoice::lyricTextGroup(parseLyricTextGroup(el, cursor)); + return LyricChoice::lyricTextGroup(parseLyricTextGroup(el, cursor, context)); } if (cursor && (cursorIs(cursor, "extend"))) { - Extend value = parseExtend(cursor); + Extend value = parseExtend(cursor, context); cursor = nextElement(cursor); return LyricChoice::extend(std::move(value)); } if (cursor && (cursorIs(cursor, "laughing"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return LyricChoice::laughing(std::move(value)); } if (cursor && (cursorIs(cursor, "humming"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return LyricChoice::humming(std::move(value)); } diff --git a/src/private/mx/core/generated/LyricChoice.h b/src/private/mx/core/generated/LyricChoice.h index 4d1480f01..914f1e652 100644 --- a/src/private/mx/core/generated/LyricChoice.h +++ b/src/private/mx/core/generated/LyricChoice.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -111,6 +113,8 @@ class LyricChoice final /// the enclosing element, for error paths. LyricChoice parseLyricChoice(pugi::xml_node el, pugi::xml_node &cursor); +LyricChoice parseLyricChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeLyricChoice(const LyricChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/LyricFont.cpp b/src/private/mx/core/generated/LyricFont.cpp index 407391eb7..954574977 100644 --- a/src/private/mx/core/generated/LyricFont.cpp +++ b/src/private/mx/core/generated/LyricFont.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/LyricFont.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -71,6 +72,11 @@ void LyricFont::setFontWeight(std::optional value) } LyricFont parseLyricFont(pugi::xml_node el) +{ + return parseLyricFont(el, ParseContext{}); +} + +LyricFont parseLyricFont(pugi::xml_node el, const ParseContext &context) { LyricFont out; for (pugi::xml_attribute a : el.attributes()) @@ -90,32 +96,38 @@ LyricFont parseLyricFont(pugi::xml_node el) } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else { throwUnknownAttribute(el, a.name()); } } - parseLyricFontContent(out, el); + parseLyricFontContent(out, el, context); return out; } void parseLyricFontContent(LyricFont &out, pugi::xml_node el) +{ + parseLyricFontContent(out, el, ParseContext{}); +} + +void parseLyricFontContent(LyricFont &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/LyricFont.h b/src/private/mx/core/generated/LyricFont.h index efc6f6969..66a97d08f 100644 --- a/src/private/mx/core/generated/LyricFont.h +++ b/src/private/mx/core/generated/LyricFont.h @@ -20,6 +20,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The lyric-font type specifies the default font for a particular name and number of lyric. class LyricFont final { @@ -49,8 +51,12 @@ class LyricFont final LyricFont parseLyricFont(pugi::xml_node el); +LyricFont parseLyricFont(pugi::xml_node el, const ParseContext &context); + void parseLyricFontContent(LyricFont &out, pugi::xml_node el); +void parseLyricFontContent(LyricFont &out, pugi::xml_node el, const ParseContext &context); + void serializeLyricFont(const LyricFont &v, pugi::xml_node parent, const char *tag); void serializeLyricFontContent(const LyricFont &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/LyricLanguage.cpp b/src/private/mx/core/generated/LyricLanguage.cpp index be8169849..7885e868d 100644 --- a/src/private/mx/core/generated/LyricLanguage.cpp +++ b/src/private/mx/core/generated/LyricLanguage.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/LyricLanguage.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,6 +42,11 @@ void LyricLanguage::setXMLLang(std::string value) } LyricLanguage parseLyricLanguage(pugi::xml_node el) +{ + return parseLyricLanguage(el, ParseContext{}); +} + +LyricLanguage parseLyricLanguage(pugi::xml_node el, const ParseContext &context) { LyricLanguage out; bool seen_xmlLang = false; @@ -73,14 +79,21 @@ LyricLanguage parseLyricLanguage(pugi::xml_node el) { // Configured import repair (plan ยง2.4): inject the default. out.setXMLLang(std::string("und")); + reportAttributeDefaulted(context, el, "xml:lang", "und"); } - parseLyricLanguageContent(out, el); + parseLyricLanguageContent(out, el, context); return out; } void parseLyricLanguageContent(LyricLanguage &out, pugi::xml_node el) +{ + parseLyricLanguageContent(out, el, ParseContext{}); +} + +void parseLyricLanguageContent(LyricLanguage &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/LyricLanguage.h b/src/private/mx/core/generated/LyricLanguage.h index d6330379a..97cc7740e 100644 --- a/src/private/mx/core/generated/LyricLanguage.h +++ b/src/private/mx/core/generated/LyricLanguage.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The lyric-language type specifies the default language for a particular name and number of lyric. class LyricLanguage final { @@ -36,8 +38,12 @@ class LyricLanguage final LyricLanguage parseLyricLanguage(pugi::xml_node el); +LyricLanguage parseLyricLanguage(pugi::xml_node el, const ParseContext &context); + void parseLyricLanguageContent(LyricLanguage &out, pugi::xml_node el); +void parseLyricLanguageContent(LyricLanguage &out, pugi::xml_node el, const ParseContext &context); + void serializeLyricLanguage(const LyricLanguage &v, pugi::xml_node parent, const char *tag); void serializeLyricLanguageContent(const LyricLanguage &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/LyricSyllableGroup.cpp b/src/private/mx/core/generated/LyricSyllableGroup.cpp index 28ee6a5ae..405b6c64c 100644 --- a/src/private/mx/core/generated/LyricSyllableGroup.cpp +++ b/src/private/mx/core/generated/LyricSyllableGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/LyricSyllableGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,15 +32,20 @@ void LyricSyllableGroup::setText(TextElementData value) } LyricSyllableGroup parseLyricSyllableGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseLyricSyllableGroup(el, cursor, ParseContext{}); +} + +LyricSyllableGroup parseLyricSyllableGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { LyricSyllableGroup out; if (cursor && (cursorIs(cursor, "elision"))) { - out.setElisionSyllabicGroup(parseElisionSyllabicGroup(el, cursor)); + out.setElisionSyllabicGroup(parseElisionSyllabicGroup(el, cursor, context)); } if (cursorIs(cursor, "text")) { - out.setText(parseTextElementData(cursor)); + out.setText(parseTextElementData(cursor, context)); cursor = nextElement(cursor); } else diff --git a/src/private/mx/core/generated/LyricSyllableGroup.h b/src/private/mx/core/generated/LyricSyllableGroup.h index 2f758b90d..1d73b9799 100644 --- a/src/private/mx/core/generated/LyricSyllableGroup.h +++ b/src/private/mx/core/generated/LyricSyllableGroup.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A shared content group (synthesized from an anonymous /// particle of the schema): transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -39,6 +41,8 @@ class LyricSyllableGroup final /// is the enclosing element, for error paths. LyricSyllableGroup parseLyricSyllableGroup(pugi::xml_node el, pugi::xml_node &cursor); +LyricSyllableGroup parseLyricSyllableGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeLyricSyllableGroup(const LyricSyllableGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/LyricTextGroup.cpp b/src/private/mx/core/generated/LyricTextGroup.cpp index 02a5b736d..7e8563c4c 100644 --- a/src/private/mx/core/generated/LyricTextGroup.cpp +++ b/src/private/mx/core/generated/LyricTextGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/LyricTextGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -56,16 +57,21 @@ void LyricTextGroup::setExtend(std::optional value) } LyricTextGroup parseLyricTextGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseLyricTextGroup(el, cursor, ParseContext{}); +} + +LyricTextGroup parseLyricTextGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { LyricTextGroup out; if (cursorIs(cursor, "syllabic")) { - out.setSyllabic(Syllabic::parse(childText(cursor))); + out.setSyllabic(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (cursorIs(cursor, "text")) { - out.setText(parseTextElementData(cursor)); + out.setText(parseTextElementData(cursor, context)); cursor = nextElement(cursor); } else @@ -74,11 +80,11 @@ LyricTextGroup parseLyricTextGroup(pugi::xml_node el, pugi::xml_node &cursor) } while (cursor && (cursorIs(cursor, "elision") || cursorIs(cursor, "text"))) { - out.addLyricSyllableGroup(parseLyricSyllableGroup(el, cursor)); + out.addLyricSyllableGroup(parseLyricSyllableGroup(el, cursor, context)); } if (cursorIs(cursor, "extend")) { - out.setExtend(parseExtend(cursor)); + out.setExtend(parseExtend(cursor, context)); cursor = nextElement(cursor); } return out; diff --git a/src/private/mx/core/generated/LyricTextGroup.h b/src/private/mx/core/generated/LyricTextGroup.h index 6655343c6..23dc12b37 100644 --- a/src/private/mx/core/generated/LyricTextGroup.h +++ b/src/private/mx/core/generated/LyricTextGroup.h @@ -20,6 +20,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A shared content group (synthesized from an anonymous /// particle of the schema): transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -48,6 +50,8 @@ class LyricTextGroup final /// is the enclosing element, for error paths. LyricTextGroup parseLyricTextGroup(pugi::xml_node el, pugi::xml_node &cursor); +LyricTextGroup parseLyricTextGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeLyricTextGroup(const LyricTextGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/MIDI128.cpp b/src/private/mx/core/generated/MIDI128.cpp index 358e9fb7a..900f161a6 100644 --- a/src/private/mx/core/generated/MIDI128.cpp +++ b/src/private/mx/core/generated/MIDI128.cpp @@ -42,20 +42,33 @@ std::string MIDI128::toString() const bool MIDI128::tryParse(std::string_view text, MIDI128 &out) { - int v{}; - if (!tryParseInt(text, v)) + ValueParseOutcome outcome = ValueParseOutcome::valid; + MIDI128 parsed = parse(text, outcome); + if (outcome == ValueParseOutcome::invalid) { return false; } - out = MIDI128{v}; + out = std::move(parsed); return true; } MIDI128 MIDI128::parse(std::string_view text) { - MIDI128 v; - tryParse(text, v); - return v; + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +MIDI128 MIDI128::parse(std::string_view text, ValueParseOutcome &outcome) +{ + int v{}; + if (!tryParseInt(text, v)) + { + outcome = ValueParseOutcome::invalid; + return MIDI128{}; + } + MIDI128 out{v}; + outcome = out.value() == v ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; } } // namespace mx::core diff --git a/src/private/mx/core/generated/MIDI128.h b/src/private/mx/core/generated/MIDI128.h index 89510bc81..dcf806952 100644 --- a/src/private/mx/core/generated/MIDI128.h +++ b/src/private/mx/core/generated/MIDI128.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -35,6 +37,9 @@ class MIDI128 final /// Lenient: non-numeric text yields the clamped zero. static MIDI128 parse(std::string_view text); + /// Lenient, and says whether the text was non-numeric or clamped. + static MIDI128 parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const MIDI128 &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/MIDI16.cpp b/src/private/mx/core/generated/MIDI16.cpp index 74920b4a9..c7b4cbd79 100644 --- a/src/private/mx/core/generated/MIDI16.cpp +++ b/src/private/mx/core/generated/MIDI16.cpp @@ -42,20 +42,33 @@ std::string MIDI16::toString() const bool MIDI16::tryParse(std::string_view text, MIDI16 &out) { - int v{}; - if (!tryParseInt(text, v)) + ValueParseOutcome outcome = ValueParseOutcome::valid; + MIDI16 parsed = parse(text, outcome); + if (outcome == ValueParseOutcome::invalid) { return false; } - out = MIDI16{v}; + out = std::move(parsed); return true; } MIDI16 MIDI16::parse(std::string_view text) { - MIDI16 v; - tryParse(text, v); - return v; + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +MIDI16 MIDI16::parse(std::string_view text, ValueParseOutcome &outcome) +{ + int v{}; + if (!tryParseInt(text, v)) + { + outcome = ValueParseOutcome::invalid; + return MIDI16{}; + } + MIDI16 out{v}; + outcome = out.value() == v ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; } } // namespace mx::core diff --git a/src/private/mx/core/generated/MIDI16.h b/src/private/mx/core/generated/MIDI16.h index 7777c8f5a..78ac9cd85 100644 --- a/src/private/mx/core/generated/MIDI16.h +++ b/src/private/mx/core/generated/MIDI16.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -35,6 +37,9 @@ class MIDI16 final /// Lenient: non-numeric text yields the clamped zero. static MIDI16 parse(std::string_view text); + /// Lenient, and says whether the text was non-numeric or clamped. + static MIDI16 parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const MIDI16 &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/MIDI16384.cpp b/src/private/mx/core/generated/MIDI16384.cpp index 269a088c8..d32543233 100644 --- a/src/private/mx/core/generated/MIDI16384.cpp +++ b/src/private/mx/core/generated/MIDI16384.cpp @@ -42,20 +42,33 @@ std::string MIDI16384::toString() const bool MIDI16384::tryParse(std::string_view text, MIDI16384 &out) { - int v{}; - if (!tryParseInt(text, v)) + ValueParseOutcome outcome = ValueParseOutcome::valid; + MIDI16384 parsed = parse(text, outcome); + if (outcome == ValueParseOutcome::invalid) { return false; } - out = MIDI16384{v}; + out = std::move(parsed); return true; } MIDI16384 MIDI16384::parse(std::string_view text) { - MIDI16384 v; - tryParse(text, v); - return v; + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +MIDI16384 MIDI16384::parse(std::string_view text, ValueParseOutcome &outcome) +{ + int v{}; + if (!tryParseInt(text, v)) + { + outcome = ValueParseOutcome::invalid; + return MIDI16384{}; + } + MIDI16384 out{v}; + outcome = out.value() == v ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; } } // namespace mx::core diff --git a/src/private/mx/core/generated/MIDI16384.h b/src/private/mx/core/generated/MIDI16384.h index 567ecc234..adec05596 100644 --- a/src/private/mx/core/generated/MIDI16384.h +++ b/src/private/mx/core/generated/MIDI16384.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -35,6 +37,9 @@ class MIDI16384 final /// Lenient: non-numeric text yields the clamped zero. static MIDI16384 parse(std::string_view text); + /// Lenient, and says whether the text was non-numeric or clamped. + static MIDI16384 parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const MIDI16384 &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/MIDIDevice.cpp b/src/private/mx/core/generated/MIDIDevice.cpp index 8c764d179..d99f1f3a2 100644 --- a/src/private/mx/core/generated/MIDIDevice.cpp +++ b/src/private/mx/core/generated/MIDIDevice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/MIDIDevice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,6 +42,11 @@ void MIDIDevice::setValue(std::string value) } MIDIDevice parseMIDIDevice(pugi::xml_node el) +{ + return parseMIDIDevice(el, ParseContext{}); +} + +MIDIDevice parseMIDIDevice(pugi::xml_node el, const ParseContext &context) { MIDIDevice out; for (pugi::xml_attribute a : el.attributes()) @@ -52,7 +58,7 @@ MIDIDevice parseMIDIDevice(pugi::xml_node el) } if (aname == "port") { - out.setPort(MIDI16::parse(a.value())); + out.setPort(parseValue(a.value(), context, el, "port")); } else if (aname == "id") { @@ -63,11 +69,16 @@ MIDIDevice parseMIDIDevice(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseMIDIDeviceContent(out, el); + parseMIDIDeviceContent(out, el, context); return out; } void parseMIDIDeviceContent(MIDIDevice &out, pugi::xml_node el) +{ + parseMIDIDeviceContent(out, el, ParseContext{}); +} + +void parseMIDIDeviceContent(MIDIDevice &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/MIDIDevice.h b/src/private/mx/core/generated/MIDIDevice.h index 3531a000e..f3a6a4e5c 100644 --- a/src/private/mx/core/generated/MIDIDevice.h +++ b/src/private/mx/core/generated/MIDIDevice.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The midi-device type corresponds to the DeviceName meta event in Standard MIDI Files. The /// optional port attribute is a number from 1 to 16 that can be used with the unofficial MIDI 1.0 /// port (or cable) meta event. Unlike the DeviceName meta event, there can be multiple midi-device @@ -42,8 +44,12 @@ class MIDIDevice final MIDIDevice parseMIDIDevice(pugi::xml_node el); +MIDIDevice parseMIDIDevice(pugi::xml_node el, const ParseContext &context); + void parseMIDIDeviceContent(MIDIDevice &out, pugi::xml_node el); +void parseMIDIDeviceContent(MIDIDevice &out, pugi::xml_node el, const ParseContext &context); + void serializeMIDIDevice(const MIDIDevice &v, pugi::xml_node parent, const char *tag); void serializeMIDIDeviceContent(const MIDIDevice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/MIDIInstrument.cpp b/src/private/mx/core/generated/MIDIInstrument.cpp index e6b6e44ed..a44e08501 100644 --- a/src/private/mx/core/generated/MIDIInstrument.cpp +++ b/src/private/mx/core/generated/MIDIInstrument.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/MIDIInstrument.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -101,6 +102,11 @@ void MIDIInstrument::setElevation(std::optional value) } MIDIInstrument parseMIDIInstrument(pugi::xml_node el) +{ + return parseMIDIInstrument(el, ParseContext{}); +} + +MIDIInstrument parseMIDIInstrument(pugi::xml_node el, const ParseContext &context) { MIDIInstrument out; bool seen_id = false; @@ -125,16 +131,21 @@ MIDIInstrument parseMIDIInstrument(pugi::xml_node el) { throwMissingAttribute(el, "id"); } - parseMIDIInstrumentContent(out, el); + parseMIDIInstrumentContent(out, el, context); return out; } void parseMIDIInstrumentContent(MIDIInstrument &out, pugi::xml_node el) +{ + parseMIDIInstrumentContent(out, el, ParseContext{}); +} + +void parseMIDIInstrumentContent(MIDIInstrument &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "midi-channel")) { - out.setMIDIChannel(MIDI16::parse(childText(cursor))); + out.setMIDIChannel(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (cursorIs(cursor, "midi-name")) @@ -144,32 +155,32 @@ void parseMIDIInstrumentContent(MIDIInstrument &out, pugi::xml_node el) } if (cursorIs(cursor, "midi-bank")) { - out.setMIDIBank(MIDI16384::parse(childText(cursor))); + out.setMIDIBank(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (cursorIs(cursor, "midi-program")) { - out.setMIDIProgram(MIDI128::parse(childText(cursor))); + out.setMIDIProgram(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (cursorIs(cursor, "midi-unpitched")) { - out.setMIDIUnpitched(MIDI128::parse(childText(cursor))); + out.setMIDIUnpitched(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (cursorIs(cursor, "volume")) { - out.setVolume(Percent::parse(childText(cursor))); + out.setVolume(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (cursorIs(cursor, "pan")) { - out.setPan(RotationDegrees::parse(childText(cursor))); + out.setPan(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (cursorIs(cursor, "elevation")) { - out.setElevation(RotationDegrees::parse(childText(cursor))); + out.setElevation(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/MIDIInstrument.h b/src/private/mx/core/generated/MIDIInstrument.h index a950d0e85..078ac95ff 100644 --- a/src/private/mx/core/generated/MIDIInstrument.h +++ b/src/private/mx/core/generated/MIDIInstrument.h @@ -23,6 +23,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The midi-instrument type defines MIDI 1.0 instrument playback. The midi-instrument element can be /// a part of either the score-instrument element at the start of a part, or the sound element within /// a part. The id attribute refers to the score-instrument affected by the change. @@ -65,8 +67,12 @@ class MIDIInstrument final MIDIInstrument parseMIDIInstrument(pugi::xml_node el); +MIDIInstrument parseMIDIInstrument(pugi::xml_node el, const ParseContext &context); + void parseMIDIInstrumentContent(MIDIInstrument &out, pugi::xml_node el); +void parseMIDIInstrumentContent(MIDIInstrument &out, pugi::xml_node el, const ParseContext &context); + void serializeMIDIInstrument(const MIDIInstrument &v, pugi::xml_node parent, const char *tag); void serializeMIDIInstrumentContent(const MIDIInstrument &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/MarginType.cpp b/src/private/mx/core/generated/MarginType.cpp index 5ad2f1386..cb2a0939b 100644 --- a/src/private/mx/core/generated/MarginType.cpp +++ b/src/private/mx/core/generated/MarginType.cpp @@ -48,9 +48,15 @@ bool MarginType::tryParse(std::string_view text, MarginType &out) noexcept } MarginType MarginType::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +MarginType MarginType::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { MarginType v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/MarginType.h b/src/private/mx/core/generated/MarginType.h index 40ad8e109..92c2c2af5 100644 --- a/src/private/mx/core/generated/MarginType.h +++ b/src/private/mx/core/generated/MarginType.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -42,6 +44,9 @@ class MarginType final /// (the import leniency policy; never produces an invalid value). static MarginType parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static MarginType parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const MarginType &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/MeasureLayout.cpp b/src/private/mx/core/generated/MeasureLayout.cpp index e330e93ab..c50aed215 100644 --- a/src/private/mx/core/generated/MeasureLayout.cpp +++ b/src/private/mx/core/generated/MeasureLayout.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/MeasureLayout.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -21,6 +22,11 @@ void MeasureLayout::setMeasureDistance(std::optional value) } MeasureLayout parseMeasureLayout(pugi::xml_node el) +{ + return parseMeasureLayout(el, ParseContext{}); +} + +MeasureLayout parseMeasureLayout(pugi::xml_node el, const ParseContext &context) { MeasureLayout out; for (pugi::xml_attribute a : el.attributes()) @@ -32,16 +38,21 @@ MeasureLayout parseMeasureLayout(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseMeasureLayoutContent(out, el); + parseMeasureLayoutContent(out, el, context); return out; } void parseMeasureLayoutContent(MeasureLayout &out, pugi::xml_node el) +{ + parseMeasureLayoutContent(out, el, ParseContext{}); +} + +void parseMeasureLayoutContent(MeasureLayout &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "measure-distance")) { - out.setMeasureDistance(Tenths::parse(childText(cursor))); + out.setMeasureDistance(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/MeasureLayout.h b/src/private/mx/core/generated/MeasureLayout.h index f6c8da1eb..600b4a73c 100644 --- a/src/private/mx/core/generated/MeasureLayout.h +++ b/src/private/mx/core/generated/MeasureLayout.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The measure-layout type includes the horizontal distance from the previous measure. It applies to /// the current measure only. /// Content fields mirror the schema grammar in declaration order; the @@ -34,8 +36,12 @@ class MeasureLayout final MeasureLayout parseMeasureLayout(pugi::xml_node el); +MeasureLayout parseMeasureLayout(pugi::xml_node el, const ParseContext &context); + void parseMeasureLayoutContent(MeasureLayout &out, pugi::xml_node el); +void parseMeasureLayoutContent(MeasureLayout &out, pugi::xml_node el, const ParseContext &context); + void serializeMeasureLayout(const MeasureLayout &v, pugi::xml_node parent, const char *tag); void serializeMeasureLayoutContent(const MeasureLayout &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/MeasureNumbering.cpp b/src/private/mx/core/generated/MeasureNumbering.cpp index 8faf032bf..bf7656a57 100644 --- a/src/private/mx/core/generated/MeasureNumbering.cpp +++ b/src/private/mx/core/generated/MeasureNumbering.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/MeasureNumbering.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -171,6 +172,11 @@ void MeasureNumbering::setValue(MeasureNumberingValue value) } MeasureNumbering parseMeasureNumbering(pugi::xml_node el) +{ + return parseMeasureNumbering(el, ParseContext{}); +} + +MeasureNumbering parseMeasureNumbering(pugi::xml_node el, const ParseContext &context) { MeasureNumbering out; for (pugi::xml_attribute a : el.attributes()) @@ -182,76 +188,81 @@ MeasureNumbering parseMeasureNumbering(pugi::xml_node el) } if (aname == "system") { - out.setSystem(SystemRelationNumber::parse(a.value())); + out.setSystem(parseValue(a.value(), context, el, "system")); } else if (aname == "staff") { - out.setStaff(StaffNumber::parse(a.value())); + out.setStaff(parseValue(a.value(), context, el, "staff")); } else if (aname == "multiple-rest-always") { - out.setMultipleRestAlways(YesNo::parse(a.value())); + out.setMultipleRestAlways(parseValue(a.value(), context, el, "multiple-rest-always")); } else if (aname == "multiple-rest-range") { - out.setMultipleRestRange(YesNo::parse(a.value())); + out.setMultipleRestRange(parseValue(a.value(), context, el, "multiple-rest-range")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "halign") { - out.setHalign(LeftCenterRight::parse(a.value())); + out.setHalign(parseValue(a.value(), context, el, "halign")); } else if (aname == "valign") { - out.setValign(Valign::parse(a.value())); + out.setValign(parseValue(a.value(), context, el, "valign")); } else { throwUnknownAttribute(el, a.name()); } } - parseMeasureNumberingContent(out, el); + parseMeasureNumberingContent(out, el, context); return out; } void parseMeasureNumberingContent(MeasureNumbering &out, pugi::xml_node el) { - out.setValue(MeasureNumberingValue::parse(childText(el))); + parseMeasureNumberingContent(out, el, ParseContext{}); +} + +void parseMeasureNumberingContent(MeasureNumbering &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/MeasureNumbering.h b/src/private/mx/core/generated/MeasureNumbering.h index 7025a1729..46f8a2683 100644 --- a/src/private/mx/core/generated/MeasureNumbering.h +++ b/src/private/mx/core/generated/MeasureNumbering.h @@ -26,6 +26,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The measure-numbering type describes how frequently measure numbers are displayed on this part. /// The text attribute from the measure element is used for display, or the number attribute if the /// text attribute is not present. Measures with an implicit attribute set to "yes" never display a @@ -97,8 +99,12 @@ class MeasureNumbering final MeasureNumbering parseMeasureNumbering(pugi::xml_node el); +MeasureNumbering parseMeasureNumbering(pugi::xml_node el, const ParseContext &context); + void parseMeasureNumberingContent(MeasureNumbering &out, pugi::xml_node el); +void parseMeasureNumberingContent(MeasureNumbering &out, pugi::xml_node el, const ParseContext &context); + void serializeMeasureNumbering(const MeasureNumbering &v, pugi::xml_node parent, const char *tag); void serializeMeasureNumberingContent(const MeasureNumbering &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/MeasureNumberingValue.cpp b/src/private/mx/core/generated/MeasureNumberingValue.cpp index 5d8b47b59..56adbe966 100644 --- a/src/private/mx/core/generated/MeasureNumberingValue.cpp +++ b/src/private/mx/core/generated/MeasureNumberingValue.cpp @@ -48,9 +48,15 @@ bool MeasureNumberingValue::tryParse(std::string_view text, MeasureNumberingValu } MeasureNumberingValue MeasureNumberingValue::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +MeasureNumberingValue MeasureNumberingValue::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { MeasureNumberingValue v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/MeasureNumberingValue.h b/src/private/mx/core/generated/MeasureNumberingValue.h index 96664d633..939055eb2 100644 --- a/src/private/mx/core/generated/MeasureNumberingValue.h +++ b/src/private/mx/core/generated/MeasureNumberingValue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -43,6 +45,9 @@ class MeasureNumberingValue final /// (the import leniency policy; never produces an invalid value). static MeasureNumberingValue parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static MeasureNumberingValue parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const MeasureNumberingValue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/MeasureRepeat.cpp b/src/private/mx/core/generated/MeasureRepeat.cpp index c23e4fb45..5515ea3d4 100644 --- a/src/private/mx/core/generated/MeasureRepeat.cpp +++ b/src/private/mx/core/generated/MeasureRepeat.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/MeasureRepeat.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,6 +42,11 @@ void MeasureRepeat::setValue(PositiveIntegerOrEmpty value) } MeasureRepeat parseMeasureRepeat(pugi::xml_node el) +{ + return parseMeasureRepeat(el, ParseContext{}); +} + +MeasureRepeat parseMeasureRepeat(pugi::xml_node el, const ParseContext &context) { MeasureRepeat out; bool seen_type = false; @@ -54,11 +60,11 @@ MeasureRepeat parseMeasureRepeat(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(StartStop::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "slashes") { - out.setSlashes(parseInt(a.value())); + out.setSlashes(parseIntegerValue(a.value(), context, el, "slashes")); } else { @@ -69,13 +75,18 @@ MeasureRepeat parseMeasureRepeat(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseMeasureRepeatContent(out, el); + parseMeasureRepeatContent(out, el, context); return out; } void parseMeasureRepeatContent(MeasureRepeat &out, pugi::xml_node el) { - out.setValue(PositiveIntegerOrEmpty::parse(childText(el))); + parseMeasureRepeatContent(out, el, ParseContext{}); +} + +void parseMeasureRepeatContent(MeasureRepeat &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/MeasureRepeat.h b/src/private/mx/core/generated/MeasureRepeat.h index 8585d0798..27bd66fd3 100644 --- a/src/private/mx/core/generated/MeasureRepeat.h +++ b/src/private/mx/core/generated/MeasureRepeat.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The measure-repeat type is used for both single and multiple measure repeats. The text of the /// element indicates the number of measures to be repeated in a single pattern. The slashes /// attribute specifies the number of slashes to use in the repeat sign. It is 1 if not specified. @@ -44,8 +46,12 @@ class MeasureRepeat final MeasureRepeat parseMeasureRepeat(pugi::xml_node el); +MeasureRepeat parseMeasureRepeat(pugi::xml_node el, const ParseContext &context); + void parseMeasureRepeatContent(MeasureRepeat &out, pugi::xml_node el); +void parseMeasureRepeatContent(MeasureRepeat &out, pugi::xml_node el, const ParseContext &context); + void serializeMeasureRepeat(const MeasureRepeat &v, pugi::xml_node parent, const char *tag); void serializeMeasureRepeatContent(const MeasureRepeat &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/MeasureStyle.cpp b/src/private/mx/core/generated/MeasureStyle.cpp index af8306a35..2d51f6ecf 100644 --- a/src/private/mx/core/generated/MeasureStyle.cpp +++ b/src/private/mx/core/generated/MeasureStyle.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/MeasureStyle.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -91,6 +92,11 @@ void MeasureStyle::setChoice(MeasureStyleChoice value) } MeasureStyle parseMeasureStyle(pugi::xml_node el) +{ + return parseMeasureStyle(el, ParseContext{}); +} + +MeasureStyle parseMeasureStyle(pugi::xml_node el, const ParseContext &context) { MeasureStyle out; for (pugi::xml_attribute a : el.attributes()) @@ -102,27 +108,27 @@ MeasureStyle parseMeasureStyle(pugi::xml_node el) } if (aname == "number") { - out.setNumber(StaffNumber::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "id") { @@ -133,17 +139,22 @@ MeasureStyle parseMeasureStyle(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseMeasureStyleContent(out, el); + parseMeasureStyleContent(out, el, context); return out; } void parseMeasureStyleContent(MeasureStyle &out, pugi::xml_node el) +{ + parseMeasureStyleContent(out, el, ParseContext{}); +} + +void parseMeasureStyleContent(MeasureStyle &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "multiple-rest") || cursorIs(cursor, "measure-repeat") || cursorIs(cursor, "beat-repeat") || cursorIs(cursor, "slash"))) { - out.setChoice(parseMeasureStyleChoice(el, cursor)); + out.setChoice(parseMeasureStyleChoice(el, cursor, context)); } else { diff --git a/src/private/mx/core/generated/MeasureStyle.h b/src/private/mx/core/generated/MeasureStyle.h index 98f54a3d1..be1662fbe 100644 --- a/src/private/mx/core/generated/MeasureStyle.h +++ b/src/private/mx/core/generated/MeasureStyle.h @@ -25,6 +25,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A measure-style indicates a special way to print partial to multiple measures within a part. This /// includes multiple rests over several measures, repeats of beats, single, or multiple measures, /// and use of slash notation. The multiple-rest and measure-repeat elements indicate the number of @@ -68,8 +70,12 @@ class MeasureStyle final MeasureStyle parseMeasureStyle(pugi::xml_node el); +MeasureStyle parseMeasureStyle(pugi::xml_node el, const ParseContext &context); + void parseMeasureStyleContent(MeasureStyle &out, pugi::xml_node el); +void parseMeasureStyleContent(MeasureStyle &out, pugi::xml_node el, const ParseContext &context); + void serializeMeasureStyle(const MeasureStyle &v, pugi::xml_node parent, const char *tag); void serializeMeasureStyleContent(const MeasureStyle &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/MeasureStyleChoice.cpp b/src/private/mx/core/generated/MeasureStyleChoice.cpp index b492b2ab5..1f859e3bf 100644 --- a/src/private/mx/core/generated/MeasureStyleChoice.cpp +++ b/src/private/mx/core/generated/MeasureStyleChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/MeasureStyleChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -36,28 +37,33 @@ MeasureStyleChoice MeasureStyleChoice::slash(Slash value) } MeasureStyleChoice parseMeasureStyleChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseMeasureStyleChoice(el, cursor, ParseContext{}); +} + +MeasureStyleChoice parseMeasureStyleChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "multiple-rest"))) { - MultipleRest value = parseMultipleRest(cursor); + MultipleRest value = parseMultipleRest(cursor, context); cursor = nextElement(cursor); return MeasureStyleChoice::multipleRest(std::move(value)); } if (cursor && (cursorIs(cursor, "measure-repeat"))) { - MeasureRepeat value = parseMeasureRepeat(cursor); + MeasureRepeat value = parseMeasureRepeat(cursor, context); cursor = nextElement(cursor); return MeasureStyleChoice::measureRepeat(std::move(value)); } if (cursor && (cursorIs(cursor, "beat-repeat"))) { - BeatRepeat value = parseBeatRepeat(cursor); + BeatRepeat value = parseBeatRepeat(cursor, context); cursor = nextElement(cursor); return MeasureStyleChoice::beatRepeat(std::move(value)); } if (cursor && (cursorIs(cursor, "slash"))) { - Slash value = parseSlash(cursor); + Slash value = parseSlash(cursor, context); cursor = nextElement(cursor); return MeasureStyleChoice::slash(std::move(value)); } diff --git a/src/private/mx/core/generated/MeasureStyleChoice.h b/src/private/mx/core/generated/MeasureStyleChoice.h index 57987a1a8..40516f964 100644 --- a/src/private/mx/core/generated/MeasureStyleChoice.h +++ b/src/private/mx/core/generated/MeasureStyleChoice.h @@ -20,6 +20,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -112,6 +114,8 @@ class MeasureStyleChoice final /// the enclosing element, for error paths. MeasureStyleChoice parseMeasureStyleChoice(pugi::xml_node el, pugi::xml_node &cursor); +MeasureStyleChoice parseMeasureStyleChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeMeasureStyleChoice(const MeasureStyleChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/MeasureText.cpp b/src/private/mx/core/generated/MeasureText.cpp index 65b80f007..9a188a80e 100644 --- a/src/private/mx/core/generated/MeasureText.cpp +++ b/src/private/mx/core/generated/MeasureText.cpp @@ -42,4 +42,11 @@ MeasureText MeasureText::parse(std::string_view text) return MeasureText{std::string{text}}; } +MeasureText MeasureText::parse(std::string_view text, ValueParseOutcome &outcome) +{ + MeasureText out{std::string{text}}; + outcome = out.value() == text ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; +} + } // namespace mx::core diff --git a/src/private/mx/core/generated/MeasureText.h b/src/private/mx/core/generated/MeasureText.h index b27dfe10a..652ce4318 100644 --- a/src/private/mx/core/generated/MeasureText.h +++ b/src/private/mx/core/generated/MeasureText.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -37,6 +39,9 @@ class MeasureText final static MeasureText parse(std::string_view text); + /// Says whether the text had to be repaired. + static MeasureText parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const MeasureText &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Membrane.cpp b/src/private/mx/core/generated/Membrane.cpp index e42ec6826..88f5dd671 100644 --- a/src/private/mx/core/generated/Membrane.cpp +++ b/src/private/mx/core/generated/Membrane.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Membrane.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void Membrane::setValue(MembraneValue value) } Membrane parseMembrane(pugi::xml_node el) +{ + return parseMembrane(el, ParseContext{}); +} + +Membrane parseMembrane(pugi::xml_node el, const ParseContext &context) { Membrane out; for (pugi::xml_attribute a : el.attributes()) @@ -42,20 +48,25 @@ Membrane parseMembrane(pugi::xml_node el) } if (aname == "smufl") { - out.setSmufl(SmuflPictogramGlyphName::parse(a.value())); + out.setSmufl(parseValue(a.value(), context, el, "smufl")); } else { throwUnknownAttribute(el, a.name()); } } - parseMembraneContent(out, el); + parseMembraneContent(out, el, context); return out; } void parseMembraneContent(Membrane &out, pugi::xml_node el) { - out.setValue(MembraneValue::parse(childText(el))); + parseMembraneContent(out, el, ParseContext{}); +} + +void parseMembraneContent(Membrane &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Membrane.h b/src/private/mx/core/generated/Membrane.h index 4c75a6130..d598141ee 100644 --- a/src/private/mx/core/generated/Membrane.h +++ b/src/private/mx/core/generated/Membrane.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The membrane type represents pictograms for membrane percussion instruments. The smufl attribute /// is used to distinguish different SMuFL stylistic alternates. class Membrane final @@ -34,8 +36,12 @@ class Membrane final Membrane parseMembrane(pugi::xml_node el); +Membrane parseMembrane(pugi::xml_node el, const ParseContext &context); + void parseMembraneContent(Membrane &out, pugi::xml_node el); +void parseMembraneContent(Membrane &out, pugi::xml_node el, const ParseContext &context); + void serializeMembrane(const Membrane &v, pugi::xml_node parent, const char *tag); void serializeMembraneContent(const Membrane &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/MembraneValue.cpp b/src/private/mx/core/generated/MembraneValue.cpp index 8440bd772..6796e23c0 100644 --- a/src/private/mx/core/generated/MembraneValue.cpp +++ b/src/private/mx/core/generated/MembraneValue.cpp @@ -118,9 +118,15 @@ bool MembraneValue::tryParse(std::string_view text, MembraneValue &out) noexcept } MembraneValue MembraneValue::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +MembraneValue MembraneValue::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { MembraneValue v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/MembraneValue.h b/src/private/mx/core/generated/MembraneValue.h index dd5246102..34bd86e7f 100644 --- a/src/private/mx/core/generated/MembraneValue.h +++ b/src/private/mx/core/generated/MembraneValue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -70,6 +72,9 @@ class MembraneValue final /// (the import leniency policy; never produces an invalid value). static MembraneValue parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static MembraneValue parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const MembraneValue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Metal.cpp b/src/private/mx/core/generated/Metal.cpp index 39d9da1b1..b7f0f5a3e 100644 --- a/src/private/mx/core/generated/Metal.cpp +++ b/src/private/mx/core/generated/Metal.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Metal.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void Metal::setValue(MetalValue value) } Metal parseMetal(pugi::xml_node el) +{ + return parseMetal(el, ParseContext{}); +} + +Metal parseMetal(pugi::xml_node el, const ParseContext &context) { Metal out; for (pugi::xml_attribute a : el.attributes()) @@ -42,20 +48,25 @@ Metal parseMetal(pugi::xml_node el) } if (aname == "smufl") { - out.setSmufl(SmuflPictogramGlyphName::parse(a.value())); + out.setSmufl(parseValue(a.value(), context, el, "smufl")); } else { throwUnknownAttribute(el, a.name()); } } - parseMetalContent(out, el); + parseMetalContent(out, el, context); return out; } void parseMetalContent(Metal &out, pugi::xml_node el) { - out.setValue(MetalValue::parse(childText(el))); + parseMetalContent(out, el, ParseContext{}); +} + +void parseMetalContent(Metal &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Metal.h b/src/private/mx/core/generated/Metal.h index ad429fe82..607a6d4f8 100644 --- a/src/private/mx/core/generated/Metal.h +++ b/src/private/mx/core/generated/Metal.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The metal type represents pictograms for metal percussion instruments. The smufl attribute is /// used to distinguish different SMuFL stylistic alternates. class Metal final @@ -34,8 +36,12 @@ class Metal final Metal parseMetal(pugi::xml_node el); +Metal parseMetal(pugi::xml_node el, const ParseContext &context); + void parseMetalContent(Metal &out, pugi::xml_node el); +void parseMetalContent(Metal &out, pugi::xml_node el, const ParseContext &context); + void serializeMetal(const Metal &v, pugi::xml_node parent, const char *tag); void serializeMetalContent(const Metal &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/MetalValue.cpp b/src/private/mx/core/generated/MetalValue.cpp index 3f1ee2b04..2bf45eb43 100644 --- a/src/private/mx/core/generated/MetalValue.cpp +++ b/src/private/mx/core/generated/MetalValue.cpp @@ -222,9 +222,15 @@ bool MetalValue::tryParse(std::string_view text, MetalValue &out) noexcept } MetalValue MetalValue::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +MetalValue MetalValue::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { MetalValue v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/MetalValue.h b/src/private/mx/core/generated/MetalValue.h index 8d008e670..758919a10 100644 --- a/src/private/mx/core/generated/MetalValue.h +++ b/src/private/mx/core/generated/MetalValue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -102,6 +104,9 @@ class MetalValue final /// (the import leniency policy; never produces an invalid value). static MetalValue parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static MetalValue parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const MetalValue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Metronome.cpp b/src/private/mx/core/generated/Metronome.cpp index db355f8eb..f1d45b105 100644 --- a/src/private/mx/core/generated/Metronome.cpp +++ b/src/private/mx/core/generated/Metronome.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Metronome.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -171,6 +172,11 @@ void Metronome::setChoice(MetronomeChoice value) } Metronome parseMetronome(pugi::xml_node el) +{ + return parseMetronome(el, ParseContext{}); +} + +Metronome parseMetronome(pugi::xml_node el, const ParseContext &context) { Metronome out; for (pugi::xml_attribute a : el.attributes()) @@ -182,59 +188,59 @@ Metronome parseMetronome(pugi::xml_node el) } if (aname == "parentheses") { - out.setParentheses(YesNo::parse(a.value())); + out.setParentheses(parseValue(a.value(), context, el, "parentheses")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "halign") { - out.setHalign(LeftCenterRight::parse(a.value())); + out.setHalign(parseValue(a.value(), context, el, "halign")); } else if (aname == "valign") { - out.setValign(Valign::parse(a.value())); + out.setValign(parseValue(a.value(), context, el, "valign")); } else if (aname == "print-object") { - out.setPrintObject(YesNo::parse(a.value())); + out.setPrintObject(parseValue(a.value(), context, el, "print-object")); } else if (aname == "justify") { - out.setJustify(LeftCenterRight::parse(a.value())); + out.setJustify(parseValue(a.value(), context, el, "justify")); } else if (aname == "id") { @@ -245,17 +251,22 @@ Metronome parseMetronome(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseMetronomeContent(out, el); + parseMetronomeContent(out, el, context); return out; } void parseMetronomeContent(Metronome &out, pugi::xml_node el) +{ + parseMetronomeContent(out, el, ParseContext{}); +} + +void parseMetronomeContent(Metronome &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "beat-unit") || cursorIs(cursor, "metronome-arrows") || cursorIs(cursor, "metronome-note"))) { - out.setChoice(parseMetronomeChoice(el, cursor)); + out.setChoice(parseMetronomeChoice(el, cursor, context)); } else { diff --git a/src/private/mx/core/generated/Metronome.h b/src/private/mx/core/generated/Metronome.h index 1b2114531..e8bacdc8f 100644 --- a/src/private/mx/core/generated/Metronome.h +++ b/src/private/mx/core/generated/Metronome.h @@ -28,6 +28,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The metronome type represents metronome marks and other metric relationships. The beat-unit group /// and per-minute element specify regular metronome marks. The metronome-note and metronome-relation /// elements allow for the specification of metric modulations and other metric relationships, such @@ -97,8 +99,12 @@ class Metronome final Metronome parseMetronome(pugi::xml_node el); +Metronome parseMetronome(pugi::xml_node el, const ParseContext &context); + void parseMetronomeContent(Metronome &out, pugi::xml_node el); +void parseMetronomeContent(Metronome &out, pugi::xml_node el, const ParseContext &context); + void serializeMetronome(const Metronome &v, pugi::xml_node parent, const char *tag); void serializeMetronomeContent(const Metronome &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/MetronomeBeam.cpp b/src/private/mx/core/generated/MetronomeBeam.cpp index 231377fe8..5264d51ff 100644 --- a/src/private/mx/core/generated/MetronomeBeam.cpp +++ b/src/private/mx/core/generated/MetronomeBeam.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/MetronomeBeam.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void MetronomeBeam::setValue(BeamValue value) } MetronomeBeam parseMetronomeBeam(pugi::xml_node el) +{ + return parseMetronomeBeam(el, ParseContext{}); +} + +MetronomeBeam parseMetronomeBeam(pugi::xml_node el, const ParseContext &context) { MetronomeBeam out; for (pugi::xml_attribute a : el.attributes()) @@ -42,20 +48,25 @@ MetronomeBeam parseMetronomeBeam(pugi::xml_node el) } if (aname == "number") { - out.setNumber(BeamLevel::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else { throwUnknownAttribute(el, a.name()); } } - parseMetronomeBeamContent(out, el); + parseMetronomeBeamContent(out, el, context); return out; } void parseMetronomeBeamContent(MetronomeBeam &out, pugi::xml_node el) { - out.setValue(BeamValue::parse(childText(el))); + parseMetronomeBeamContent(out, el, ParseContext{}); +} + +void parseMetronomeBeamContent(MetronomeBeam &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/MetronomeBeam.h b/src/private/mx/core/generated/MetronomeBeam.h index da7bd01a9..29bdb8aaa 100644 --- a/src/private/mx/core/generated/MetronomeBeam.h +++ b/src/private/mx/core/generated/MetronomeBeam.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The metronome-beam type works like the beam type in defining metric relationships, but does not /// include all the attributes available in the beam type. class MetronomeBeam final @@ -34,8 +36,12 @@ class MetronomeBeam final MetronomeBeam parseMetronomeBeam(pugi::xml_node el); +MetronomeBeam parseMetronomeBeam(pugi::xml_node el, const ParseContext &context); + void parseMetronomeBeamContent(MetronomeBeam &out, pugi::xml_node el); +void parseMetronomeBeamContent(MetronomeBeam &out, pugi::xml_node el, const ParseContext &context); + void serializeMetronomeBeam(const MetronomeBeam &v, pugi::xml_node parent, const char *tag); void serializeMetronomeBeamContent(const MetronomeBeam &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/MetronomeChoice.cpp b/src/private/mx/core/generated/MetronomeChoice.cpp index 75425ec78..a1f87b7bb 100644 --- a/src/private/mx/core/generated/MetronomeChoice.cpp +++ b/src/private/mx/core/generated/MetronomeChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/MetronomeChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -26,14 +27,19 @@ MetronomeChoice MetronomeChoice::group2(MetronomeChoiceGroup2 value) } MetronomeChoice parseMetronomeChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseMetronomeChoice(el, cursor, ParseContext{}); +} + +MetronomeChoice parseMetronomeChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "beat-unit"))) { - return MetronomeChoice::group(parseMetronomeChoiceGroup(el, cursor)); + return MetronomeChoice::group(parseMetronomeChoiceGroup(el, cursor, context)); } if (cursor && (cursorIs(cursor, "metronome-arrows") || cursorIs(cursor, "metronome-note"))) { - return MetronomeChoice::group2(parseMetronomeChoiceGroup2(el, cursor)); + return MetronomeChoice::group2(parseMetronomeChoiceGroup2(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/MetronomeChoice.h b/src/private/mx/core/generated/MetronomeChoice.h index c249bfedc..df699be80 100644 --- a/src/private/mx/core/generated/MetronomeChoice.h +++ b/src/private/mx/core/generated/MetronomeChoice.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -82,6 +84,8 @@ class MetronomeChoice final /// the enclosing element, for error paths. MetronomeChoice parseMetronomeChoice(pugi::xml_node el, pugi::xml_node &cursor); +MetronomeChoice parseMetronomeChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeMetronomeChoice(const MetronomeChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/MetronomeChoiceGroup.cpp b/src/private/mx/core/generated/MetronomeChoiceGroup.cpp index 7a54bf11f..dfb524bc5 100644 --- a/src/private/mx/core/generated/MetronomeChoiceGroup.cpp +++ b/src/private/mx/core/generated/MetronomeChoiceGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/MetronomeChoiceGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -46,11 +47,16 @@ void MetronomeChoiceGroup::setChoice(MetronomeChoiceGroupChoice value) } MetronomeChoiceGroup parseMetronomeChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseMetronomeChoiceGroup(el, cursor, ParseContext{}); +} + +MetronomeChoiceGroup parseMetronomeChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { MetronomeChoiceGroup out; if (cursor && (cursorIs(cursor, "beat-unit"))) { - out.setBeatUnit(parseBeatUnitGroup(el, cursor)); + out.setBeatUnit(parseBeatUnitGroup(el, cursor, context)); } else { @@ -58,12 +64,12 @@ MetronomeChoiceGroup parseMetronomeChoiceGroup(pugi::xml_node el, pugi::xml_node } while (cursorIs(cursor, "beat-unit-tied")) { - out.addBeatUnitTied(parseBeatUnitTied(cursor)); + out.addBeatUnitTied(parseBeatUnitTied(cursor, context)); cursor = nextElement(cursor); } if (cursor && (cursorIs(cursor, "per-minute") || cursorIs(cursor, "beat-unit"))) { - out.setChoice(parseMetronomeChoiceGroupChoice(el, cursor)); + out.setChoice(parseMetronomeChoiceGroupChoice(el, cursor, context)); } else { diff --git a/src/private/mx/core/generated/MetronomeChoiceGroup.h b/src/private/mx/core/generated/MetronomeChoiceGroup.h index 76457a185..cc6789677 100644 --- a/src/private/mx/core/generated/MetronomeChoiceGroup.h +++ b/src/private/mx/core/generated/MetronomeChoiceGroup.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A shared content group (synthesized from an anonymous /// particle of the schema): transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -44,6 +46,8 @@ class MetronomeChoiceGroup final /// is the enclosing element, for error paths. MetronomeChoiceGroup parseMetronomeChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor); +MetronomeChoiceGroup parseMetronomeChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeMetronomeChoiceGroup(const MetronomeChoiceGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/MetronomeChoiceGroup2.cpp b/src/private/mx/core/generated/MetronomeChoiceGroup2.cpp index 4db5e1c25..8c420a60f 100644 --- a/src/private/mx/core/generated/MetronomeChoiceGroup2.cpp +++ b/src/private/mx/core/generated/MetronomeChoiceGroup2.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/MetronomeChoiceGroup2.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -46,11 +47,16 @@ void MetronomeChoiceGroup2::setGroup(std::optional v } MetronomeChoiceGroup2 parseMetronomeChoiceGroup2(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseMetronomeChoiceGroup2(el, cursor, ParseContext{}); +} + +MetronomeChoiceGroup2 parseMetronomeChoiceGroup2(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { MetronomeChoiceGroup2 out; if (cursorIs(cursor, "metronome-arrows")) { - parseEmpty(cursor); + parseEmpty(cursor, context); out.setMetronomeArrows(true); cursor = nextElement(cursor); } @@ -58,16 +64,16 @@ MetronomeChoiceGroup2 parseMetronomeChoiceGroup2(pugi::xml_node el, pugi::xml_no { throwMissingOrMisplaced(el, cursor, "metronome-note"); } - out.setMetronomeNote(OneOrMore{parseMetronomeNote(cursor)}); + out.setMetronomeNote(OneOrMore{parseMetronomeNote(cursor, context)}); cursor = nextElement(cursor); while (cursorIs(cursor, "metronome-note")) { - out.addMetronomeNote(parseMetronomeNote(cursor)); + out.addMetronomeNote(parseMetronomeNote(cursor, context)); cursor = nextElement(cursor); } if (cursor && (cursorIs(cursor, "metronome-relation"))) { - out.setGroup(parseMetronomeChoiceGroup2Group(el, cursor)); + out.setGroup(parseMetronomeChoiceGroup2Group(el, cursor, context)); } return out; } diff --git a/src/private/mx/core/generated/MetronomeChoiceGroup2.h b/src/private/mx/core/generated/MetronomeChoiceGroup2.h index 0cd762c50..e52cf13be 100644 --- a/src/private/mx/core/generated/MetronomeChoiceGroup2.h +++ b/src/private/mx/core/generated/MetronomeChoiceGroup2.h @@ -20,6 +20,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A shared content group (synthesized from an anonymous /// particle of the schema): transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -45,6 +47,9 @@ class MetronomeChoiceGroup2 final /// is the enclosing element, for error paths. MetronomeChoiceGroup2 parseMetronomeChoiceGroup2(pugi::xml_node el, pugi::xml_node &cursor); +MetronomeChoiceGroup2 parseMetronomeChoiceGroup2(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context); + void serializeMetronomeChoiceGroup2(const MetronomeChoiceGroup2 &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/MetronomeChoiceGroup2Group.cpp b/src/private/mx/core/generated/MetronomeChoiceGroup2Group.cpp index 465462887..0035db016 100644 --- a/src/private/mx/core/generated/MetronomeChoiceGroup2Group.cpp +++ b/src/private/mx/core/generated/MetronomeChoiceGroup2Group.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/MetronomeChoiceGroup2Group.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -36,6 +37,12 @@ void MetronomeChoiceGroup2Group::setMetronomeNote(OneOrMore value } MetronomeChoiceGroup2Group parseMetronomeChoiceGroup2Group(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseMetronomeChoiceGroup2Group(el, cursor, ParseContext{}); +} + +MetronomeChoiceGroup2Group parseMetronomeChoiceGroup2Group(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context) { MetronomeChoiceGroup2Group out; if (cursorIs(cursor, "metronome-relation")) @@ -51,11 +58,11 @@ MetronomeChoiceGroup2Group parseMetronomeChoiceGroup2Group(pugi::xml_node el, pu { throwMissingOrMisplaced(el, cursor, "metronome-note"); } - out.setMetronomeNote(OneOrMore{parseMetronomeNote(cursor)}); + out.setMetronomeNote(OneOrMore{parseMetronomeNote(cursor, context)}); cursor = nextElement(cursor); while (cursorIs(cursor, "metronome-note")) { - out.addMetronomeNote(parseMetronomeNote(cursor)); + out.addMetronomeNote(parseMetronomeNote(cursor, context)); cursor = nextElement(cursor); } return out; diff --git a/src/private/mx/core/generated/MetronomeChoiceGroup2Group.h b/src/private/mx/core/generated/MetronomeChoiceGroup2Group.h index 1f6b5b406..e388b9acb 100644 --- a/src/private/mx/core/generated/MetronomeChoiceGroup2Group.h +++ b/src/private/mx/core/generated/MetronomeChoiceGroup2Group.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A shared content group (synthesized from an anonymous /// particle of the schema): transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -40,6 +42,9 @@ class MetronomeChoiceGroup2Group final /// is the enclosing element, for error paths. MetronomeChoiceGroup2Group parseMetronomeChoiceGroup2Group(pugi::xml_node el, pugi::xml_node &cursor); +MetronomeChoiceGroup2Group parseMetronomeChoiceGroup2Group(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context); + void serializeMetronomeChoiceGroup2Group(const MetronomeChoiceGroup2Group &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/MetronomeChoiceGroupChoice.cpp b/src/private/mx/core/generated/MetronomeChoiceGroupChoice.cpp index ae10bd9d3..e74c3ef42 100644 --- a/src/private/mx/core/generated/MetronomeChoiceGroupChoice.cpp +++ b/src/private/mx/core/generated/MetronomeChoiceGroupChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/MetronomeChoiceGroupChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -26,16 +27,22 @@ MetronomeChoiceGroupChoice MetronomeChoiceGroupChoice::group(MetronomeChoiceGrou } MetronomeChoiceGroupChoice parseMetronomeChoiceGroupChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseMetronomeChoiceGroupChoice(el, cursor, ParseContext{}); +} + +MetronomeChoiceGroupChoice parseMetronomeChoiceGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context) { if (cursor && (cursorIs(cursor, "per-minute"))) { - PerMinute value = parsePerMinute(cursor); + PerMinute value = parsePerMinute(cursor, context); cursor = nextElement(cursor); return MetronomeChoiceGroupChoice::perMinute(std::move(value)); } if (cursor && (cursorIs(cursor, "beat-unit"))) { - return MetronomeChoiceGroupChoice::group(parseMetronomeChoiceGroupChoiceGroup(el, cursor)); + return MetronomeChoiceGroupChoice::group(parseMetronomeChoiceGroupChoiceGroup(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/MetronomeChoiceGroupChoice.h b/src/private/mx/core/generated/MetronomeChoiceGroupChoice.h index 0723d330e..60615b112 100644 --- a/src/private/mx/core/generated/MetronomeChoiceGroupChoice.h +++ b/src/private/mx/core/generated/MetronomeChoiceGroupChoice.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -82,6 +84,9 @@ class MetronomeChoiceGroupChoice final /// the enclosing element, for error paths. MetronomeChoiceGroupChoice parseMetronomeChoiceGroupChoice(pugi::xml_node el, pugi::xml_node &cursor); +MetronomeChoiceGroupChoice parseMetronomeChoiceGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context); + void serializeMetronomeChoiceGroupChoice(const MetronomeChoiceGroupChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/MetronomeChoiceGroupChoiceGroup.cpp b/src/private/mx/core/generated/MetronomeChoiceGroupChoiceGroup.cpp index accaa60a9..1e88f0c5e 100644 --- a/src/private/mx/core/generated/MetronomeChoiceGroupChoiceGroup.cpp +++ b/src/private/mx/core/generated/MetronomeChoiceGroupChoiceGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/MetronomeChoiceGroupChoiceGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -36,11 +37,17 @@ void MetronomeChoiceGroupChoiceGroup::setBeatUnitTied(std::vector } MetronomeChoiceGroupChoiceGroup parseMetronomeChoiceGroupChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseMetronomeChoiceGroupChoiceGroup(el, cursor, ParseContext{}); +} + +MetronomeChoiceGroupChoiceGroup parseMetronomeChoiceGroupChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context) { MetronomeChoiceGroupChoiceGroup out; if (cursor && (cursorIs(cursor, "beat-unit"))) { - out.setBeatUnit(parseBeatUnitGroup(el, cursor)); + out.setBeatUnit(parseBeatUnitGroup(el, cursor, context)); } else { @@ -48,7 +55,7 @@ MetronomeChoiceGroupChoiceGroup parseMetronomeChoiceGroupChoiceGroup(pugi::xml_n } while (cursorIs(cursor, "beat-unit-tied")) { - out.addBeatUnitTied(parseBeatUnitTied(cursor)); + out.addBeatUnitTied(parseBeatUnitTied(cursor, context)); cursor = nextElement(cursor); } return out; diff --git a/src/private/mx/core/generated/MetronomeChoiceGroupChoiceGroup.h b/src/private/mx/core/generated/MetronomeChoiceGroupChoiceGroup.h index 3cd45ab8a..80325c517 100644 --- a/src/private/mx/core/generated/MetronomeChoiceGroupChoiceGroup.h +++ b/src/private/mx/core/generated/MetronomeChoiceGroupChoiceGroup.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A shared content group (synthesized from an anonymous /// particle of the schema): transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -40,6 +42,9 @@ class MetronomeChoiceGroupChoiceGroup final /// is the enclosing element, for error paths. MetronomeChoiceGroupChoiceGroup parseMetronomeChoiceGroupChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor); +MetronomeChoiceGroupChoiceGroup parseMetronomeChoiceGroupChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context); + void serializeMetronomeChoiceGroupChoiceGroup(const MetronomeChoiceGroupChoiceGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/MetronomeNote.cpp b/src/private/mx/core/generated/MetronomeNote.cpp index 0c700221e..340199f31 100644 --- a/src/private/mx/core/generated/MetronomeNote.cpp +++ b/src/private/mx/core/generated/MetronomeNote.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/MetronomeNote.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -71,6 +72,11 @@ void MetronomeNote::setMetronomeTuplet(std::optional value) } MetronomeNote parseMetronomeNote(pugi::xml_node el) +{ + return parseMetronomeNote(el, ParseContext{}); +} + +MetronomeNote parseMetronomeNote(pugi::xml_node el, const ParseContext &context) { MetronomeNote out; for (pugi::xml_attribute a : el.attributes()) @@ -82,16 +88,21 @@ MetronomeNote parseMetronomeNote(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseMetronomeNoteContent(out, el); + parseMetronomeNoteContent(out, el, context); return out; } void parseMetronomeNoteContent(MetronomeNote &out, pugi::xml_node el) +{ + parseMetronomeNoteContent(out, el, ParseContext{}); +} + +void parseMetronomeNoteContent(MetronomeNote &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "metronome-type")) { - out.setMetronomeType(NoteTypeValue::parse(childText(cursor))); + out.setMetronomeType(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -100,22 +111,22 @@ void parseMetronomeNoteContent(MetronomeNote &out, pugi::xml_node el) } while (cursorIs(cursor, "metronome-dot")) { - out.addMetronomeDot(parseEmpty(cursor)); + out.addMetronomeDot(parseEmpty(cursor, context)); cursor = nextElement(cursor); } while (cursorIs(cursor, "metronome-beam")) { - out.addMetronomeBeam(parseMetronomeBeam(cursor)); + out.addMetronomeBeam(parseMetronomeBeam(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "metronome-tied")) { - out.setMetronomeTied(parseMetronomeTied(cursor)); + out.setMetronomeTied(parseMetronomeTied(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "metronome-tuplet")) { - out.setMetronomeTuplet(parseMetronomeTuplet(cursor)); + out.setMetronomeTuplet(parseMetronomeTuplet(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/MetronomeNote.h b/src/private/mx/core/generated/MetronomeNote.h index 44735bad9..08de394af 100644 --- a/src/private/mx/core/generated/MetronomeNote.h +++ b/src/private/mx/core/generated/MetronomeNote.h @@ -21,6 +21,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The metronome-note type defines the appearance of a note within a metric relationship mark. /// Content fields mirror the schema grammar in declaration order; the /// serializer walks them, so a wrong order is unrepresentable (plan ยง2.3). @@ -51,8 +53,12 @@ class MetronomeNote final MetronomeNote parseMetronomeNote(pugi::xml_node el); +MetronomeNote parseMetronomeNote(pugi::xml_node el, const ParseContext &context); + void parseMetronomeNoteContent(MetronomeNote &out, pugi::xml_node el); +void parseMetronomeNoteContent(MetronomeNote &out, pugi::xml_node el, const ParseContext &context); + void serializeMetronomeNote(const MetronomeNote &v, pugi::xml_node parent, const char *tag); void serializeMetronomeNoteContent(const MetronomeNote &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/MetronomeTied.cpp b/src/private/mx/core/generated/MetronomeTied.cpp index 33d3705c1..c9ce0e358 100644 --- a/src/private/mx/core/generated/MetronomeTied.cpp +++ b/src/private/mx/core/generated/MetronomeTied.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/MetronomeTied.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -21,6 +22,11 @@ void MetronomeTied::setType(StartStop value) } MetronomeTied parseMetronomeTied(pugi::xml_node el) +{ + return parseMetronomeTied(el, ParseContext{}); +} + +MetronomeTied parseMetronomeTied(pugi::xml_node el, const ParseContext &context) { MetronomeTied out; bool seen_type = false; @@ -34,7 +40,7 @@ MetronomeTied parseMetronomeTied(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(StartStop::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else { @@ -45,13 +51,19 @@ MetronomeTied parseMetronomeTied(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseMetronomeTiedContent(out, el); + parseMetronomeTiedContent(out, el, context); return out; } void parseMetronomeTiedContent(MetronomeTied &out, pugi::xml_node el) +{ + parseMetronomeTiedContent(out, el, ParseContext{}); +} + +void parseMetronomeTiedContent(MetronomeTied &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/MetronomeTied.h b/src/private/mx/core/generated/MetronomeTied.h index 86419414c..81459817b 100644 --- a/src/private/mx/core/generated/MetronomeTied.h +++ b/src/private/mx/core/generated/MetronomeTied.h @@ -15,6 +15,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The metronome-tied indicates the presence of a tie within a metric relationship mark. As with the /// tied element, both the start and stop of the tie should be specified, in this case within /// separate metronome-note elements. @@ -31,8 +33,12 @@ class MetronomeTied final MetronomeTied parseMetronomeTied(pugi::xml_node el); +MetronomeTied parseMetronomeTied(pugi::xml_node el, const ParseContext &context); + void parseMetronomeTiedContent(MetronomeTied &out, pugi::xml_node el); +void parseMetronomeTiedContent(MetronomeTied &out, pugi::xml_node el, const ParseContext &context); + void serializeMetronomeTied(const MetronomeTied &v, pugi::xml_node parent, const char *tag); void serializeMetronomeTiedContent(const MetronomeTied &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/MetronomeTuplet.cpp b/src/private/mx/core/generated/MetronomeTuplet.cpp index dc03df05e..3447d92e4 100644 --- a/src/private/mx/core/generated/MetronomeTuplet.cpp +++ b/src/private/mx/core/generated/MetronomeTuplet.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/MetronomeTuplet.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,6 +42,11 @@ void MetronomeTuplet::setShowNumber(std::optional value) } MetronomeTuplet parseMetronomeTuplet(pugi::xml_node el) +{ + return parseMetronomeTuplet(el, ParseContext{}); +} + +MetronomeTuplet parseMetronomeTuplet(pugi::xml_node el, const ParseContext &context) { MetronomeTuplet out; bool seen_type = false; @@ -54,15 +60,15 @@ MetronomeTuplet parseMetronomeTuplet(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(StartStop::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "bracket") { - out.setBracket(YesNo::parse(a.value())); + out.setBracket(parseValue(a.value(), context, el, "bracket")); } else if (aname == "show-number") { - out.setShowNumber(ShowTuplet::parse(a.value())); + out.setShowNumber(parseValue(a.value(), context, el, "show-number")); } else { @@ -73,7 +79,7 @@ MetronomeTuplet parseMetronomeTuplet(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseTimeModificationContent(out, el); + parseTimeModificationContent(out, el, context); return out; } diff --git a/src/private/mx/core/generated/MetronomeTuplet.h b/src/private/mx/core/generated/MetronomeTuplet.h index 5c4a28ddf..c352496ed 100644 --- a/src/private/mx/core/generated/MetronomeTuplet.h +++ b/src/private/mx/core/generated/MetronomeTuplet.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The metronome-tuplet type uses the same element structure as the time-modification element along /// with some attributes from the tuplet element. /// The schema's complexContent extension: non-polymorphic public @@ -41,6 +43,8 @@ class MetronomeTuplet : public TimeModification MetronomeTuplet parseMetronomeTuplet(pugi::xml_node el); +MetronomeTuplet parseMetronomeTuplet(pugi::xml_node el, const ParseContext &context); + void serializeMetronomeTuplet(const MetronomeTuplet &v, pugi::xml_node parent, const char *tag); } // namespace mx::core diff --git a/src/private/mx/core/generated/Millimeters.cpp b/src/private/mx/core/generated/Millimeters.cpp index 11edc688a..93ee55e58 100644 --- a/src/private/mx/core/generated/Millimeters.cpp +++ b/src/private/mx/core/generated/Millimeters.cpp @@ -34,20 +34,33 @@ std::string Millimeters::toString() const bool Millimeters::tryParse(std::string_view text, Millimeters &out) { - Decimal v; - if (!Decimal::tryParse(text, v)) + ValueParseOutcome outcome = ValueParseOutcome::valid; + Millimeters parsed = parse(text, outcome); + if (outcome == ValueParseOutcome::invalid) { return false; } - out = Millimeters{std::move(v)}; + out = std::move(parsed); return true; } Millimeters Millimeters::parse(std::string_view text) { - Millimeters v; - tryParse(text, v); - return v; + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +Millimeters Millimeters::parse(std::string_view text, ValueParseOutcome &outcome) +{ + Decimal v; + if (!Decimal::tryParse(text, v)) + { + outcome = ValueParseOutcome::invalid; + return Millimeters{}; + } + Millimeters out{v}; + outcome = out.value() == v ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; } } // namespace mx::core diff --git a/src/private/mx/core/generated/Millimeters.h b/src/private/mx/core/generated/Millimeters.h index 806dc180d..411c7398e 100644 --- a/src/private/mx/core/generated/Millimeters.h +++ b/src/private/mx/core/generated/Millimeters.h @@ -3,6 +3,7 @@ #pragma once #include "mx/core/Decimal.h" +#include "mx/core/Lexical.h" #include #include @@ -38,6 +39,9 @@ class Millimeters final /// Lenient: non-numeric text yields the clamped zero. static Millimeters parse(std::string_view text); + /// Lenient, and says whether the text was non-numeric or clamped. + static Millimeters parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const Millimeters &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Milliseconds.cpp b/src/private/mx/core/generated/Milliseconds.cpp index 10d7e9e60..2b5e117fe 100644 --- a/src/private/mx/core/generated/Milliseconds.cpp +++ b/src/private/mx/core/generated/Milliseconds.cpp @@ -38,20 +38,33 @@ std::string Milliseconds::toString() const bool Milliseconds::tryParse(std::string_view text, Milliseconds &out) { - int v{}; - if (!tryParseInt(text, v)) + ValueParseOutcome outcome = ValueParseOutcome::valid; + Milliseconds parsed = parse(text, outcome); + if (outcome == ValueParseOutcome::invalid) { return false; } - out = Milliseconds{v}; + out = std::move(parsed); return true; } Milliseconds Milliseconds::parse(std::string_view text) { - Milliseconds v; - tryParse(text, v); - return v; + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +Milliseconds Milliseconds::parse(std::string_view text, ValueParseOutcome &outcome) +{ + int v{}; + if (!tryParseInt(text, v)) + { + outcome = ValueParseOutcome::invalid; + return Milliseconds{}; + } + Milliseconds out{v}; + outcome = out.value() == v ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; } } // namespace mx::core diff --git a/src/private/mx/core/generated/Milliseconds.h b/src/private/mx/core/generated/Milliseconds.h index f23cb66d2..198882f46 100644 --- a/src/private/mx/core/generated/Milliseconds.h +++ b/src/private/mx/core/generated/Milliseconds.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -35,6 +37,9 @@ class Milliseconds final /// Lenient: non-numeric text yields the clamped zero. static Milliseconds parse(std::string_view text); + /// Lenient, and says whether the text was non-numeric or clamped. + static Milliseconds parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const Milliseconds &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Miscellaneous.cpp b/src/private/mx/core/generated/Miscellaneous.cpp index c78033d28..6a79acc7c 100644 --- a/src/private/mx/core/generated/Miscellaneous.cpp +++ b/src/private/mx/core/generated/Miscellaneous.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Miscellaneous.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -26,6 +27,11 @@ void Miscellaneous::setMiscellaneousField(std::vector value) } Miscellaneous parseMiscellaneous(pugi::xml_node el) +{ + return parseMiscellaneous(el, ParseContext{}); +} + +Miscellaneous parseMiscellaneous(pugi::xml_node el, const ParseContext &context) { Miscellaneous out; for (pugi::xml_attribute a : el.attributes()) @@ -37,16 +43,21 @@ Miscellaneous parseMiscellaneous(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseMiscellaneousContent(out, el); + parseMiscellaneousContent(out, el, context); return out; } void parseMiscellaneousContent(Miscellaneous &out, pugi::xml_node el) +{ + parseMiscellaneousContent(out, el, ParseContext{}); +} + +void parseMiscellaneousContent(Miscellaneous &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); while (cursorIs(cursor, "miscellaneous-field")) { - out.addMiscellaneousField(parseMiscellaneousField(cursor)); + out.addMiscellaneousField(parseMiscellaneousField(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/Miscellaneous.h b/src/private/mx/core/generated/Miscellaneous.h index 01d0d1c46..d4d00d4c0 100644 --- a/src/private/mx/core/generated/Miscellaneous.h +++ b/src/private/mx/core/generated/Miscellaneous.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// If a program has other metadata not yet supported in the MusicXML format, it can go in the /// miscellaneous element. The miscellaneous type puts each separate part of metadata into its own /// miscellaneous-field type. @@ -36,8 +38,12 @@ class Miscellaneous final Miscellaneous parseMiscellaneous(pugi::xml_node el); +Miscellaneous parseMiscellaneous(pugi::xml_node el, const ParseContext &context); + void parseMiscellaneousContent(Miscellaneous &out, pugi::xml_node el); +void parseMiscellaneousContent(Miscellaneous &out, pugi::xml_node el, const ParseContext &context); + void serializeMiscellaneous(const Miscellaneous &v, pugi::xml_node parent, const char *tag); void serializeMiscellaneousContent(const Miscellaneous &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/MiscellaneousField.cpp b/src/private/mx/core/generated/MiscellaneousField.cpp index 083502967..781053262 100644 --- a/src/private/mx/core/generated/MiscellaneousField.cpp +++ b/src/private/mx/core/generated/MiscellaneousField.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/MiscellaneousField.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void MiscellaneousField::setValue(std::string value) } MiscellaneousField parseMiscellaneousField(pugi::xml_node el) +{ + return parseMiscellaneousField(el, ParseContext{}); +} + +MiscellaneousField parseMiscellaneousField(pugi::xml_node el, const ParseContext &context) { MiscellaneousField out; bool seen_name = false; @@ -55,11 +61,16 @@ MiscellaneousField parseMiscellaneousField(pugi::xml_node el) { throwMissingAttribute(el, "name"); } - parseMiscellaneousFieldContent(out, el); + parseMiscellaneousFieldContent(out, el, context); return out; } void parseMiscellaneousFieldContent(MiscellaneousField &out, pugi::xml_node el) +{ + parseMiscellaneousFieldContent(out, el, ParseContext{}); +} + +void parseMiscellaneousFieldContent(MiscellaneousField &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/MiscellaneousField.h b/src/private/mx/core/generated/MiscellaneousField.h index 5951dd8b3..a70884daa 100644 --- a/src/private/mx/core/generated/MiscellaneousField.h +++ b/src/private/mx/core/generated/MiscellaneousField.h @@ -13,6 +13,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// If a program has other metadata not yet supported in the MusicXML format, each type of metadata /// can go in a miscellaneous-field element. The required name attribute indicates the type of /// metadata the element content represents. @@ -32,8 +34,12 @@ class MiscellaneousField final MiscellaneousField parseMiscellaneousField(pugi::xml_node el); +MiscellaneousField parseMiscellaneousField(pugi::xml_node el, const ParseContext &context); + void parseMiscellaneousFieldContent(MiscellaneousField &out, pugi::xml_node el); +void parseMiscellaneousFieldContent(MiscellaneousField &out, pugi::xml_node el, const ParseContext &context); + void serializeMiscellaneousField(const MiscellaneousField &v, pugi::xml_node parent, const char *tag); void serializeMiscellaneousFieldContent(const MiscellaneousField &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Mode.cpp b/src/private/mx/core/generated/Mode.cpp index 937150740..b5ac25710 100644 --- a/src/private/mx/core/generated/Mode.cpp +++ b/src/private/mx/core/generated/Mode.cpp @@ -32,4 +32,11 @@ Mode Mode::parse(std::string_view text) return Mode{std::string{text}}; } +Mode Mode::parse(std::string_view text, ValueParseOutcome &outcome) +{ + Mode out{std::string{text}}; + outcome = out.value() == text ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; +} + } // namespace mx::core diff --git a/src/private/mx/core/generated/Mode.h b/src/private/mx/core/generated/Mode.h index f45cf7880..6efeb5a06 100644 --- a/src/private/mx/core/generated/Mode.h +++ b/src/private/mx/core/generated/Mode.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -35,6 +37,9 @@ class Mode final static Mode parse(std::string_view text); + /// Says whether the text had to be repaired. + static Mode parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const Mode &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Mordent.cpp b/src/private/mx/core/generated/Mordent.cpp index 8ad6701c0..87fa333ee 100644 --- a/src/private/mx/core/generated/Mordent.cpp +++ b/src/private/mx/core/generated/Mordent.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Mordent.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,6 +42,11 @@ void Mordent::setDeparture(std::optional value) } Mordent parseMordent(pugi::xml_node el) +{ + return parseMordent(el, ParseContext{}); +} + +Mordent parseMordent(pugi::xml_node el, const ParseContext &context) { Mordent out; for (pugi::xml_attribute a : el.attributes()) @@ -52,90 +58,90 @@ Mordent parseMordent(pugi::xml_node el) } if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else if (aname == "start-note") { - out.setStartNote(StartNote::parse(a.value())); + out.setStartNote(parseValue(a.value(), context, el, "start-note")); } else if (aname == "trill-step") { - out.setTrillStep(TrillStep::parse(a.value())); + out.setTrillStep(parseValue(a.value(), context, el, "trill-step")); } else if (aname == "two-note-turn") { - out.setTwoNoteTurn(TwoNoteTurn::parse(a.value())); + out.setTwoNoteTurn(parseValue(a.value(), context, el, "two-note-turn")); } else if (aname == "accelerate") { - out.setAccelerate(YesNo::parse(a.value())); + out.setAccelerate(parseValue(a.value(), context, el, "accelerate")); } else if (aname == "beats") { - out.setBeats(TrillBeats::parse(a.value())); + out.setBeats(parseValue(a.value(), context, el, "beats")); } else if (aname == "second-beat") { - out.setSecondBeat(Percent::parse(a.value())); + out.setSecondBeat(parseValue(a.value(), context, el, "second-beat")); } else if (aname == "last-beat") { - out.setLastBeat(Percent::parse(a.value())); + out.setLastBeat(parseValue(a.value(), context, el, "last-beat")); } else if (aname == "long") { - out.setLong(YesNo::parse(a.value())); + out.setLong(parseValue(a.value(), context, el, "long")); } else if (aname == "approach") { - out.setApproach(AboveBelow::parse(a.value())); + out.setApproach(parseValue(a.value(), context, el, "approach")); } else if (aname == "departure") { - out.setDeparture(AboveBelow::parse(a.value())); + out.setDeparture(parseValue(a.value(), context, el, "departure")); } else { throwUnknownAttribute(el, a.name()); } } - parseEmptyTrillSoundContent(out, el); + parseEmptyTrillSoundContent(out, el, context); return out; } diff --git a/src/private/mx/core/generated/Mordent.h b/src/private/mx/core/generated/Mordent.h index 27980f313..e9f30647f 100644 --- a/src/private/mx/core/generated/Mordent.h +++ b/src/private/mx/core/generated/Mordent.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The mordent type is used for both represents the mordent sign with the vertical line and the /// inverted-mordent sign without the line. The long attribute is "no" by default. The approach and /// departure attributes are used for compound ornaments, indicating how the beginning and ending of @@ -42,6 +44,8 @@ class Mordent : public EmptyTrillSound Mordent parseMordent(pugi::xml_node el); +Mordent parseMordent(pugi::xml_node el, const ParseContext &context); + void serializeMordent(const Mordent &v, pugi::xml_node parent, const char *tag); } // namespace mx::core diff --git a/src/private/mx/core/generated/MultipleRest.cpp b/src/private/mx/core/generated/MultipleRest.cpp index 4da046413..ecfaa0487 100644 --- a/src/private/mx/core/generated/MultipleRest.cpp +++ b/src/private/mx/core/generated/MultipleRest.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/MultipleRest.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void MultipleRest::setValue(int value) } MultipleRest parseMultipleRest(pugi::xml_node el) +{ + return parseMultipleRest(el, ParseContext{}); +} + +MultipleRest parseMultipleRest(pugi::xml_node el, const ParseContext &context) { MultipleRest out; for (pugi::xml_attribute a : el.attributes()) @@ -42,20 +48,25 @@ MultipleRest parseMultipleRest(pugi::xml_node el) } if (aname == "use-symbols") { - out.setUseSymbols(YesNo::parse(a.value())); + out.setUseSymbols(parseValue(a.value(), context, el, "use-symbols")); } else { throwUnknownAttribute(el, a.name()); } } - parseMultipleRestContent(out, el); + parseMultipleRestContent(out, el, context); return out; } void parseMultipleRestContent(MultipleRest &out, pugi::xml_node el) { - out.setValue(parseInt(childText(el))); + parseMultipleRestContent(out, el, ParseContext{}); +} + +void parseMultipleRestContent(MultipleRest &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseIntegerValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/MultipleRest.h b/src/private/mx/core/generated/MultipleRest.h index 1940adfb6..04e900f1e 100644 --- a/src/private/mx/core/generated/MultipleRest.h +++ b/src/private/mx/core/generated/MultipleRest.h @@ -15,6 +15,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The text of the multiple-rest type indicates the number of measures in the multiple rest. /// Multiple rests may use the 1-bar / 2-bar / 4-bar rest symbols, or a single shape. The use-symbols /// attribute indicates which to use; it is no if not specified. @@ -34,8 +36,12 @@ class MultipleRest final MultipleRest parseMultipleRest(pugi::xml_node el); +MultipleRest parseMultipleRest(pugi::xml_node el, const ParseContext &context); + void parseMultipleRestContent(MultipleRest &out, pugi::xml_node el); +void parseMultipleRestContent(MultipleRest &out, pugi::xml_node el, const ParseContext &context); + void serializeMultipleRest(const MultipleRest &v, pugi::xml_node parent, const char *tag); void serializeMultipleRestContent(const MultipleRest &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/MusicDataChoice.cpp b/src/private/mx/core/generated/MusicDataChoice.cpp index 4a51a2fe4..71bf96993 100644 --- a/src/private/mx/core/generated/MusicDataChoice.cpp +++ b/src/private/mx/core/generated/MusicDataChoice.cpp @@ -2,6 +2,7 @@ #include "mx/core/generated/MusicDataChoice.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -179,88 +180,93 @@ MusicDataChoice MusicDataChoice::bookmark(Bookmark value) } MusicDataChoice parseMusicDataChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseMusicDataChoice(el, cursor, ParseContext{}); +} + +MusicDataChoice parseMusicDataChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursorIs(cursor, "note")) { - Note value = parseNote(cursor); + Note value = parseNote(cursor, context); cursor = nextElement(cursor); return MusicDataChoice::note(std::move(value)); } if (cursorIs(cursor, "backup")) { - Backup value = parseBackup(cursor); + Backup value = parseBackup(cursor, context); cursor = nextElement(cursor); return MusicDataChoice::backup(std::move(value)); } if (cursorIs(cursor, "forward")) { - Forward value = parseForward(cursor); + Forward value = parseForward(cursor, context); cursor = nextElement(cursor); return MusicDataChoice::forward(std::move(value)); } if (cursorIs(cursor, "direction")) { - Direction value = parseDirection(cursor); + Direction value = parseDirection(cursor, context); cursor = nextElement(cursor); return MusicDataChoice::direction(std::move(value)); } if (cursorIs(cursor, "attributes")) { - Attributes value = parseAttributes(cursor); + Attributes value = parseAttributes(cursor, context); cursor = nextElement(cursor); return MusicDataChoice::attributes(std::move(value)); } if (cursorIs(cursor, "harmony")) { - Harmony value = parseHarmony(cursor); + Harmony value = parseHarmony(cursor, context); cursor = nextElement(cursor); return MusicDataChoice::harmony(std::move(value)); } if (cursorIs(cursor, "figured-bass")) { - FiguredBass value = parseFiguredBass(cursor); + FiguredBass value = parseFiguredBass(cursor, context); cursor = nextElement(cursor); return MusicDataChoice::figuredBass(std::move(value)); } if (cursorIs(cursor, "print")) { - Print value = parsePrint(cursor); + Print value = parsePrint(cursor, context); cursor = nextElement(cursor); return MusicDataChoice::print(std::move(value)); } if (cursorIs(cursor, "sound")) { - Sound value = parseSound(cursor); + Sound value = parseSound(cursor, context); cursor = nextElement(cursor); return MusicDataChoice::sound(std::move(value)); } if (cursorIs(cursor, "listening")) { - Listening value = parseListening(cursor); + Listening value = parseListening(cursor, context); cursor = nextElement(cursor); return MusicDataChoice::listening(std::move(value)); } if (cursorIs(cursor, "barline")) { - Barline value = parseBarline(cursor); + Barline value = parseBarline(cursor, context); cursor = nextElement(cursor); return MusicDataChoice::barline(std::move(value)); } if (cursorIs(cursor, "grouping")) { - Grouping value = parseGrouping(cursor); + Grouping value = parseGrouping(cursor, context); cursor = nextElement(cursor); return MusicDataChoice::grouping(std::move(value)); } if (cursorIs(cursor, "link")) { - Link value = parseLink(cursor); + Link value = parseLink(cursor, context); cursor = nextElement(cursor); return MusicDataChoice::link(std::move(value)); } if (cursorIs(cursor, "bookmark")) { - Bookmark value = parseBookmark(cursor); + Bookmark value = parseBookmark(cursor, context); cursor = nextElement(cursor); return MusicDataChoice::bookmark(std::move(value)); } diff --git a/src/private/mx/core/generated/MusicDataChoice.h b/src/private/mx/core/generated/MusicDataChoice.h index 230220b41..a80a4e68f 100644 --- a/src/private/mx/core/generated/MusicDataChoice.h +++ b/src/private/mx/core/generated/MusicDataChoice.h @@ -29,6 +29,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The music-data group contains the basic musical data that is either associated with a part or a /// measure, depending on whether the partwise or timewise hierarchy is used. /// A repeated heterogeneous choice with large alternatives: each is boxed @@ -277,6 +279,8 @@ class MusicDataChoice final /// the enclosing element, for error paths. MusicDataChoice parseMusicDataChoice(pugi::xml_node el, pugi::xml_node &cursor); +MusicDataChoice parseMusicDataChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeMusicDataChoice(const MusicDataChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/Mute.cpp b/src/private/mx/core/generated/Mute.cpp index e49dac800..c9b8c8f04 100644 --- a/src/private/mx/core/generated/Mute.cpp +++ b/src/private/mx/core/generated/Mute.cpp @@ -107,9 +107,15 @@ bool Mute::tryParse(std::string_view text, Mute &out) noexcept } Mute Mute::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +Mute Mute::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { Mute v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/Mute.h b/src/private/mx/core/generated/Mute.h index 4b7bff496..42c9af7da 100644 --- a/src/private/mx/core/generated/Mute.h +++ b/src/private/mx/core/generated/Mute.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -68,6 +70,9 @@ class Mute final /// (the import leniency policy; never produces an invalid value). static Mute parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static Mute parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const Mute &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/NameDisplay.cpp b/src/private/mx/core/generated/NameDisplay.cpp index e7e000e4d..029b8e402 100644 --- a/src/private/mx/core/generated/NameDisplay.cpp +++ b/src/private/mx/core/generated/NameDisplay.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/NameDisplay.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -36,6 +37,11 @@ void NameDisplay::setChoice(std::vector value) } NameDisplay parseNameDisplay(pugi::xml_node el) +{ + return parseNameDisplay(el, ParseContext{}); +} + +NameDisplay parseNameDisplay(pugi::xml_node el, const ParseContext &context) { NameDisplay out; for (pugi::xml_attribute a : el.attributes()) @@ -47,23 +53,28 @@ NameDisplay parseNameDisplay(pugi::xml_node el) } if (aname == "print-object") { - out.setPrintObject(YesNo::parse(a.value())); + out.setPrintObject(parseValue(a.value(), context, el, "print-object")); } else { throwUnknownAttribute(el, a.name()); } } - parseNameDisplayContent(out, el); + parseNameDisplayContent(out, el, context); return out; } void parseNameDisplayContent(NameDisplay &out, pugi::xml_node el) +{ + parseNameDisplayContent(out, el, ParseContext{}); +} + +void parseNameDisplayContent(NameDisplay &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); while (cursor && (cursorIs(cursor, "display-text") || cursorIs(cursor, "accidental-text"))) { - out.addChoice(parseNameDisplayChoice(el, cursor)); + out.addChoice(parseNameDisplayChoice(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/NameDisplay.h b/src/private/mx/core/generated/NameDisplay.h index 9a9179522..7d4101e00 100644 --- a/src/private/mx/core/generated/NameDisplay.h +++ b/src/private/mx/core/generated/NameDisplay.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The name-display type is used for exact formatting of multi-font text in part and group names to /// the left of the system. The print-object attribute can be used to determine what, if anything, is /// printed at the start of each system. Enclosure for the display-text element is none by default. @@ -41,8 +43,12 @@ class NameDisplay final NameDisplay parseNameDisplay(pugi::xml_node el); +NameDisplay parseNameDisplay(pugi::xml_node el, const ParseContext &context); + void parseNameDisplayContent(NameDisplay &out, pugi::xml_node el); +void parseNameDisplayContent(NameDisplay &out, pugi::xml_node el, const ParseContext &context); + void serializeNameDisplay(const NameDisplay &v, pugi::xml_node parent, const char *tag); void serializeNameDisplayContent(const NameDisplay &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/NameDisplayChoice.cpp b/src/private/mx/core/generated/NameDisplayChoice.cpp index 81e9480f8..f10145b50 100644 --- a/src/private/mx/core/generated/NameDisplayChoice.cpp +++ b/src/private/mx/core/generated/NameDisplayChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/NameDisplayChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -26,16 +27,21 @@ NameDisplayChoice NameDisplayChoice::accidentalText(AccidentalText value) } NameDisplayChoice parseNameDisplayChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseNameDisplayChoice(el, cursor, ParseContext{}); +} + +NameDisplayChoice parseNameDisplayChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "display-text"))) { - FormattedText value = parseFormattedText(cursor); + FormattedText value = parseFormattedText(cursor, context); cursor = nextElement(cursor); return NameDisplayChoice::displayText(std::move(value)); } if (cursor && (cursorIs(cursor, "accidental-text"))) { - AccidentalText value = parseAccidentalText(cursor); + AccidentalText value = parseAccidentalText(cursor, context); cursor = nextElement(cursor); return NameDisplayChoice::accidentalText(std::move(value)); } diff --git a/src/private/mx/core/generated/NameDisplayChoice.h b/src/private/mx/core/generated/NameDisplayChoice.h index e50909193..e9b7d0947 100644 --- a/src/private/mx/core/generated/NameDisplayChoice.h +++ b/src/private/mx/core/generated/NameDisplayChoice.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -82,6 +84,8 @@ class NameDisplayChoice final /// the enclosing element, for error paths. NameDisplayChoice parseNameDisplayChoice(pugi::xml_node el, pugi::xml_node &cursor); +NameDisplayChoice parseNameDisplayChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeNameDisplayChoice(const NameDisplayChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/NonArpeggiate.cpp b/src/private/mx/core/generated/NonArpeggiate.cpp index 9c3cc3c6d..7344afe0a 100644 --- a/src/private/mx/core/generated/NonArpeggiate.cpp +++ b/src/private/mx/core/generated/NonArpeggiate.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/NonArpeggiate.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -101,6 +102,11 @@ void NonArpeggiate::setID(std::optional value) } NonArpeggiate parseNonArpeggiate(pugi::xml_node el) +{ + return parseNonArpeggiate(el, ParseContext{}); +} + +NonArpeggiate parseNonArpeggiate(pugi::xml_node el, const ParseContext &context) { NonArpeggiate out; bool seen_type = false; @@ -114,35 +120,35 @@ NonArpeggiate parseNonArpeggiate(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(TopBottom::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "number") { - out.setNumber(NumberLevel::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "id") { @@ -157,13 +163,19 @@ NonArpeggiate parseNonArpeggiate(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseNonArpeggiateContent(out, el); + parseNonArpeggiateContent(out, el, context); return out; } void parseNonArpeggiateContent(NonArpeggiate &out, pugi::xml_node el) +{ + parseNonArpeggiateContent(out, el, ParseContext{}); +} + +void parseNonArpeggiateContent(NonArpeggiate &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/NonArpeggiate.h b/src/private/mx/core/generated/NonArpeggiate.h index c24ef7f87..438c0f5a8 100644 --- a/src/private/mx/core/generated/NonArpeggiate.h +++ b/src/private/mx/core/generated/NonArpeggiate.h @@ -21,6 +21,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The non-arpeggiate type indicates that this note is at the top or bottom of a bracket indicating /// to not arpeggiate these notes. Since this does not involve playback, it is only used on the top /// or bottom notes, not on each note as for the arpeggiate type. @@ -61,8 +63,12 @@ class NonArpeggiate final NonArpeggiate parseNonArpeggiate(pugi::xml_node el); +NonArpeggiate parseNonArpeggiate(pugi::xml_node el, const ParseContext &context); + void parseNonArpeggiateContent(NonArpeggiate &out, pugi::xml_node el); +void parseNonArpeggiateContent(NonArpeggiate &out, pugi::xml_node el, const ParseContext &context); + void serializeNonArpeggiate(const NonArpeggiate &v, pugi::xml_node parent, const char *tag); void serializeNonArpeggiateContent(const NonArpeggiate &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/NonNegativeDecimal.cpp b/src/private/mx/core/generated/NonNegativeDecimal.cpp index c5e0374af..1944e573e 100644 --- a/src/private/mx/core/generated/NonNegativeDecimal.cpp +++ b/src/private/mx/core/generated/NonNegativeDecimal.cpp @@ -38,20 +38,33 @@ std::string NonNegativeDecimal::toString() const bool NonNegativeDecimal::tryParse(std::string_view text, NonNegativeDecimal &out) { - Decimal v; - if (!Decimal::tryParse(text, v)) + ValueParseOutcome outcome = ValueParseOutcome::valid; + NonNegativeDecimal parsed = parse(text, outcome); + if (outcome == ValueParseOutcome::invalid) { return false; } - out = NonNegativeDecimal{std::move(v)}; + out = std::move(parsed); return true; } NonNegativeDecimal NonNegativeDecimal::parse(std::string_view text) { - NonNegativeDecimal v; - tryParse(text, v); - return v; + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +NonNegativeDecimal NonNegativeDecimal::parse(std::string_view text, ValueParseOutcome &outcome) +{ + Decimal v; + if (!Decimal::tryParse(text, v)) + { + outcome = ValueParseOutcome::invalid; + return NonNegativeDecimal{}; + } + NonNegativeDecimal out{v}; + outcome = out.value() == v ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; } } // namespace mx::core diff --git a/src/private/mx/core/generated/NonNegativeDecimal.h b/src/private/mx/core/generated/NonNegativeDecimal.h index c0746d2ef..5b605f67b 100644 --- a/src/private/mx/core/generated/NonNegativeDecimal.h +++ b/src/private/mx/core/generated/NonNegativeDecimal.h @@ -3,6 +3,7 @@ #pragma once #include "mx/core/Decimal.h" +#include "mx/core/Lexical.h" #include #include @@ -37,6 +38,9 @@ class NonNegativeDecimal final /// Lenient: non-numeric text yields the clamped zero. static NonNegativeDecimal parse(std::string_view text); + /// Lenient, and says whether the text was non-numeric or clamped. + static NonNegativeDecimal parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const NonNegativeDecimal &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/NonTraditionalKeyGroup.cpp b/src/private/mx/core/generated/NonTraditionalKeyGroup.cpp index 9ad686ea0..d9c8c2d19 100644 --- a/src/private/mx/core/generated/NonTraditionalKeyGroup.cpp +++ b/src/private/mx/core/generated/NonTraditionalKeyGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/NonTraditionalKeyGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,11 +42,17 @@ void NonTraditionalKeyGroup::setKeyAccidental(std::optional value } NonTraditionalKeyGroup parseNonTraditionalKeyGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseNonTraditionalKeyGroup(el, cursor, ParseContext{}); +} + +NonTraditionalKeyGroup parseNonTraditionalKeyGroup(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context) { NonTraditionalKeyGroup out; if (cursorIs(cursor, "key-step")) { - out.setKeyStep(Step::parse(childText(cursor))); + out.setKeyStep(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -54,7 +61,7 @@ NonTraditionalKeyGroup parseNonTraditionalKeyGroup(pugi::xml_node el, pugi::xml_ } if (cursorIs(cursor, "key-alter")) { - out.setKeyAlter(Semitones::parse(childText(cursor))); + out.setKeyAlter(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -63,7 +70,7 @@ NonTraditionalKeyGroup parseNonTraditionalKeyGroup(pugi::xml_node el, pugi::xml_ } if (cursorIs(cursor, "key-accidental")) { - out.setKeyAccidental(parseKeyAccidental(cursor)); + out.setKeyAccidental(parseKeyAccidental(cursor, context)); cursor = nextElement(cursor); } return out; diff --git a/src/private/mx/core/generated/NonTraditionalKeyGroup.h b/src/private/mx/core/generated/NonTraditionalKeyGroup.h index 3ddb6a894..50b5591df 100644 --- a/src/private/mx/core/generated/NonTraditionalKeyGroup.h +++ b/src/private/mx/core/generated/NonTraditionalKeyGroup.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The non-traditional-key group represents a single alteration within a non-traditional key /// signature. A sequence of these groups makes up a non-traditional key signature /// A shared content group: transparent on the wire, its @@ -44,6 +46,9 @@ class NonTraditionalKeyGroup final /// is the enclosing element, for error paths. NonTraditionalKeyGroup parseNonTraditionalKeyGroup(pugi::xml_node el, pugi::xml_node &cursor); +NonTraditionalKeyGroup parseNonTraditionalKeyGroup(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context); + void serializeNonTraditionalKeyGroup(const NonTraditionalKeyGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/NormalNoteGroup.cpp b/src/private/mx/core/generated/NormalNoteGroup.cpp index 3f51a183f..281333072 100644 --- a/src/private/mx/core/generated/NormalNoteGroup.cpp +++ b/src/private/mx/core/generated/NormalNoteGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/NormalNoteGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -51,12 +52,17 @@ void NormalNoteGroup::clearTie() noexcept } NormalNoteGroup parseNormalNoteGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseNormalNoteGroup(el, cursor, ParseContext{}); +} + +NormalNoteGroup parseNormalNoteGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { NormalNoteGroup out; if (cursor && (cursorIs(cursor, "chord") || cursorIs(cursor, "pitch") || cursorIs(cursor, "unpitched") || cursorIs(cursor, "rest"))) { - out.setFullNote(parseFullNoteGroup(el, cursor)); + out.setFullNote(parseFullNoteGroup(el, cursor, context)); } else { @@ -64,7 +70,7 @@ NormalNoteGroup parseNormalNoteGroup(pugi::xml_node el, pugi::xml_node &cursor) } if (cursorIs(cursor, "duration")) { - out.setDuration(PositiveDivisions::parse(childText(cursor))); + out.setDuration(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -73,7 +79,7 @@ NormalNoteGroup parseNormalNoteGroup(pugi::xml_node el, pugi::xml_node &cursor) } while (cursorIs(cursor, "tie")) { - if (!out.addTie(parseTie(cursor))) + if (!out.addTie(parseTie(cursor, context))) { throwTooManyElements(cursor); } diff --git a/src/private/mx/core/generated/NormalNoteGroup.h b/src/private/mx/core/generated/NormalNoteGroup.h index 3fe87af62..5a4b48dcf 100644 --- a/src/private/mx/core/generated/NormalNoteGroup.h +++ b/src/private/mx/core/generated/NormalNoteGroup.h @@ -20,6 +20,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A shared content group (synthesized from an anonymous /// particle of the schema): transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -47,6 +49,8 @@ class NormalNoteGroup final /// is the enclosing element, for error paths. NormalNoteGroup parseNormalNoteGroup(pugi::xml_node el, pugi::xml_node &cursor); +NormalNoteGroup parseNormalNoteGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeNormalNoteGroup(const NormalNoteGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/Notations.cpp b/src/private/mx/core/generated/Notations.cpp index e8c219a50..b934c6ad4 100644 --- a/src/private/mx/core/generated/Notations.cpp +++ b/src/private/mx/core/generated/Notations.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Notations.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -56,6 +57,11 @@ void Notations::setChoice(std::vector value) } Notations parseNotations(pugi::xml_node el) +{ + return parseNotations(el, ParseContext{}); +} + +Notations parseNotations(pugi::xml_node el, const ParseContext &context) { Notations out; for (pugi::xml_attribute a : el.attributes()) @@ -67,7 +73,7 @@ Notations parseNotations(pugi::xml_node el) } if (aname == "print-object") { - out.setPrintObject(YesNo::parse(a.value())); + out.setPrintObject(parseValue(a.value(), context, el, "print-object")); } else if (aname == "id") { @@ -78,16 +84,21 @@ Notations parseNotations(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseNotationsContent(out, el); + parseNotationsContent(out, el, context); return out; } void parseNotationsContent(Notations &out, pugi::xml_node el) +{ + parseNotationsContent(out, el, ParseContext{}); +} + +void parseNotationsContent(Notations &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "footnote") || cursorIs(cursor, "level"))) { - out.setEditorial(parseEditorialGroup(el, cursor)); + out.setEditorial(parseEditorialGroup(el, cursor, context)); } while (cursor && (cursorIs(cursor, "tied") || cursorIs(cursor, "slur") || cursorIs(cursor, "tuplet") || @@ -96,7 +107,7 @@ void parseNotationsContent(Notations &out, pugi::xml_node el) cursorIs(cursor, "fermata") || cursorIs(cursor, "arpeggiate") || cursorIs(cursor, "non-arpeggiate") || cursorIs(cursor, "accidental-mark") || cursorIs(cursor, "other-notation"))) { - out.addChoice(parseNotationsChoice(el, cursor)); + out.addChoice(parseNotationsChoice(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/Notations.h b/src/private/mx/core/generated/Notations.h index 360ea1fa1..ce7012dea 100644 --- a/src/private/mx/core/generated/Notations.h +++ b/src/private/mx/core/generated/Notations.h @@ -21,6 +21,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Notations refer to musical notations, not XML notations. Multiple notations are allowed in order /// to represent multiple editorial levels. The print-object attribute, added in Version 3.0, allows /// notations to represent details of performance technique, such as fingerings, without having them @@ -50,8 +52,12 @@ class Notations final Notations parseNotations(pugi::xml_node el); +Notations parseNotations(pugi::xml_node el, const ParseContext &context); + void parseNotationsContent(Notations &out, pugi::xml_node el); +void parseNotationsContent(Notations &out, pugi::xml_node el, const ParseContext &context); + void serializeNotations(const Notations &v, pugi::xml_node parent, const char *tag); void serializeNotationsContent(const Notations &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/NotationsChoice.cpp b/src/private/mx/core/generated/NotationsChoice.cpp index dfb5b0b79..10a01a14d 100644 --- a/src/private/mx/core/generated/NotationsChoice.cpp +++ b/src/private/mx/core/generated/NotationsChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/NotationsChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -86,88 +87,93 @@ NotationsChoice NotationsChoice::otherNotation(OtherNotation value) } NotationsChoice parseNotationsChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseNotationsChoice(el, cursor, ParseContext{}); +} + +NotationsChoice parseNotationsChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "tied"))) { - Tied value = parseTied(cursor); + Tied value = parseTied(cursor, context); cursor = nextElement(cursor); return NotationsChoice::tied(std::move(value)); } if (cursor && (cursorIs(cursor, "slur"))) { - Slur value = parseSlur(cursor); + Slur value = parseSlur(cursor, context); cursor = nextElement(cursor); return NotationsChoice::slur(std::move(value)); } if (cursor && (cursorIs(cursor, "tuplet"))) { - Tuplet value = parseTuplet(cursor); + Tuplet value = parseTuplet(cursor, context); cursor = nextElement(cursor); return NotationsChoice::tuplet(std::move(value)); } if (cursor && (cursorIs(cursor, "glissando"))) { - Glissando value = parseGlissando(cursor); + Glissando value = parseGlissando(cursor, context); cursor = nextElement(cursor); return NotationsChoice::glissando(std::move(value)); } if (cursor && (cursorIs(cursor, "slide"))) { - Slide value = parseSlide(cursor); + Slide value = parseSlide(cursor, context); cursor = nextElement(cursor); return NotationsChoice::slide(std::move(value)); } if (cursor && (cursorIs(cursor, "ornaments"))) { - Ornaments value = parseOrnaments(cursor); + Ornaments value = parseOrnaments(cursor, context); cursor = nextElement(cursor); return NotationsChoice::ornaments(std::move(value)); } if (cursor && (cursorIs(cursor, "technical"))) { - Technical value = parseTechnical(cursor); + Technical value = parseTechnical(cursor, context); cursor = nextElement(cursor); return NotationsChoice::technical(std::move(value)); } if (cursor && (cursorIs(cursor, "articulations"))) { - Articulations value = parseArticulations(cursor); + Articulations value = parseArticulations(cursor, context); cursor = nextElement(cursor); return NotationsChoice::articulations(std::move(value)); } if (cursor && (cursorIs(cursor, "dynamics"))) { - Dynamics value = parseDynamics(cursor); + Dynamics value = parseDynamics(cursor, context); cursor = nextElement(cursor); return NotationsChoice::dynamics(std::move(value)); } if (cursor && (cursorIs(cursor, "fermata"))) { - Fermata value = parseFermata(cursor); + Fermata value = parseFermata(cursor, context); cursor = nextElement(cursor); return NotationsChoice::fermata(std::move(value)); } if (cursor && (cursorIs(cursor, "arpeggiate"))) { - Arpeggiate value = parseArpeggiate(cursor); + Arpeggiate value = parseArpeggiate(cursor, context); cursor = nextElement(cursor); return NotationsChoice::arpeggiate(std::move(value)); } if (cursor && (cursorIs(cursor, "non-arpeggiate"))) { - NonArpeggiate value = parseNonArpeggiate(cursor); + NonArpeggiate value = parseNonArpeggiate(cursor, context); cursor = nextElement(cursor); return NotationsChoice::nonArpeggiate(std::move(value)); } if (cursor && (cursorIs(cursor, "accidental-mark"))) { - AccidentalMark value = parseAccidentalMark(cursor); + AccidentalMark value = parseAccidentalMark(cursor, context); cursor = nextElement(cursor); return NotationsChoice::accidentalMark(std::move(value)); } if (cursor && (cursorIs(cursor, "other-notation"))) { - OtherNotation value = parseOtherNotation(cursor); + OtherNotation value = parseOtherNotation(cursor, context); cursor = nextElement(cursor); return NotationsChoice::otherNotation(std::move(value)); } diff --git a/src/private/mx/core/generated/NotationsChoice.h b/src/private/mx/core/generated/NotationsChoice.h index 88dc08d18..bb934b34b 100644 --- a/src/private/mx/core/generated/NotationsChoice.h +++ b/src/private/mx/core/generated/NotationsChoice.h @@ -30,6 +30,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -263,6 +265,8 @@ class NotationsChoice final /// the enclosing element, for error paths. NotationsChoice parseNotationsChoice(pugi::xml_node el, pugi::xml_node &cursor); +NotationsChoice parseNotationsChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeNotationsChoice(const NotationsChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/Note.cpp b/src/private/mx/core/generated/Note.cpp index e767fb695..ea7c5aa96 100644 --- a/src/private/mx/core/generated/Note.cpp +++ b/src/private/mx/core/generated/Note.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Note.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -411,6 +412,11 @@ void Note::setListen(std::optional value) } Note parseNote(pugi::xml_node el) +{ + return parseNote(el, ParseContext{}); +} + +Note parseNote(pugi::xml_node el, const ParseContext &context) { Note out; for (pugi::xml_attribute a : el.attributes()) @@ -422,83 +428,83 @@ Note parseNote(pugi::xml_node el) } if (aname == "print-leger") { - out.setPrintLeger(YesNo::parse(a.value())); + out.setPrintLeger(parseValue(a.value(), context, el, "print-leger")); } else if (aname == "dynamics") { - out.setDynamics(NonNegativeDecimal::parse(a.value())); + out.setDynamics(parseValue(a.value(), context, el, "dynamics")); } else if (aname == "end-dynamics") { - out.setEndDynamics(NonNegativeDecimal::parse(a.value())); + out.setEndDynamics(parseValue(a.value(), context, el, "end-dynamics")); } else if (aname == "attack") { - out.setAttack(Divisions::parse(a.value())); + out.setAttack(parseValue(a.value(), context, el, "attack")); } else if (aname == "release") { - out.setRelease(Divisions::parse(a.value())); + out.setRelease(parseValue(a.value(), context, el, "release")); } else if (aname == "time-only") { - out.setTimeOnly(TimeOnly::parse(a.value())); + out.setTimeOnly(parseValue(a.value(), context, el, "time-only")); } else if (aname == "pizzicato") { - out.setPizzicato(YesNo::parse(a.value())); + out.setPizzicato(parseValue(a.value(), context, el, "pizzicato")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "print-dot") { - out.setPrintDot(YesNo::parse(a.value())); + out.setPrintDot(parseValue(a.value(), context, el, "print-dot")); } else if (aname == "print-lyric") { - out.setPrintLyric(YesNo::parse(a.value())); + out.setPrintLyric(parseValue(a.value(), context, el, "print-lyric")); } else if (aname == "print-object") { - out.setPrintObject(YesNo::parse(a.value())); + out.setPrintObject(parseValue(a.value(), context, el, "print-object")); } else if (aname == "print-spacing") { - out.setPrintSpacing(YesNo::parse(a.value())); + out.setPrintSpacing(parseValue(a.value(), context, el, "print-spacing")); } else if (aname == "id") { @@ -509,17 +515,22 @@ Note parseNote(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseNoteContent(out, el); + parseNoteContent(out, el, context); return out; } void parseNoteContent(Note &out, pugi::xml_node el) +{ + parseNoteContent(out, el, ParseContext{}); +} + +void parseNoteContent(Note &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "grace") || cursorIs(cursor, "cue") || cursorIs(cursor, "chord") || cursorIs(cursor, "pitch") || cursorIs(cursor, "unpitched") || cursorIs(cursor, "rest"))) { - out.setChoice(parseNoteChoice(el, cursor)); + out.setChoice(parseNoteChoice(el, cursor, context)); } else { @@ -527,56 +538,56 @@ void parseNoteContent(Note &out, pugi::xml_node el) } while (cursorIs(cursor, "instrument")) { - out.addInstrument(parseInstrument(cursor)); + out.addInstrument(parseInstrument(cursor, context)); cursor = nextElement(cursor); } if (cursor && (cursorIs(cursor, "footnote") || cursorIs(cursor, "level") || cursorIs(cursor, "voice"))) { - out.setEditorialVoice(parseEditorialVoiceGroup(el, cursor)); + out.setEditorialVoice(parseEditorialVoiceGroup(el, cursor, context)); } if (cursorIs(cursor, "type")) { - out.setType(parseNoteType(cursor)); + out.setType(parseNoteType(cursor, context)); cursor = nextElement(cursor); } while (cursorIs(cursor, "dot")) { - out.addDot(parseEmptyPlacement(cursor)); + out.addDot(parseEmptyPlacement(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "accidental")) { - out.setAccidental(parseAccidental(cursor)); + out.setAccidental(parseAccidental(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "time-modification")) { - out.setTimeModification(parseTimeModification(cursor)); + out.setTimeModification(parseTimeModification(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "stem")) { - out.setStem(parseStem(cursor)); + out.setStem(parseStem(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "notehead")) { - out.setNotehead(parseNotehead(cursor)); + out.setNotehead(parseNotehead(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "notehead-text")) { - out.setNoteheadText(parseNoteheadText(cursor)); + out.setNoteheadText(parseNoteheadText(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "staff")) { - out.setStaff(parseInt(childText(cursor))); + out.setStaff(parseIntegerValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } while (cursorIs(cursor, "beam")) { - if (!out.addBeam(parseBeam(cursor))) + if (!out.addBeam(parseBeam(cursor, context))) { throwTooManyElements(cursor); } @@ -584,22 +595,22 @@ void parseNoteContent(Note &out, pugi::xml_node el) } while (cursorIs(cursor, "notations")) { - out.addNotations(parseNotations(cursor)); + out.addNotations(parseNotations(cursor, context)); cursor = nextElement(cursor); } while (cursorIs(cursor, "lyric")) { - out.addLyric(parseLyric(cursor)); + out.addLyric(parseLyric(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "play")) { - out.setPlay(parsePlay(cursor)); + out.setPlay(parsePlay(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "listen")) { - out.setListen(parseListen(cursor)); + out.setListen(parseListen(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/Note.h b/src/private/mx/core/generated/Note.h index 595cca438..af7c869f6 100644 --- a/src/private/mx/core/generated/Note.h +++ b/src/private/mx/core/generated/Note.h @@ -44,6 +44,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Notes are the most common type of MusicXML data. The MusicXML format distinguishes between /// elements used for sound information and elements used for notation information (e.g., tie is used /// for sound, tied for notation). Thus grace notes do not have a duration element. Cue notes have a @@ -195,8 +197,12 @@ class Note final Note parseNote(pugi::xml_node el); +Note parseNote(pugi::xml_node el, const ParseContext &context); + void parseNoteContent(Note &out, pugi::xml_node el); +void parseNoteContent(Note &out, pugi::xml_node el, const ParseContext &context); + void serializeNote(const Note &v, pugi::xml_node parent, const char *tag); void serializeNoteContent(const Note &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/NoteChoice.cpp b/src/private/mx/core/generated/NoteChoice.cpp index 9df834fdc..d4d59413e 100644 --- a/src/private/mx/core/generated/NoteChoice.cpp +++ b/src/private/mx/core/generated/NoteChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/NoteChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,19 +32,24 @@ NoteChoice NoteChoice::normalNoteGroup(NormalNoteGroup value) } NoteChoice parseNoteChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseNoteChoice(el, cursor, ParseContext{}); +} + +NoteChoice parseNoteChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "grace"))) { - return NoteChoice::graceNoteGroup(parseGraceNoteGroup(el, cursor)); + return NoteChoice::graceNoteGroup(parseGraceNoteGroup(el, cursor, context)); } if (cursor && (cursorIs(cursor, "cue"))) { - return NoteChoice::cueNoteGroup(parseCueNoteGroup(el, cursor)); + return NoteChoice::cueNoteGroup(parseCueNoteGroup(el, cursor, context)); } if (cursor && (cursorIs(cursor, "chord") || cursorIs(cursor, "pitch") || cursorIs(cursor, "unpitched") || cursorIs(cursor, "rest"))) { - return NoteChoice::normalNoteGroup(parseNormalNoteGroup(el, cursor)); + return NoteChoice::normalNoteGroup(parseNormalNoteGroup(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/NoteChoice.h b/src/private/mx/core/generated/NoteChoice.h index 9b691a501..a9fe4d6c2 100644 --- a/src/private/mx/core/generated/NoteChoice.h +++ b/src/private/mx/core/generated/NoteChoice.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -97,6 +99,8 @@ class NoteChoice final /// the enclosing element, for error paths. NoteChoice parseNoteChoice(pugi::xml_node el, pugi::xml_node &cursor); +NoteChoice parseNoteChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeNoteChoice(const NoteChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/NoteSize.cpp b/src/private/mx/core/generated/NoteSize.cpp index 8f6217a87..3e9c6ba05 100644 --- a/src/private/mx/core/generated/NoteSize.cpp +++ b/src/private/mx/core/generated/NoteSize.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/NoteSize.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void NoteSize::setValue(NonNegativeDecimal value) } NoteSize parseNoteSize(pugi::xml_node el) +{ + return parseNoteSize(el, ParseContext{}); +} + +NoteSize parseNoteSize(pugi::xml_node el, const ParseContext &context) { NoteSize out; bool seen_type = false; @@ -44,7 +50,7 @@ NoteSize parseNoteSize(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(NoteSizeType::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else { @@ -55,13 +61,18 @@ NoteSize parseNoteSize(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseNoteSizeContent(out, el); + parseNoteSizeContent(out, el, context); return out; } void parseNoteSizeContent(NoteSize &out, pugi::xml_node el) { - out.setValue(NonNegativeDecimal::parse(childText(el))); + parseNoteSizeContent(out, el, ParseContext{}); +} + +void parseNoteSizeContent(NoteSize &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/NoteSize.h b/src/private/mx/core/generated/NoteSize.h index 98a64c497..1c853308e 100644 --- a/src/private/mx/core/generated/NoteSize.h +++ b/src/private/mx/core/generated/NoteSize.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The note-size type indicates the percentage of the regular note size to use for notes with a cue /// and large size as defined in the type element. The grace type is used for notes of cue size that /// that include a grace element. The cue type is used for all other notes with cue size, whether @@ -38,8 +40,12 @@ class NoteSize final NoteSize parseNoteSize(pugi::xml_node el); +NoteSize parseNoteSize(pugi::xml_node el, const ParseContext &context); + void parseNoteSizeContent(NoteSize &out, pugi::xml_node el); +void parseNoteSizeContent(NoteSize &out, pugi::xml_node el, const ParseContext &context); + void serializeNoteSize(const NoteSize &v, pugi::xml_node parent, const char *tag); void serializeNoteSizeContent(const NoteSize &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/NoteSizeType.cpp b/src/private/mx/core/generated/NoteSizeType.cpp index 76201ab6a..e3e007793 100644 --- a/src/private/mx/core/generated/NoteSizeType.cpp +++ b/src/private/mx/core/generated/NoteSizeType.cpp @@ -54,9 +54,15 @@ bool NoteSizeType::tryParse(std::string_view text, NoteSizeType &out) noexcept } NoteSizeType NoteSizeType::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +NoteSizeType NoteSizeType::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { NoteSizeType v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/NoteSizeType.h b/src/private/mx/core/generated/NoteSizeType.h index 8c9fd8b53..0881973f7 100644 --- a/src/private/mx/core/generated/NoteSizeType.h +++ b/src/private/mx/core/generated/NoteSizeType.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -48,6 +50,9 @@ class NoteSizeType final /// (the import leniency policy; never produces an invalid value). static NoteSizeType parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static NoteSizeType parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const NoteSizeType &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/NoteType.cpp b/src/private/mx/core/generated/NoteType.cpp index 8cca5228a..622f37ab9 100644 --- a/src/private/mx/core/generated/NoteType.cpp +++ b/src/private/mx/core/generated/NoteType.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/NoteType.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void NoteType::setValue(NoteTypeValue value) } NoteType parseNoteType(pugi::xml_node el) +{ + return parseNoteType(el, ParseContext{}); +} + +NoteType parseNoteType(pugi::xml_node el, const ParseContext &context) { NoteType out; for (pugi::xml_attribute a : el.attributes()) @@ -42,20 +48,25 @@ NoteType parseNoteType(pugi::xml_node el) } if (aname == "size") { - out.setSize(SymbolSize::parse(a.value())); + out.setSize(parseValue(a.value(), context, el, "size")); } else { throwUnknownAttribute(el, a.name()); } } - parseNoteTypeContent(out, el); + parseNoteTypeContent(out, el, context); return out; } void parseNoteTypeContent(NoteType &out, pugi::xml_node el) { - out.setValue(NoteTypeValue::parse(childText(el))); + parseNoteTypeContent(out, el, ParseContext{}); +} + +void parseNoteTypeContent(NoteType &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/NoteType.h b/src/private/mx/core/generated/NoteType.h index c169cc106..8ebb9cb91 100644 --- a/src/private/mx/core/generated/NoteType.h +++ b/src/private/mx/core/generated/NoteType.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The note-type type indicates the graphic note type. Values range from 1024th to maxima. The size /// attribute indicates full, cue, grace-cue, or large size. The default is full for regular notes, /// grace-cue for notes that contain both grace and cue elements, and cue for notes that contain @@ -36,8 +38,12 @@ class NoteType final NoteType parseNoteType(pugi::xml_node el); +NoteType parseNoteType(pugi::xml_node el, const ParseContext &context); + void parseNoteTypeContent(NoteType &out, pugi::xml_node el); +void parseNoteTypeContent(NoteType &out, pugi::xml_node el, const ParseContext &context); + void serializeNoteType(const NoteType &v, pugi::xml_node parent, const char *tag); void serializeNoteTypeContent(const NoteType &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/NoteTypeValue.cpp b/src/private/mx/core/generated/NoteTypeValue.cpp index a38615d1a..0dbcb9455 100644 --- a/src/private/mx/core/generated/NoteTypeValue.cpp +++ b/src/private/mx/core/generated/NoteTypeValue.cpp @@ -102,9 +102,15 @@ bool NoteTypeValue::tryParse(std::string_view text, NoteTypeValue &out) noexcept } NoteTypeValue NoteTypeValue::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +NoteTypeValue NoteTypeValue::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { NoteTypeValue v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/NoteTypeValue.h b/src/private/mx/core/generated/NoteTypeValue.h index 0bc2b815e..58a08f3cf 100644 --- a/src/private/mx/core/generated/NoteTypeValue.h +++ b/src/private/mx/core/generated/NoteTypeValue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -65,6 +67,9 @@ class NoteTypeValue final /// (the import leniency policy; never produces an invalid value). static NoteTypeValue parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static NoteTypeValue parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const NoteTypeValue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Notehead.cpp b/src/private/mx/core/generated/Notehead.cpp index 696687d67..92f35e2e0 100644 --- a/src/private/mx/core/generated/Notehead.cpp +++ b/src/private/mx/core/generated/Notehead.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Notehead.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -101,6 +102,11 @@ void Notehead::setValue(NoteheadValue value) } Notehead parseNotehead(pugi::xml_node el) +{ + return parseNotehead(el, ParseContext{}); +} + +Notehead parseNotehead(pugi::xml_node el, const ParseContext &context) { Notehead out; for (pugi::xml_attribute a : el.attributes()) @@ -112,48 +118,53 @@ Notehead parseNotehead(pugi::xml_node el) } if (aname == "filled") { - out.setFilled(YesNo::parse(a.value())); + out.setFilled(parseValue(a.value(), context, el, "filled")); } else if (aname == "parentheses") { - out.setParentheses(YesNo::parse(a.value())); + out.setParentheses(parseValue(a.value(), context, el, "parentheses")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "smufl") { - out.setSmufl(SmuflGlyphName::parse(a.value())); + out.setSmufl(parseValue(a.value(), context, el, "smufl")); } else { throwUnknownAttribute(el, a.name()); } } - parseNoteheadContent(out, el); + parseNoteheadContent(out, el, context); return out; } void parseNoteheadContent(Notehead &out, pugi::xml_node el) { - out.setValue(NoteheadValue::parse(childText(el))); + parseNoteheadContent(out, el, ParseContext{}); +} + +void parseNoteheadContent(Notehead &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Notehead.h b/src/private/mx/core/generated/Notehead.h index 535cdc42b..6fc30f9b0 100644 --- a/src/private/mx/core/generated/Notehead.h +++ b/src/private/mx/core/generated/Notehead.h @@ -22,6 +22,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The notehead type indicates shapes other than the open and closed ovals associated with note /// durations. The smufl attribute can be used to specify a particular notehead, allowing application /// interoperability without requiring every SMuFL glyph to have a MusicXML element equivalent. This @@ -69,8 +71,12 @@ class Notehead final Notehead parseNotehead(pugi::xml_node el); +Notehead parseNotehead(pugi::xml_node el, const ParseContext &context); + void parseNoteheadContent(Notehead &out, pugi::xml_node el); +void parseNoteheadContent(Notehead &out, pugi::xml_node el, const ParseContext &context); + void serializeNotehead(const Notehead &v, pugi::xml_node parent, const char *tag); void serializeNoteheadContent(const Notehead &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/NoteheadText.cpp b/src/private/mx/core/generated/NoteheadText.cpp index fbe8aef3f..d294a41a5 100644 --- a/src/private/mx/core/generated/NoteheadText.cpp +++ b/src/private/mx/core/generated/NoteheadText.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/NoteheadText.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -26,6 +27,11 @@ void NoteheadText::setChoice(OneOrMore value) } NoteheadText parseNoteheadText(pugi::xml_node el) +{ + return parseNoteheadText(el, ParseContext{}); +} + +NoteheadText parseNoteheadText(pugi::xml_node el, const ParseContext &context) { NoteheadText out; for (pugi::xml_attribute a : el.attributes()) @@ -37,21 +43,26 @@ NoteheadText parseNoteheadText(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseNoteheadTextContent(out, el); + parseNoteheadTextContent(out, el, context); return out; } void parseNoteheadTextContent(NoteheadText &out, pugi::xml_node el) +{ + parseNoteheadTextContent(out, el, ParseContext{}); +} + +void parseNoteheadTextContent(NoteheadText &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (!(cursor && (cursorIs(cursor, "display-text") || cursorIs(cursor, "accidental-text")))) { throwMissingElement(el, "display-text"); } - out.setChoice(OneOrMore{parseNoteheadTextChoice(el, cursor)}); + out.setChoice(OneOrMore{parseNoteheadTextChoice(el, cursor, context)}); while (cursor && (cursorIs(cursor, "display-text") || cursorIs(cursor, "accidental-text"))) { - out.addChoice(parseNoteheadTextChoice(el, cursor)); + out.addChoice(parseNoteheadTextChoice(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/NoteheadText.h b/src/private/mx/core/generated/NoteheadText.h index e7e36ddc0..588797f83 100644 --- a/src/private/mx/core/generated/NoteheadText.h +++ b/src/private/mx/core/generated/NoteheadText.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The notehead-text type represents text that is displayed inside a notehead, as is done in some /// educational music. It is not needed for the numbers used in tablature or jianpu notation. The /// presence of a TAB or jianpu clefs is sufficient to indicate that numbers are used. The @@ -38,8 +40,12 @@ class NoteheadText final NoteheadText parseNoteheadText(pugi::xml_node el); +NoteheadText parseNoteheadText(pugi::xml_node el, const ParseContext &context); + void parseNoteheadTextContent(NoteheadText &out, pugi::xml_node el); +void parseNoteheadTextContent(NoteheadText &out, pugi::xml_node el, const ParseContext &context); + void serializeNoteheadText(const NoteheadText &v, pugi::xml_node parent, const char *tag); void serializeNoteheadTextContent(const NoteheadText &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/NoteheadTextChoice.cpp b/src/private/mx/core/generated/NoteheadTextChoice.cpp index 4949e4a3f..3884f46f2 100644 --- a/src/private/mx/core/generated/NoteheadTextChoice.cpp +++ b/src/private/mx/core/generated/NoteheadTextChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/NoteheadTextChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -26,16 +27,21 @@ NoteheadTextChoice NoteheadTextChoice::accidentalText(AccidentalText value) } NoteheadTextChoice parseNoteheadTextChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseNoteheadTextChoice(el, cursor, ParseContext{}); +} + +NoteheadTextChoice parseNoteheadTextChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "display-text"))) { - FormattedText value = parseFormattedText(cursor); + FormattedText value = parseFormattedText(cursor, context); cursor = nextElement(cursor); return NoteheadTextChoice::displayText(std::move(value)); } if (cursor && (cursorIs(cursor, "accidental-text"))) { - AccidentalText value = parseAccidentalText(cursor); + AccidentalText value = parseAccidentalText(cursor, context); cursor = nextElement(cursor); return NoteheadTextChoice::accidentalText(std::move(value)); } diff --git a/src/private/mx/core/generated/NoteheadTextChoice.h b/src/private/mx/core/generated/NoteheadTextChoice.h index 2572c5d93..2de216caa 100644 --- a/src/private/mx/core/generated/NoteheadTextChoice.h +++ b/src/private/mx/core/generated/NoteheadTextChoice.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -82,6 +84,8 @@ class NoteheadTextChoice final /// the enclosing element, for error paths. NoteheadTextChoice parseNoteheadTextChoice(pugi::xml_node el, pugi::xml_node &cursor); +NoteheadTextChoice parseNoteheadTextChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeNoteheadTextChoice(const NoteheadTextChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/NoteheadValue.cpp b/src/private/mx/core/generated/NoteheadValue.cpp index e46e5e08f..9489caafd 100644 --- a/src/private/mx/core/generated/NoteheadValue.cpp +++ b/src/private/mx/core/generated/NoteheadValue.cpp @@ -198,9 +198,15 @@ bool NoteheadValue::tryParse(std::string_view text, NoteheadValue &out) noexcept } NoteheadValue NoteheadValue::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +NoteheadValue NoteheadValue::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { NoteheadValue v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/NoteheadValue.h b/src/private/mx/core/generated/NoteheadValue.h index a339915c8..10bf12036 100644 --- a/src/private/mx/core/generated/NoteheadValue.h +++ b/src/private/mx/core/generated/NoteheadValue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -104,6 +106,9 @@ class NoteheadValue final /// (the import leniency policy; never produces an invalid value). static NoteheadValue parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static NoteheadValue parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const NoteheadValue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/NumberLevel.cpp b/src/private/mx/core/generated/NumberLevel.cpp index 8318801f6..0f3b3af3d 100644 --- a/src/private/mx/core/generated/NumberLevel.cpp +++ b/src/private/mx/core/generated/NumberLevel.cpp @@ -42,20 +42,33 @@ std::string NumberLevel::toString() const bool NumberLevel::tryParse(std::string_view text, NumberLevel &out) { - int v{}; - if (!tryParseInt(text, v)) + ValueParseOutcome outcome = ValueParseOutcome::valid; + NumberLevel parsed = parse(text, outcome); + if (outcome == ValueParseOutcome::invalid) { return false; } - out = NumberLevel{v}; + out = std::move(parsed); return true; } NumberLevel NumberLevel::parse(std::string_view text) { - NumberLevel v; - tryParse(text, v); - return v; + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +NumberLevel NumberLevel::parse(std::string_view text, ValueParseOutcome &outcome) +{ + int v{}; + if (!tryParseInt(text, v)) + { + outcome = ValueParseOutcome::invalid; + return NumberLevel{}; + } + NumberLevel out{v}; + outcome = out.value() == v ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; } } // namespace mx::core diff --git a/src/private/mx/core/generated/NumberLevel.h b/src/private/mx/core/generated/NumberLevel.h index e8cbd3def..591146bb2 100644 --- a/src/private/mx/core/generated/NumberLevel.h +++ b/src/private/mx/core/generated/NumberLevel.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -58,6 +60,9 @@ class NumberLevel final /// Lenient: non-numeric text yields the clamped zero. static NumberLevel parse(std::string_view text); + /// Lenient, and says whether the text was non-numeric or clamped. + static NumberLevel parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const NumberLevel &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/NumberOfLines.cpp b/src/private/mx/core/generated/NumberOfLines.cpp index a270f127a..f755cd608 100644 --- a/src/private/mx/core/generated/NumberOfLines.cpp +++ b/src/private/mx/core/generated/NumberOfLines.cpp @@ -42,20 +42,33 @@ std::string NumberOfLines::toString() const bool NumberOfLines::tryParse(std::string_view text, NumberOfLines &out) { - int v{}; - if (!tryParseInt(text, v)) + ValueParseOutcome outcome = ValueParseOutcome::valid; + NumberOfLines parsed = parse(text, outcome); + if (outcome == ValueParseOutcome::invalid) { return false; } - out = NumberOfLines{v}; + out = std::move(parsed); return true; } NumberOfLines NumberOfLines::parse(std::string_view text) { - NumberOfLines v; - tryParse(text, v); - return v; + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +NumberOfLines NumberOfLines::parse(std::string_view text, ValueParseOutcome &outcome) +{ + int v{}; + if (!tryParseInt(text, v)) + { + outcome = ValueParseOutcome::invalid; + return NumberOfLines{}; + } + NumberOfLines out{v}; + outcome = out.value() == v ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; } } // namespace mx::core diff --git a/src/private/mx/core/generated/NumberOfLines.h b/src/private/mx/core/generated/NumberOfLines.h index 76eb02a19..7e2b3e288 100644 --- a/src/private/mx/core/generated/NumberOfLines.h +++ b/src/private/mx/core/generated/NumberOfLines.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -35,6 +37,9 @@ class NumberOfLines final /// Lenient: non-numeric text yields the clamped zero. static NumberOfLines parse(std::string_view text); + /// Lenient, and says whether the text was non-numeric or clamped. + static NumberOfLines parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const NumberOfLines &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/NumberOrNormal.cpp b/src/private/mx/core/generated/NumberOrNormal.cpp index 76898e6d1..2b1e75bc1 100644 --- a/src/private/mx/core/generated/NumberOrNormal.cpp +++ b/src/private/mx/core/generated/NumberOrNormal.cpp @@ -56,12 +56,20 @@ bool NumberOrNormal::tryParse(std::string_view text, NumberOrNormal &out) } NumberOrNormal NumberOrNormal::parse(std::string_view text) +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +NumberOrNormal NumberOrNormal::parse(std::string_view text, ValueParseOutcome &outcome) { NumberOrNormal out; if (tryParse(text, out)) { + outcome = ValueParseOutcome::valid; return out; } + outcome = ValueParseOutcome::invalid; return NumberOrNormal::decimal(Decimal::parse(text)); } diff --git a/src/private/mx/core/generated/NumberOrNormal.h b/src/private/mx/core/generated/NumberOrNormal.h index 9688922c6..c733792a4 100644 --- a/src/private/mx/core/generated/NumberOrNormal.h +++ b/src/private/mx/core/generated/NumberOrNormal.h @@ -3,6 +3,7 @@ #pragma once #include "mx/core/Decimal.h" +#include "mx/core/Lexical.h" #include #include @@ -68,6 +69,10 @@ class NumberOrNormal final /// parse (never produces an invalid value). static NumberOrNormal parse(std::string_view text); + /// Lenient, and says whether no member matched or a matched number was + /// clamped. + static NumberOrNormal parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const NumberOrNormal &other) const = default; private: diff --git a/src/private/mx/core/generated/Numeral.cpp b/src/private/mx/core/generated/Numeral.cpp index 2ad954235..b97317b04 100644 --- a/src/private/mx/core/generated/Numeral.cpp +++ b/src/private/mx/core/generated/Numeral.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Numeral.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,6 +42,11 @@ void Numeral::setNumeralKey(std::optional value) } Numeral parseNumeral(pugi::xml_node el) +{ + return parseNumeral(el, ParseContext{}); +} + +Numeral parseNumeral(pugi::xml_node el, const ParseContext &context) { Numeral out; for (pugi::xml_attribute a : el.attributes()) @@ -52,16 +58,21 @@ Numeral parseNumeral(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseNumeralContent(out, el); + parseNumeralContent(out, el, context); return out; } void parseNumeralContent(Numeral &out, pugi::xml_node el) +{ + parseNumeralContent(out, el, ParseContext{}); +} + +void parseNumeralContent(Numeral &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "numeral-root")) { - out.setNumeralRoot(parseNumeralRoot(cursor)); + out.setNumeralRoot(parseNumeralRoot(cursor, context)); cursor = nextElement(cursor); } else @@ -70,12 +81,12 @@ void parseNumeralContent(Numeral &out, pugi::xml_node el) } if (cursorIs(cursor, "numeral-alter")) { - out.setNumeralAlter(parseHarmonyAlter(cursor)); + out.setNumeralAlter(parseHarmonyAlter(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "numeral-key")) { - out.setNumeralKey(parseNumeralKey(cursor)); + out.setNumeralKey(parseNumeralKey(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/Numeral.h b/src/private/mx/core/generated/Numeral.h index c13334ab2..1b0b4475c 100644 --- a/src/private/mx/core/generated/Numeral.h +++ b/src/private/mx/core/generated/Numeral.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The numeral type represents the Roman numeral or Nashville number part of a harmony. It requires /// that the key be specified in the encoding, either with a key or numeral-key element. /// Content fields mirror the schema grammar in declaration order; the @@ -42,8 +44,12 @@ class Numeral final Numeral parseNumeral(pugi::xml_node el); +Numeral parseNumeral(pugi::xml_node el, const ParseContext &context); + void parseNumeralContent(Numeral &out, pugi::xml_node el); +void parseNumeralContent(Numeral &out, pugi::xml_node el, const ParseContext &context); + void serializeNumeral(const Numeral &v, pugi::xml_node parent, const char *tag); void serializeNumeralContent(const Numeral &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/NumeralKey.cpp b/src/private/mx/core/generated/NumeralKey.cpp index 99a680947..7895796fa 100644 --- a/src/private/mx/core/generated/NumeralKey.cpp +++ b/src/private/mx/core/generated/NumeralKey.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/NumeralKey.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,6 +42,11 @@ void NumeralKey::setNumeralMode(NumeralMode value) } NumeralKey parseNumeralKey(pugi::xml_node el) +{ + return parseNumeralKey(el, ParseContext{}); +} + +NumeralKey parseNumeralKey(pugi::xml_node el, const ParseContext &context) { NumeralKey out; for (pugi::xml_attribute a : el.attributes()) @@ -52,23 +58,28 @@ NumeralKey parseNumeralKey(pugi::xml_node el) } if (aname == "print-object") { - out.setPrintObject(YesNo::parse(a.value())); + out.setPrintObject(parseValue(a.value(), context, el, "print-object")); } else { throwUnknownAttribute(el, a.name()); } } - parseNumeralKeyContent(out, el); + parseNumeralKeyContent(out, el, context); return out; } void parseNumeralKeyContent(NumeralKey &out, pugi::xml_node el) +{ + parseNumeralKeyContent(out, el, ParseContext{}); +} + +void parseNumeralKeyContent(NumeralKey &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "numeral-fifths")) { - out.setNumeralFifths(Fifths::parse(childText(cursor))); + out.setNumeralFifths(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -77,7 +88,7 @@ void parseNumeralKeyContent(NumeralKey &out, pugi::xml_node el) } if (cursorIs(cursor, "numeral-mode")) { - out.setNumeralMode(NumeralMode::parse(childText(cursor))); + out.setNumeralMode(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else diff --git a/src/private/mx/core/generated/NumeralKey.h b/src/private/mx/core/generated/NumeralKey.h index 758bd6076..08bd02a4b 100644 --- a/src/private/mx/core/generated/NumeralKey.h +++ b/src/private/mx/core/generated/NumeralKey.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The numeral-key type is used when the key for the numeral is different than the key specified by /// the key signature. The numeral-fifths element specifies the key in the same way as the fifths /// element. The numeral-mode element specifies the mode similar to the mode element, but with a @@ -44,8 +46,12 @@ class NumeralKey final NumeralKey parseNumeralKey(pugi::xml_node el); +NumeralKey parseNumeralKey(pugi::xml_node el, const ParseContext &context); + void parseNumeralKeyContent(NumeralKey &out, pugi::xml_node el); +void parseNumeralKeyContent(NumeralKey &out, pugi::xml_node el, const ParseContext &context); + void serializeNumeralKey(const NumeralKey &v, pugi::xml_node parent, const char *tag); void serializeNumeralKeyContent(const NumeralKey &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/NumeralMode.cpp b/src/private/mx/core/generated/NumeralMode.cpp index be73dabda..ed5c508f2 100644 --- a/src/private/mx/core/generated/NumeralMode.cpp +++ b/src/private/mx/core/generated/NumeralMode.cpp @@ -56,9 +56,15 @@ bool NumeralMode::tryParse(std::string_view text, NumeralMode &out) noexcept } NumeralMode NumeralMode::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +NumeralMode NumeralMode::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { NumeralMode v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/NumeralMode.h b/src/private/mx/core/generated/NumeralMode.h index 7d2179736..ad7e3b7d5 100644 --- a/src/private/mx/core/generated/NumeralMode.h +++ b/src/private/mx/core/generated/NumeralMode.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -50,6 +52,9 @@ class NumeralMode final /// (the import leniency policy; never produces an invalid value). static NumeralMode parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static NumeralMode parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const NumeralMode &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/NumeralRoot.cpp b/src/private/mx/core/generated/NumeralRoot.cpp index d95605add..74f95e76e 100644 --- a/src/private/mx/core/generated/NumeralRoot.cpp +++ b/src/private/mx/core/generated/NumeralRoot.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/NumeralRoot.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -121,6 +122,11 @@ void NumeralRoot::setValue(NumeralValue value) } NumeralRoot parseNumeralRoot(pugi::xml_node el) +{ + return parseNumeralRoot(el, ParseContext{}); +} + +NumeralRoot parseNumeralRoot(pugi::xml_node el, const ParseContext &context) { NumeralRoot out; for (pugi::xml_attribute a : el.attributes()) @@ -136,52 +142,57 @@ NumeralRoot parseNumeralRoot(pugi::xml_node el) } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else { throwUnknownAttribute(el, a.name()); } } - parseNumeralRootContent(out, el); + parseNumeralRootContent(out, el, context); return out; } void parseNumeralRootContent(NumeralRoot &out, pugi::xml_node el) { - out.setValue(NumeralValue::parse(childText(el))); + parseNumeralRootContent(out, el, ParseContext{}); +} + +void parseNumeralRootContent(NumeralRoot &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/NumeralRoot.h b/src/private/mx/core/generated/NumeralRoot.h index 517860baf..2e28ff007 100644 --- a/src/private/mx/core/generated/NumeralRoot.h +++ b/src/private/mx/core/generated/NumeralRoot.h @@ -21,6 +21,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The numeral-root type represents the Roman numeral or Nashville number as a positive integer from /// 1 to 7. The text attribute indicates how the numeral should appear in the score. A numeral-root /// value of 5 with a kind of major would have a text attribute of "V" if displayed as a Roman @@ -69,8 +71,12 @@ class NumeralRoot final NumeralRoot parseNumeralRoot(pugi::xml_node el); +NumeralRoot parseNumeralRoot(pugi::xml_node el, const ParseContext &context); + void parseNumeralRootContent(NumeralRoot &out, pugi::xml_node el); +void parseNumeralRootContent(NumeralRoot &out, pugi::xml_node el, const ParseContext &context); + void serializeNumeralRoot(const NumeralRoot &v, pugi::xml_node parent, const char *tag); void serializeNumeralRootContent(const NumeralRoot &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/NumeralValue.cpp b/src/private/mx/core/generated/NumeralValue.cpp index 2355ff18c..0e53f0ff1 100644 --- a/src/private/mx/core/generated/NumeralValue.cpp +++ b/src/private/mx/core/generated/NumeralValue.cpp @@ -42,20 +42,33 @@ std::string NumeralValue::toString() const bool NumeralValue::tryParse(std::string_view text, NumeralValue &out) { - int v{}; - if (!tryParseInt(text, v)) + ValueParseOutcome outcome = ValueParseOutcome::valid; + NumeralValue parsed = parse(text, outcome); + if (outcome == ValueParseOutcome::invalid) { return false; } - out = NumeralValue{v}; + out = std::move(parsed); return true; } NumeralValue NumeralValue::parse(std::string_view text) { - NumeralValue v; - tryParse(text, v); - return v; + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +NumeralValue NumeralValue::parse(std::string_view text, ValueParseOutcome &outcome) +{ + int v{}; + if (!tryParseInt(text, v)) + { + outcome = ValueParseOutcome::invalid; + return NumeralValue{}; + } + NumeralValue out{v}; + outcome = out.value() == v ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; } } // namespace mx::core diff --git a/src/private/mx/core/generated/NumeralValue.h b/src/private/mx/core/generated/NumeralValue.h index 177e12142..cb50396e8 100644 --- a/src/private/mx/core/generated/NumeralValue.h +++ b/src/private/mx/core/generated/NumeralValue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -36,6 +38,9 @@ class NumeralValue final /// Lenient: non-numeric text yields the clamped zero. static NumeralValue parse(std::string_view text); + /// Lenient, and says whether the text was non-numeric or clamped. + static NumeralValue parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const NumeralValue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Octave.cpp b/src/private/mx/core/generated/Octave.cpp index 2a6b34fd5..e7ed36e31 100644 --- a/src/private/mx/core/generated/Octave.cpp +++ b/src/private/mx/core/generated/Octave.cpp @@ -42,20 +42,33 @@ std::string Octave::toString() const bool Octave::tryParse(std::string_view text, Octave &out) { - int v{}; - if (!tryParseInt(text, v)) + ValueParseOutcome outcome = ValueParseOutcome::valid; + Octave parsed = parse(text, outcome); + if (outcome == ValueParseOutcome::invalid) { return false; } - out = Octave{v}; + out = std::move(parsed); return true; } Octave Octave::parse(std::string_view text) { - Octave v; - tryParse(text, v); - return v; + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +Octave Octave::parse(std::string_view text, ValueParseOutcome &outcome) +{ + int v{}; + if (!tryParseInt(text, v)) + { + outcome = ValueParseOutcome::invalid; + return Octave{}; + } + Octave out{v}; + outcome = out.value() == v ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; } } // namespace mx::core diff --git a/src/private/mx/core/generated/Octave.h b/src/private/mx/core/generated/Octave.h index 6606a1388..e4cca6fcd 100644 --- a/src/private/mx/core/generated/Octave.h +++ b/src/private/mx/core/generated/Octave.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -35,6 +37,9 @@ class Octave final /// Lenient: non-numeric text yields the clamped zero. static Octave parse(std::string_view text); + /// Lenient, and says whether the text was non-numeric or clamped. + static Octave parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const Octave &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/OctaveShift.cpp b/src/private/mx/core/generated/OctaveShift.cpp index 30328f9c6..60dd371b7 100644 --- a/src/private/mx/core/generated/OctaveShift.cpp +++ b/src/private/mx/core/generated/OctaveShift.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/OctaveShift.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -161,6 +162,11 @@ void OctaveShift::setID(std::optional value) } OctaveShift parseOctaveShift(pugi::xml_node el) +{ + return parseOctaveShift(el, ParseContext{}); +} + +OctaveShift parseOctaveShift(pugi::xml_node el, const ParseContext &context) { OctaveShift out; bool seen_type = false; @@ -174,59 +180,59 @@ OctaveShift parseOctaveShift(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(UpDownStopContinue::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "number") { - out.setNumber(NumberLevel::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else if (aname == "size") { - out.setSize(parseInt(a.value())); + out.setSize(parseIntegerValue(a.value(), context, el, "size")); } else if (aname == "dash-length") { - out.setDashLength(Tenths::parse(a.value())); + out.setDashLength(parseValue(a.value(), context, el, "dash-length")); } else if (aname == "space-length") { - out.setSpaceLength(Tenths::parse(a.value())); + out.setSpaceLength(parseValue(a.value(), context, el, "space-length")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "id") { @@ -241,13 +247,19 @@ OctaveShift parseOctaveShift(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseOctaveShiftContent(out, el); + parseOctaveShiftContent(out, el, context); return out; } void parseOctaveShiftContent(OctaveShift &out, pugi::xml_node el) +{ + parseOctaveShiftContent(out, el, ParseContext{}); +} + +void parseOctaveShiftContent(OctaveShift &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/OctaveShift.h b/src/private/mx/core/generated/OctaveShift.h index ad513dae9..d5ac32833 100644 --- a/src/private/mx/core/generated/OctaveShift.h +++ b/src/private/mx/core/generated/OctaveShift.h @@ -24,6 +24,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The octave shift type indicates where notes are shifted up or down from their true pitched values /// because of printing difficulty. Thus a treble clef line noted with 8va will be indicated with an /// octave-shift down from the pitch data indicated in the notes. A size of 8 indicates one octave; a @@ -83,8 +85,12 @@ class OctaveShift final OctaveShift parseOctaveShift(pugi::xml_node el); +OctaveShift parseOctaveShift(pugi::xml_node el, const ParseContext &context); + void parseOctaveShiftContent(OctaveShift &out, pugi::xml_node el); +void parseOctaveShiftContent(OctaveShift &out, pugi::xml_node el, const ParseContext &context); + void serializeOctaveShift(const OctaveShift &v, pugi::xml_node parent, const char *tag); void serializeOctaveShiftContent(const OctaveShift &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Offset.cpp b/src/private/mx/core/generated/Offset.cpp index 1293993c5..e5cdea0dc 100644 --- a/src/private/mx/core/generated/Offset.cpp +++ b/src/private/mx/core/generated/Offset.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Offset.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void Offset::setValue(Divisions value) } Offset parseOffset(pugi::xml_node el) +{ + return parseOffset(el, ParseContext{}); +} + +Offset parseOffset(pugi::xml_node el, const ParseContext &context) { Offset out; for (pugi::xml_attribute a : el.attributes()) @@ -42,20 +48,25 @@ Offset parseOffset(pugi::xml_node el) } if (aname == "sound") { - out.setSound(YesNo::parse(a.value())); + out.setSound(parseValue(a.value(), context, el, "sound")); } else { throwUnknownAttribute(el, a.name()); } } - parseOffsetContent(out, el); + parseOffsetContent(out, el, context); return out; } void parseOffsetContent(Offset &out, pugi::xml_node el) { - out.setValue(Divisions::parse(childText(el))); + parseOffsetContent(out, el, ParseContext{}); +} + +void parseOffsetContent(Offset &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Offset.h b/src/private/mx/core/generated/Offset.h index 9e2ae68b7..ffa7a53b4 100644 --- a/src/private/mx/core/generated/Offset.h +++ b/src/private/mx/core/generated/Offset.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// An offset is represented in terms of divisions, and indicates where the direction will appear /// relative to the current musical location. The current musical location is always within the /// current measure, even at the end of a measure. The offset affects the visual appearance of the @@ -40,8 +42,12 @@ class Offset final Offset parseOffset(pugi::xml_node el); +Offset parseOffset(pugi::xml_node el, const ParseContext &context); + void parseOffsetContent(Offset &out, pugi::xml_node el); +void parseOffsetContent(Offset &out, pugi::xml_node el, const ParseContext &context); + void serializeOffset(const Offset &v, pugi::xml_node parent, const char *tag); void serializeOffsetContent(const Offset &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/OnOff.cpp b/src/private/mx/core/generated/OnOff.cpp index ba5d4f34a..43715da20 100644 --- a/src/private/mx/core/generated/OnOff.cpp +++ b/src/private/mx/core/generated/OnOff.cpp @@ -42,9 +42,15 @@ bool OnOff::tryParse(std::string_view text, OnOff &out) noexcept } OnOff OnOff::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +OnOff OnOff::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { OnOff v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/OnOff.h b/src/private/mx/core/generated/OnOff.h index 0e3703fbd..e9ddcdf29 100644 --- a/src/private/mx/core/generated/OnOff.h +++ b/src/private/mx/core/generated/OnOff.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -40,6 +42,9 @@ class OnOff final /// (the import leniency policy; never produces an invalid value). static OnOff parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static OnOff parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const OnOff &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Opus.cpp b/src/private/mx/core/generated/Opus.cpp index 93223f5e5..611850bc7 100644 --- a/src/private/mx/core/generated/Opus.cpp +++ b/src/private/mx/core/generated/Opus.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Opus.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -71,6 +72,11 @@ void Opus::setXlinkActuate(std::optional value) } Opus parseOpus(pugi::xml_node el) +{ + return parseOpus(el, ParseContext{}); +} + +Opus parseOpus(pugi::xml_node el, const ParseContext &context) { Opus out; bool seen_xlinkHref = false; @@ -115,13 +121,19 @@ Opus parseOpus(pugi::xml_node el) { throwMissingAttribute(el, "xlink:href"); } - parseOpusContent(out, el); + parseOpusContent(out, el, context); return out; } void parseOpusContent(Opus &out, pugi::xml_node el) +{ + parseOpusContent(out, el, ParseContext{}); +} + +void parseOpusContent(Opus &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Opus.h b/src/private/mx/core/generated/Opus.h index 56810dde6..f1b1fb9bd 100644 --- a/src/private/mx/core/generated/Opus.h +++ b/src/private/mx/core/generated/Opus.h @@ -13,6 +13,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The opus type represents a link to a MusicXML opus document that composes multiple MusicXML /// scores into a collection. class Opus final @@ -43,8 +45,12 @@ class Opus final Opus parseOpus(pugi::xml_node el); +Opus parseOpus(pugi::xml_node el, const ParseContext &context); + void parseOpusContent(Opus &out, pugi::xml_node el); +void parseOpusContent(Opus &out, pugi::xml_node el, const ParseContext &context); + void serializeOpus(const Opus &v, pugi::xml_node parent, const char *tag); void serializeOpusContent(const Opus &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Ornaments.cpp b/src/private/mx/core/generated/Ornaments.cpp index 7c9626be7..3902e154b 100644 --- a/src/private/mx/core/generated/Ornaments.cpp +++ b/src/private/mx/core/generated/Ornaments.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Ornaments.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -36,6 +37,11 @@ void Ornaments::setGroup(std::vector value) } Ornaments parseOrnaments(pugi::xml_node el) +{ + return parseOrnaments(el, ParseContext{}); +} + +Ornaments parseOrnaments(pugi::xml_node el, const ParseContext &context) { Ornaments out; for (pugi::xml_attribute a : el.attributes()) @@ -54,11 +60,16 @@ Ornaments parseOrnaments(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseOrnamentsContent(out, el); + parseOrnamentsContent(out, el, context); return out; } void parseOrnamentsContent(Ornaments &out, pugi::xml_node el) +{ + parseOrnamentsContent(out, el, ParseContext{}); +} + +void parseOrnamentsContent(Ornaments &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); while (cursor && (cursorIs(cursor, "trill-mark") || cursorIs(cursor, "turn") || cursorIs(cursor, "delayed-turn") || @@ -68,7 +79,7 @@ void parseOrnamentsContent(Ornaments &out, pugi::xml_node el) cursorIs(cursor, "inverted-mordent") || cursorIs(cursor, "schleifer") || cursorIs(cursor, "tremolo") || cursorIs(cursor, "haydn") || cursorIs(cursor, "other-ornament"))) { - out.addGroup(parseOrnamentsGroup(el, cursor)); + out.addGroup(parseOrnamentsGroup(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/Ornaments.h b/src/private/mx/core/generated/Ornaments.h index 759df1242..8d5246f0b 100644 --- a/src/private/mx/core/generated/Ornaments.h +++ b/src/private/mx/core/generated/Ornaments.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Ornaments can be any of several types, followed optionally by accidentals. The accidental-mark /// element's content is represented the same as an accidental element, but with a different name to /// reflect the different musical meaning. @@ -41,8 +43,12 @@ class Ornaments final Ornaments parseOrnaments(pugi::xml_node el); +Ornaments parseOrnaments(pugi::xml_node el, const ParseContext &context); + void parseOrnamentsContent(Ornaments &out, pugi::xml_node el); +void parseOrnamentsContent(Ornaments &out, pugi::xml_node el, const ParseContext &context); + void serializeOrnaments(const Ornaments &v, pugi::xml_node parent, const char *tag); void serializeOrnamentsContent(const Ornaments &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/OrnamentsGroup.cpp b/src/private/mx/core/generated/OrnamentsGroup.cpp index 28dc41701..d732dc5a7 100644 --- a/src/private/mx/core/generated/OrnamentsGroup.cpp +++ b/src/private/mx/core/generated/OrnamentsGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/OrnamentsGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -36,6 +37,11 @@ void OrnamentsGroup::setAccidentalMark(std::vector value) } OrnamentsGroup parseOrnamentsGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseOrnamentsGroup(el, cursor, ParseContext{}); +} + +OrnamentsGroup parseOrnamentsGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { OrnamentsGroup out; if (cursor && (cursorIs(cursor, "trill-mark") || cursorIs(cursor, "turn") || cursorIs(cursor, "delayed-turn") || @@ -45,7 +51,7 @@ OrnamentsGroup parseOrnamentsGroup(pugi::xml_node el, pugi::xml_node &cursor) cursorIs(cursor, "inverted-mordent") || cursorIs(cursor, "schleifer") || cursorIs(cursor, "tremolo") || cursorIs(cursor, "haydn") || cursorIs(cursor, "other-ornament"))) { - out.setChoice(parseOrnamentsGroupChoice(el, cursor)); + out.setChoice(parseOrnamentsGroupChoice(el, cursor, context)); } else { @@ -53,7 +59,7 @@ OrnamentsGroup parseOrnamentsGroup(pugi::xml_node el, pugi::xml_node &cursor) } while (cursorIs(cursor, "accidental-mark")) { - out.addAccidentalMark(parseAccidentalMark(cursor)); + out.addAccidentalMark(parseAccidentalMark(cursor, context)); cursor = nextElement(cursor); } return out; diff --git a/src/private/mx/core/generated/OrnamentsGroup.h b/src/private/mx/core/generated/OrnamentsGroup.h index d1b3dc2dd..202d09a02 100644 --- a/src/private/mx/core/generated/OrnamentsGroup.h +++ b/src/private/mx/core/generated/OrnamentsGroup.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A shared content group (synthesized from an anonymous /// particle of the schema): transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -40,6 +42,8 @@ class OrnamentsGroup final /// is the enclosing element, for error paths. OrnamentsGroup parseOrnamentsGroup(pugi::xml_node el, pugi::xml_node &cursor); +OrnamentsGroup parseOrnamentsGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeOrnamentsGroup(const OrnamentsGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/OrnamentsGroupChoice.cpp b/src/private/mx/core/generated/OrnamentsGroupChoice.cpp index 4a2729824..e72220c8b 100644 --- a/src/private/mx/core/generated/OrnamentsGroupChoice.cpp +++ b/src/private/mx/core/generated/OrnamentsGroupChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/OrnamentsGroupChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -91,94 +92,99 @@ OrnamentsGroupChoice OrnamentsGroupChoice::otherOrnament(OtherPlacementText valu } OrnamentsGroupChoice parseOrnamentsGroupChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseOrnamentsGroupChoice(el, cursor, ParseContext{}); +} + +OrnamentsGroupChoice parseOrnamentsGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "trill-mark"))) { - EmptyTrillSound value = parseEmptyTrillSound(cursor); + EmptyTrillSound value = parseEmptyTrillSound(cursor, context); cursor = nextElement(cursor); return OrnamentsGroupChoice::trillMark(std::move(value)); } if (cursor && (cursorIs(cursor, "turn"))) { - HorizontalTurn value = parseHorizontalTurn(cursor); + HorizontalTurn value = parseHorizontalTurn(cursor, context); cursor = nextElement(cursor); return OrnamentsGroupChoice::turn(std::move(value)); } if (cursor && (cursorIs(cursor, "delayed-turn"))) { - HorizontalTurn value = parseHorizontalTurn(cursor); + HorizontalTurn value = parseHorizontalTurn(cursor, context); cursor = nextElement(cursor); return OrnamentsGroupChoice::delayedTurn(std::move(value)); } if (cursor && (cursorIs(cursor, "inverted-turn"))) { - HorizontalTurn value = parseHorizontalTurn(cursor); + HorizontalTurn value = parseHorizontalTurn(cursor, context); cursor = nextElement(cursor); return OrnamentsGroupChoice::invertedTurn(std::move(value)); } if (cursor && (cursorIs(cursor, "delayed-inverted-turn"))) { - HorizontalTurn value = parseHorizontalTurn(cursor); + HorizontalTurn value = parseHorizontalTurn(cursor, context); cursor = nextElement(cursor); return OrnamentsGroupChoice::delayedInvertedTurn(std::move(value)); } if (cursor && (cursorIs(cursor, "vertical-turn"))) { - EmptyTrillSound value = parseEmptyTrillSound(cursor); + EmptyTrillSound value = parseEmptyTrillSound(cursor, context); cursor = nextElement(cursor); return OrnamentsGroupChoice::verticalTurn(std::move(value)); } if (cursor && (cursorIs(cursor, "inverted-vertical-turn"))) { - EmptyTrillSound value = parseEmptyTrillSound(cursor); + EmptyTrillSound value = parseEmptyTrillSound(cursor, context); cursor = nextElement(cursor); return OrnamentsGroupChoice::invertedVerticalTurn(std::move(value)); } if (cursor && (cursorIs(cursor, "shake"))) { - EmptyTrillSound value = parseEmptyTrillSound(cursor); + EmptyTrillSound value = parseEmptyTrillSound(cursor, context); cursor = nextElement(cursor); return OrnamentsGroupChoice::shake(std::move(value)); } if (cursor && (cursorIs(cursor, "wavy-line"))) { - WavyLine value = parseWavyLine(cursor); + WavyLine value = parseWavyLine(cursor, context); cursor = nextElement(cursor); return OrnamentsGroupChoice::wavyLine(std::move(value)); } if (cursor && (cursorIs(cursor, "mordent"))) { - Mordent value = parseMordent(cursor); + Mordent value = parseMordent(cursor, context); cursor = nextElement(cursor); return OrnamentsGroupChoice::mordent(std::move(value)); } if (cursor && (cursorIs(cursor, "inverted-mordent"))) { - Mordent value = parseMordent(cursor); + Mordent value = parseMordent(cursor, context); cursor = nextElement(cursor); return OrnamentsGroupChoice::invertedMordent(std::move(value)); } if (cursor && (cursorIs(cursor, "schleifer"))) { - EmptyPlacement value = parseEmptyPlacement(cursor); + EmptyPlacement value = parseEmptyPlacement(cursor, context); cursor = nextElement(cursor); return OrnamentsGroupChoice::schleifer(std::move(value)); } if (cursor && (cursorIs(cursor, "tremolo"))) { - Tremolo value = parseTremolo(cursor); + Tremolo value = parseTremolo(cursor, context); cursor = nextElement(cursor); return OrnamentsGroupChoice::tremolo(std::move(value)); } if (cursor && (cursorIs(cursor, "haydn"))) { - EmptyTrillSound value = parseEmptyTrillSound(cursor); + EmptyTrillSound value = parseEmptyTrillSound(cursor, context); cursor = nextElement(cursor); return OrnamentsGroupChoice::haydn(std::move(value)); } if (cursor && (cursorIs(cursor, "other-ornament"))) { - OtherPlacementText value = parseOtherPlacementText(cursor); + OtherPlacementText value = parseOtherPlacementText(cursor, context); cursor = nextElement(cursor); return OrnamentsGroupChoice::otherOrnament(std::move(value)); } diff --git a/src/private/mx/core/generated/OrnamentsGroupChoice.h b/src/private/mx/core/generated/OrnamentsGroupChoice.h index 20ef16e94..d003f6b8c 100644 --- a/src/private/mx/core/generated/OrnamentsGroupChoice.h +++ b/src/private/mx/core/generated/OrnamentsGroupChoice.h @@ -23,6 +23,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -271,6 +273,8 @@ class OrnamentsGroupChoice final /// the enclosing element, for error paths. OrnamentsGroupChoice parseOrnamentsGroupChoice(pugi::xml_node el, pugi::xml_node &cursor); +OrnamentsGroupChoice parseOrnamentsGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeOrnamentsGroupChoice(const OrnamentsGroupChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/OtherAppearance.cpp b/src/private/mx/core/generated/OtherAppearance.cpp index 8eb6e9e55..ef3bbbc06 100644 --- a/src/private/mx/core/generated/OtherAppearance.cpp +++ b/src/private/mx/core/generated/OtherAppearance.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/OtherAppearance.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void OtherAppearance::setValue(std::string value) } OtherAppearance parseOtherAppearance(pugi::xml_node el) +{ + return parseOtherAppearance(el, ParseContext{}); +} + +OtherAppearance parseOtherAppearance(pugi::xml_node el, const ParseContext &context) { OtherAppearance out; bool seen_type = false; @@ -55,11 +61,16 @@ OtherAppearance parseOtherAppearance(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseOtherAppearanceContent(out, el); + parseOtherAppearanceContent(out, el, context); return out; } void parseOtherAppearanceContent(OtherAppearance &out, pugi::xml_node el) +{ + parseOtherAppearanceContent(out, el, ParseContext{}); +} + +void parseOtherAppearanceContent(OtherAppearance &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/OtherAppearance.h b/src/private/mx/core/generated/OtherAppearance.h index 0b1a245e1..bf266f212 100644 --- a/src/private/mx/core/generated/OtherAppearance.h +++ b/src/private/mx/core/generated/OtherAppearance.h @@ -13,6 +13,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The other-appearance type is used to define any graphical settings not yet in the current version /// of the MusicXML format. This allows extended representation, though without application /// interoperability. @@ -32,8 +34,12 @@ class OtherAppearance final OtherAppearance parseOtherAppearance(pugi::xml_node el); +OtherAppearance parseOtherAppearance(pugi::xml_node el, const ParseContext &context); + void parseOtherAppearanceContent(OtherAppearance &out, pugi::xml_node el); +void parseOtherAppearanceContent(OtherAppearance &out, pugi::xml_node el, const ParseContext &context); + void serializeOtherAppearance(const OtherAppearance &v, pugi::xml_node parent, const char *tag); void serializeOtherAppearanceContent(const OtherAppearance &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/OtherDirection.cpp b/src/private/mx/core/generated/OtherDirection.cpp index 387eefd1b..8edcd06ad 100644 --- a/src/private/mx/core/generated/OtherDirection.cpp +++ b/src/private/mx/core/generated/OtherDirection.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/OtherDirection.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -161,6 +162,11 @@ void OtherDirection::setValue(std::string value) } OtherDirection parseOtherDirection(pugi::xml_node el) +{ + return parseOtherDirection(el, ParseContext{}); +} + +OtherDirection parseOtherDirection(pugi::xml_node el, const ParseContext &context) { OtherDirection out; for (pugi::xml_attribute a : el.attributes()) @@ -172,55 +178,55 @@ OtherDirection parseOtherDirection(pugi::xml_node el) } if (aname == "print-object") { - out.setPrintObject(YesNo::parse(a.value())); + out.setPrintObject(parseValue(a.value(), context, el, "print-object")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "halign") { - out.setHalign(LeftCenterRight::parse(a.value())); + out.setHalign(parseValue(a.value(), context, el, "halign")); } else if (aname == "valign") { - out.setValign(Valign::parse(a.value())); + out.setValign(parseValue(a.value(), context, el, "valign")); } else if (aname == "smufl") { - out.setSmufl(SmuflGlyphName::parse(a.value())); + out.setSmufl(parseValue(a.value(), context, el, "smufl")); } else if (aname == "id") { @@ -231,11 +237,16 @@ OtherDirection parseOtherDirection(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseOtherDirectionContent(out, el); + parseOtherDirectionContent(out, el, context); return out; } void parseOtherDirectionContent(OtherDirection &out, pugi::xml_node el) +{ + parseOtherDirectionContent(out, el, ParseContext{}); +} + +void parseOtherDirectionContent(OtherDirection &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/OtherDirection.h b/src/private/mx/core/generated/OtherDirection.h index 78d9aea9a..d82ab4a6b 100644 --- a/src/private/mx/core/generated/OtherDirection.h +++ b/src/private/mx/core/generated/OtherDirection.h @@ -26,6 +26,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The other-direction type is used to define any direction symbols not yet in the MusicXML format. /// The smufl attribute can be used to specify a particular direction symbol, allowing application /// interoperability without requiring every SMuFL glyph to have a MusicXML element equivalent. Using @@ -86,8 +88,12 @@ class OtherDirection final OtherDirection parseOtherDirection(pugi::xml_node el); +OtherDirection parseOtherDirection(pugi::xml_node el, const ParseContext &context); + void parseOtherDirectionContent(OtherDirection &out, pugi::xml_node el); +void parseOtherDirectionContent(OtherDirection &out, pugi::xml_node el, const ParseContext &context); + void serializeOtherDirection(const OtherDirection &v, pugi::xml_node parent, const char *tag); void serializeOtherDirectionContent(const OtherDirection &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/OtherListening.cpp b/src/private/mx/core/generated/OtherListening.cpp index b48d53092..35be37198 100644 --- a/src/private/mx/core/generated/OtherListening.cpp +++ b/src/private/mx/core/generated/OtherListening.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/OtherListening.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -51,6 +52,11 @@ void OtherListening::setValue(std::string value) } OtherListening parseOtherListening(pugi::xml_node el) +{ + return parseOtherListening(el, ParseContext{}); +} + +OtherListening parseOtherListening(pugi::xml_node el, const ParseContext &context) { OtherListening out; bool seen_type = false; @@ -72,7 +78,7 @@ OtherListening parseOtherListening(pugi::xml_node el) } else if (aname == "time-only") { - out.setTimeOnly(TimeOnly::parse(a.value())); + out.setTimeOnly(parseValue(a.value(), context, el, "time-only")); } else { @@ -83,11 +89,16 @@ OtherListening parseOtherListening(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseOtherListeningContent(out, el); + parseOtherListeningContent(out, el, context); return out; } void parseOtherListeningContent(OtherListening &out, pugi::xml_node el) +{ + parseOtherListeningContent(out, el, ParseContext{}); +} + +void parseOtherListeningContent(OtherListening &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/OtherListening.h b/src/private/mx/core/generated/OtherListening.h index 844b1763e..a12dc0047 100644 --- a/src/private/mx/core/generated/OtherListening.h +++ b/src/private/mx/core/generated/OtherListening.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The other-listening type represents other types of listening control and interaction. The /// required type attribute indicates the type of listening to which the element content applies. The /// optional player and time-only attributes restrict the element to apply to a single player or set @@ -43,8 +45,12 @@ class OtherListening final OtherListening parseOtherListening(pugi::xml_node el); +OtherListening parseOtherListening(pugi::xml_node el, const ParseContext &context); + void parseOtherListeningContent(OtherListening &out, pugi::xml_node el); +void parseOtherListeningContent(OtherListening &out, pugi::xml_node el, const ParseContext &context); + void serializeOtherListening(const OtherListening &v, pugi::xml_node parent, const char *tag); void serializeOtherListeningContent(const OtherListening &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/OtherNotation.cpp b/src/private/mx/core/generated/OtherNotation.cpp index d34f7893b..1cdf7ca7b 100644 --- a/src/private/mx/core/generated/OtherNotation.cpp +++ b/src/private/mx/core/generated/OtherNotation.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/OtherNotation.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -171,6 +172,11 @@ void OtherNotation::setValue(std::string value) } OtherNotation parseOtherNotation(pugi::xml_node el) +{ + return parseOtherNotation(el, ParseContext{}); +} + +OtherNotation parseOtherNotation(pugi::xml_node el, const ParseContext &context) { OtherNotation out; bool seen_type = false; @@ -184,59 +190,59 @@ OtherNotation parseOtherNotation(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(StartStopSingle::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "number") { - out.setNumber(NumberLevel::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else if (aname == "print-object") { - out.setPrintObject(YesNo::parse(a.value())); + out.setPrintObject(parseValue(a.value(), context, el, "print-object")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else if (aname == "smufl") { - out.setSmufl(SmuflGlyphName::parse(a.value())); + out.setSmufl(parseValue(a.value(), context, el, "smufl")); } else if (aname == "id") { @@ -251,11 +257,16 @@ OtherNotation parseOtherNotation(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseOtherNotationContent(out, el); + parseOtherNotationContent(out, el, context); return out; } void parseOtherNotationContent(OtherNotation &out, pugi::xml_node el) +{ + parseOtherNotationContent(out, el, ParseContext{}); +} + +void parseOtherNotationContent(OtherNotation &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/OtherNotation.h b/src/private/mx/core/generated/OtherNotation.h index c7a5741c6..bdc47c9c9 100644 --- a/src/private/mx/core/generated/OtherNotation.h +++ b/src/private/mx/core/generated/OtherNotation.h @@ -27,6 +27,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The other-notation type is used to define any notations not yet in the MusicXML format. It /// handles notations where more specific extension elements such as other-dynamics and /// other-technical are not appropriate. The smufl attribute can be used to specify a particular @@ -91,8 +93,12 @@ class OtherNotation final OtherNotation parseOtherNotation(pugi::xml_node el); +OtherNotation parseOtherNotation(pugi::xml_node el, const ParseContext &context); + void parseOtherNotationContent(OtherNotation &out, pugi::xml_node el); +void parseOtherNotationContent(OtherNotation &out, pugi::xml_node el, const ParseContext &context); + void serializeOtherNotation(const OtherNotation &v, pugi::xml_node parent, const char *tag); void serializeOtherNotationContent(const OtherNotation &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/OtherPlacementText.cpp b/src/private/mx/core/generated/OtherPlacementText.cpp index 0297aaba0..31a898008 100644 --- a/src/private/mx/core/generated/OtherPlacementText.cpp +++ b/src/private/mx/core/generated/OtherPlacementText.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/OtherPlacementText.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -131,6 +132,11 @@ void OtherPlacementText::setValue(std::string value) } OtherPlacementText parseOtherPlacementText(pugi::xml_node el) +{ + return parseOtherPlacementText(el, ParseContext{}); +} + +OtherPlacementText parseOtherPlacementText(pugi::xml_node el, const ParseContext &context) { OtherPlacementText out; for (pugi::xml_attribute a : el.attributes()) @@ -142,58 +148,63 @@ OtherPlacementText parseOtherPlacementText(pugi::xml_node el) } if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else if (aname == "smufl") { - out.setSmufl(SmuflGlyphName::parse(a.value())); + out.setSmufl(parseValue(a.value(), context, el, "smufl")); } else { throwUnknownAttribute(el, a.name()); } } - parseOtherPlacementTextContent(out, el); + parseOtherPlacementTextContent(out, el, context); return out; } void parseOtherPlacementTextContent(OtherPlacementText &out, pugi::xml_node el) +{ + parseOtherPlacementTextContent(out, el, ParseContext{}); +} + +void parseOtherPlacementTextContent(OtherPlacementText &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/OtherPlacementText.h b/src/private/mx/core/generated/OtherPlacementText.h index 720356a8f..265b9a1c1 100644 --- a/src/private/mx/core/generated/OtherPlacementText.h +++ b/src/private/mx/core/generated/OtherPlacementText.h @@ -22,6 +22,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The other-placement-text type represents a text element with print-style, placement, and smufl /// attribute groups. This type is used by MusicXML notation extension elements to allow /// specification of specific SMuFL glyphs without needed to add every glyph as a MusicXML element. @@ -71,8 +73,12 @@ class OtherPlacementText final OtherPlacementText parseOtherPlacementText(pugi::xml_node el); +OtherPlacementText parseOtherPlacementText(pugi::xml_node el, const ParseContext &context); + void parseOtherPlacementTextContent(OtherPlacementText &out, pugi::xml_node el); +void parseOtherPlacementTextContent(OtherPlacementText &out, pugi::xml_node el, const ParseContext &context); + void serializeOtherPlacementText(const OtherPlacementText &v, pugi::xml_node parent, const char *tag); void serializeOtherPlacementTextContent(const OtherPlacementText &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/OtherPlay.cpp b/src/private/mx/core/generated/OtherPlay.cpp index 306130333..8a2c2f320 100644 --- a/src/private/mx/core/generated/OtherPlay.cpp +++ b/src/private/mx/core/generated/OtherPlay.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/OtherPlay.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void OtherPlay::setValue(std::string value) } OtherPlay parseOtherPlay(pugi::xml_node el) +{ + return parseOtherPlay(el, ParseContext{}); +} + +OtherPlay parseOtherPlay(pugi::xml_node el, const ParseContext &context) { OtherPlay out; bool seen_type = false; @@ -55,11 +61,16 @@ OtherPlay parseOtherPlay(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseOtherPlayContent(out, el); + parseOtherPlayContent(out, el, context); return out; } void parseOtherPlayContent(OtherPlay &out, pugi::xml_node el) +{ + parseOtherPlayContent(out, el, ParseContext{}); +} + +void parseOtherPlayContent(OtherPlay &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/OtherPlay.h b/src/private/mx/core/generated/OtherPlay.h index 4c2a6ebfc..574af0c71 100644 --- a/src/private/mx/core/generated/OtherPlay.h +++ b/src/private/mx/core/generated/OtherPlay.h @@ -13,6 +13,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The other-play element represents other types of playback. The required type attribute indicates /// the type of playback to which the element content applies. class OtherPlay final @@ -31,8 +33,12 @@ class OtherPlay final OtherPlay parseOtherPlay(pugi::xml_node el); +OtherPlay parseOtherPlay(pugi::xml_node el, const ParseContext &context); + void parseOtherPlayContent(OtherPlay &out, pugi::xml_node el); +void parseOtherPlayContent(OtherPlay &out, pugi::xml_node el, const ParseContext &context); + void serializeOtherPlay(const OtherPlay &v, pugi::xml_node parent, const char *tag); void serializeOtherPlayContent(const OtherPlay &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/OtherText.cpp b/src/private/mx/core/generated/OtherText.cpp index 2b75935fd..17076e729 100644 --- a/src/private/mx/core/generated/OtherText.cpp +++ b/src/private/mx/core/generated/OtherText.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/OtherText.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void OtherText::setValue(std::string value) } OtherText parseOtherText(pugi::xml_node el) +{ + return parseOtherText(el, ParseContext{}); +} + +OtherText parseOtherText(pugi::xml_node el, const ParseContext &context) { OtherText out; for (pugi::xml_attribute a : el.attributes()) @@ -42,18 +48,23 @@ OtherText parseOtherText(pugi::xml_node el) } if (aname == "smufl") { - out.setSmufl(SmuflGlyphName::parse(a.value())); + out.setSmufl(parseValue(a.value(), context, el, "smufl")); } else { throwUnknownAttribute(el, a.name()); } } - parseOtherTextContent(out, el); + parseOtherTextContent(out, el, context); return out; } void parseOtherTextContent(OtherText &out, pugi::xml_node el) +{ + parseOtherTextContent(out, el, ParseContext{}); +} + +void parseOtherTextContent(OtherText &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/OtherText.h b/src/private/mx/core/generated/OtherText.h index 464478e25..00f2e627d 100644 --- a/src/private/mx/core/generated/OtherText.h +++ b/src/private/mx/core/generated/OtherText.h @@ -15,6 +15,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The other-text type represents a text element with a smufl attribute group. This type is used by /// MusicXML direction extension elements to allow specification of specific SMuFL glyphs without /// needed to add every glyph as a MusicXML element. @@ -34,8 +36,12 @@ class OtherText final OtherText parseOtherText(pugi::xml_node el); +OtherText parseOtherText(pugi::xml_node el, const ParseContext &context); + void parseOtherTextContent(OtherText &out, pugi::xml_node el); +void parseOtherTextContent(OtherText &out, pugi::xml_node el, const ParseContext &context); + void serializeOtherText(const OtherText &v, pugi::xml_node parent, const char *tag); void serializeOtherTextContent(const OtherText &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/OverUnder.cpp b/src/private/mx/core/generated/OverUnder.cpp index 9f37cc03e..f846ab579 100644 --- a/src/private/mx/core/generated/OverUnder.cpp +++ b/src/private/mx/core/generated/OverUnder.cpp @@ -42,9 +42,15 @@ bool OverUnder::tryParse(std::string_view text, OverUnder &out) noexcept } OverUnder OverUnder::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +OverUnder OverUnder::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { OverUnder v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/OverUnder.h b/src/private/mx/core/generated/OverUnder.h index 4972fc1be..a66b80d52 100644 --- a/src/private/mx/core/generated/OverUnder.h +++ b/src/private/mx/core/generated/OverUnder.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -41,6 +43,9 @@ class OverUnder final /// (the import leniency policy; never produces an invalid value). static OverUnder parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static OverUnder parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const OverUnder &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/PageLayout.cpp b/src/private/mx/core/generated/PageLayout.cpp index d62f99c8a..1637d6cce 100644 --- a/src/private/mx/core/generated/PageLayout.cpp +++ b/src/private/mx/core/generated/PageLayout.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/PageLayout.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,6 +42,11 @@ void PageLayout::clearPageMargins() noexcept } PageLayout parsePageLayout(pugi::xml_node el) +{ + return parsePageLayout(el, ParseContext{}); +} + +PageLayout parsePageLayout(pugi::xml_node el, const ParseContext &context) { PageLayout out; for (pugi::xml_attribute a : el.attributes()) @@ -52,20 +58,25 @@ PageLayout parsePageLayout(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parsePageLayoutContent(out, el); + parsePageLayoutContent(out, el, context); return out; } void parsePageLayoutContent(PageLayout &out, pugi::xml_node el) +{ + parsePageLayoutContent(out, el, ParseContext{}); +} + +void parsePageLayoutContent(PageLayout &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "page-height"))) { - out.setGroup(parsePageLayoutGroup(el, cursor)); + out.setGroup(parsePageLayoutGroup(el, cursor, context)); } while (cursorIs(cursor, "page-margins")) { - if (!out.addPageMargins(parsePageMargins(cursor))) + if (!out.addPageMargins(parsePageMargins(cursor, context))) { throwTooManyElements(cursor); } diff --git a/src/private/mx/core/generated/PageLayout.h b/src/private/mx/core/generated/PageLayout.h index 35e029982..2d669c0a3 100644 --- a/src/private/mx/core/generated/PageLayout.h +++ b/src/private/mx/core/generated/PageLayout.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Page layout can be defined both in score-wide defaults and in the print element. Page margins are /// specified either for both even and odd pages, or via separate odd and even page number values. /// The type is not needed when used as part of a print element. If omitted when used in the defaults @@ -49,8 +51,12 @@ class PageLayout final PageLayout parsePageLayout(pugi::xml_node el); +PageLayout parsePageLayout(pugi::xml_node el, const ParseContext &context); + void parsePageLayoutContent(PageLayout &out, pugi::xml_node el); +void parsePageLayoutContent(PageLayout &out, pugi::xml_node el, const ParseContext &context); + void serializePageLayout(const PageLayout &v, pugi::xml_node parent, const char *tag); void serializePageLayoutContent(const PageLayout &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/PageLayoutGroup.cpp b/src/private/mx/core/generated/PageLayoutGroup.cpp index 862dfdb1b..d9ae8c776 100644 --- a/src/private/mx/core/generated/PageLayoutGroup.cpp +++ b/src/private/mx/core/generated/PageLayoutGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/PageLayoutGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,11 +32,16 @@ void PageLayoutGroup::setPageWidth(Tenths value) } PageLayoutGroup parsePageLayoutGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parsePageLayoutGroup(el, cursor, ParseContext{}); +} + +PageLayoutGroup parsePageLayoutGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { PageLayoutGroup out; if (cursorIs(cursor, "page-height")) { - out.setPageHeight(Tenths::parse(childText(cursor))); + out.setPageHeight(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -44,7 +50,7 @@ PageLayoutGroup parsePageLayoutGroup(pugi::xml_node el, pugi::xml_node &cursor) } if (cursorIs(cursor, "page-width")) { - out.setPageWidth(Tenths::parse(childText(cursor))); + out.setPageWidth(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else diff --git a/src/private/mx/core/generated/PageLayoutGroup.h b/src/private/mx/core/generated/PageLayoutGroup.h index e2da2d30b..3c8438325 100644 --- a/src/private/mx/core/generated/PageLayoutGroup.h +++ b/src/private/mx/core/generated/PageLayoutGroup.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A shared content group (synthesized from an anonymous /// particle of the schema): transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -38,6 +40,8 @@ class PageLayoutGroup final /// is the enclosing element, for error paths. PageLayoutGroup parsePageLayoutGroup(pugi::xml_node el, pugi::xml_node &cursor); +PageLayoutGroup parsePageLayoutGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializePageLayoutGroup(const PageLayoutGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/PageMargins.cpp b/src/private/mx/core/generated/PageMargins.cpp index 64671b7fb..7f13b4905 100644 --- a/src/private/mx/core/generated/PageMargins.cpp +++ b/src/private/mx/core/generated/PageMargins.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/PageMargins.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void PageMargins::setAllMargins(AllMarginsGroup value) } PageMargins parsePageMargins(pugi::xml_node el) +{ + return parsePageMargins(el, ParseContext{}); +} + +PageMargins parsePageMargins(pugi::xml_node el, const ParseContext &context) { PageMargins out; for (pugi::xml_attribute a : el.attributes()) @@ -42,23 +48,28 @@ PageMargins parsePageMargins(pugi::xml_node el) } if (aname == "type") { - out.setType(MarginType::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else { throwUnknownAttribute(el, a.name()); } } - parsePageMarginsContent(out, el); + parsePageMarginsContent(out, el, context); return out; } void parsePageMarginsContent(PageMargins &out, pugi::xml_node el) +{ + parsePageMarginsContent(out, el, ParseContext{}); +} + +void parsePageMarginsContent(PageMargins &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "left-margin"))) { - out.setAllMargins(parseAllMarginsGroup(el, cursor)); + out.setAllMargins(parseAllMarginsGroup(el, cursor, context)); } else { diff --git a/src/private/mx/core/generated/PageMargins.h b/src/private/mx/core/generated/PageMargins.h index 86cdb5493..e1417f17d 100644 --- a/src/private/mx/core/generated/PageMargins.h +++ b/src/private/mx/core/generated/PageMargins.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Page margins are specified either for both even and odd pages, or via separate odd and even page /// number values. The type attribute is not needed when used as part of a print element. If omitted /// when the page-margins type is used in the defaults element, "both" is the default value. @@ -39,8 +41,12 @@ class PageMargins final PageMargins parsePageMargins(pugi::xml_node el); +PageMargins parsePageMargins(pugi::xml_node el, const ParseContext &context); + void parsePageMarginsContent(PageMargins &out, pugi::xml_node el); +void parsePageMarginsContent(PageMargins &out, pugi::xml_node el, const ParseContext &context); + void serializePageMargins(const PageMargins &v, pugi::xml_node parent, const char *tag); void serializePageMarginsContent(const PageMargins &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/PartClef.cpp b/src/private/mx/core/generated/PartClef.cpp index 9d0632cac..022532edd 100644 --- a/src/private/mx/core/generated/PartClef.cpp +++ b/src/private/mx/core/generated/PartClef.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/PartClef.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -21,6 +22,11 @@ void PartClef::setClef(ClefGroup value) } PartClef parsePartClef(pugi::xml_node el) +{ + return parsePartClef(el, ParseContext{}); +} + +PartClef parsePartClef(pugi::xml_node el, const ParseContext &context) { PartClef out; for (pugi::xml_attribute a : el.attributes()) @@ -32,16 +38,21 @@ PartClef parsePartClef(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parsePartClefContent(out, el); + parsePartClefContent(out, el, context); return out; } void parsePartClefContent(PartClef &out, pugi::xml_node el) +{ + parsePartClefContent(out, el, ParseContext{}); +} + +void parsePartClefContent(PartClef &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "sign"))) { - out.setClef(parseClefGroup(el, cursor)); + out.setClef(parseClefGroup(el, cursor, context)); } else { diff --git a/src/private/mx/core/generated/PartClef.h b/src/private/mx/core/generated/PartClef.h index 06b10ddd1..6503eefc4 100644 --- a/src/private/mx/core/generated/PartClef.h +++ b/src/private/mx/core/generated/PartClef.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The child elements of the part-clef type have the same meaning as for the clef type. However that /// meaning applies to a transposed part created from the existing score file. /// Content fields mirror the schema grammar in declaration order; the @@ -34,8 +36,12 @@ class PartClef final PartClef parsePartClef(pugi::xml_node el); +PartClef parsePartClef(pugi::xml_node el, const ParseContext &context); + void parsePartClefContent(PartClef &out, pugi::xml_node el); +void parsePartClefContent(PartClef &out, pugi::xml_node el, const ParseContext &context); + void serializePartClef(const PartClef &v, pugi::xml_node parent, const char *tag); void serializePartClefContent(const PartClef &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/PartGroup.cpp b/src/private/mx/core/generated/PartGroup.cpp index 3e2bb9428..26c6df2fe 100644 --- a/src/private/mx/core/generated/PartGroup.cpp +++ b/src/private/mx/core/generated/PartGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/PartGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -111,6 +112,11 @@ void PartGroup::setEditorial(EditorialGroup value) } PartGroup parsePartGroup(pugi::xml_node el) +{ + return parsePartGroup(el, ParseContext{}); +} + +PartGroup parsePartGroup(pugi::xml_node el, const ParseContext &context) { PartGroup out; bool seen_type = false; @@ -124,7 +130,7 @@ PartGroup parsePartGroup(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(StartStop::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "number") { @@ -139,52 +145,57 @@ PartGroup parsePartGroup(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parsePartGroupContent(out, el); + parsePartGroupContent(out, el, context); return out; } void parsePartGroupContent(PartGroup &out, pugi::xml_node el) +{ + parsePartGroupContent(out, el, ParseContext{}); +} + +void parsePartGroupContent(PartGroup &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "group-name")) { - out.setGroupName(parseGroupName(cursor)); + out.setGroupName(parseGroupName(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "group-name-display")) { - out.setGroupNameDisplay(parseNameDisplay(cursor)); + out.setGroupNameDisplay(parseNameDisplay(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "group-abbreviation")) { - out.setGroupAbbreviation(parseGroupName(cursor)); + out.setGroupAbbreviation(parseGroupName(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "group-abbreviation-display")) { - out.setGroupAbbreviationDisplay(parseNameDisplay(cursor)); + out.setGroupAbbreviationDisplay(parseNameDisplay(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "group-symbol")) { - out.setGroupSymbol(parseGroupSymbol(cursor)); + out.setGroupSymbol(parseGroupSymbol(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "group-barline")) { - out.setGroupBarline(parseGroupBarline(cursor)); + out.setGroupBarline(parseGroupBarline(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "group-time")) { - parseEmpty(cursor); + parseEmpty(cursor, context); out.setGroupTime(true); cursor = nextElement(cursor); } if (cursor && (cursorIs(cursor, "footnote") || cursorIs(cursor, "level"))) { - out.setEditorial(parseEditorialGroup(el, cursor)); + out.setEditorial(parseEditorialGroup(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/PartGroup.h b/src/private/mx/core/generated/PartGroup.h index 6d7515265..9b729f10c 100644 --- a/src/private/mx/core/generated/PartGroup.h +++ b/src/private/mx/core/generated/PartGroup.h @@ -23,6 +23,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The part-group element indicates groupings of parts in the score, usually indicated by braces and /// brackets. Braces that are used for multi-staff parts should be defined in the attributes element /// for that part. The part-group start element appears before the first score-part in the group. The @@ -75,8 +77,12 @@ class PartGroup final PartGroup parsePartGroup(pugi::xml_node el); +PartGroup parsePartGroup(pugi::xml_node el, const ParseContext &context); + void parsePartGroupContent(PartGroup &out, pugi::xml_node el); +void parsePartGroupContent(PartGroup &out, pugi::xml_node el, const ParseContext &context); + void serializePartGroup(const PartGroup &v, pugi::xml_node parent, const char *tag); void serializePartGroupContent(const PartGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/PartLink.cpp b/src/private/mx/core/generated/PartLink.cpp index b93d41033..6c733a3d4 100644 --- a/src/private/mx/core/generated/PartLink.cpp +++ b/src/private/mx/core/generated/PartLink.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/PartLink.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -101,6 +102,11 @@ void PartLink::setGroupLink(std::vector value) } PartLink parsePartLink(pugi::xml_node el) +{ + return parsePartLink(el, ParseContext{}); +} + +PartLink parsePartLink(pugi::xml_node el, const ParseContext &context) { PartLink out; bool seen_xlinkHref = false; @@ -145,16 +151,21 @@ PartLink parsePartLink(pugi::xml_node el) { throwMissingAttribute(el, "xlink:href"); } - parsePartLinkContent(out, el); + parsePartLinkContent(out, el, context); return out; } void parsePartLinkContent(PartLink &out, pugi::xml_node el) +{ + parsePartLinkContent(out, el, ParseContext{}); +} + +void parsePartLinkContent(PartLink &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); while (cursorIs(cursor, "instrument-link")) { - out.addInstrumentLink(parseInstrumentLink(cursor)); + out.addInstrumentLink(parseInstrumentLink(cursor, context)); cursor = nextElement(cursor); } while (cursorIs(cursor, "group-link")) diff --git a/src/private/mx/core/generated/PartLink.h b/src/private/mx/core/generated/PartLink.h index 05a81fdd4..a864a915b 100644 --- a/src/private/mx/core/generated/PartLink.h +++ b/src/private/mx/core/generated/PartLink.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The part-link type allows MusicXML data for both score and parts to be contained within a single /// compressed MusicXML file. It links a score-part from a score document to MusicXML documents that /// contain parts data. In the case of a single compressed MusicXML file, the link href values are @@ -59,8 +61,12 @@ class PartLink final PartLink parsePartLink(pugi::xml_node el); +PartLink parsePartLink(pugi::xml_node el, const ParseContext &context); + void parsePartLinkContent(PartLink &out, pugi::xml_node el); +void parsePartLinkContent(PartLink &out, pugi::xml_node el, const ParseContext &context); + void serializePartLink(const PartLink &v, pugi::xml_node parent, const char *tag); void serializePartLinkContent(const PartLink &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/PartList.cpp b/src/private/mx/core/generated/PartList.cpp index 3af0b1f82..48f14320d 100644 --- a/src/private/mx/core/generated/PartList.cpp +++ b/src/private/mx/core/generated/PartList.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/PartList.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -51,6 +52,11 @@ void PartList::setChoice(std::vector value) } PartList parsePartList(pugi::xml_node el) +{ + return parsePartList(el, ParseContext{}); +} + +PartList parsePartList(pugi::xml_node el, const ParseContext &context) { PartList out; for (pugi::xml_attribute a : el.attributes()) @@ -62,21 +68,26 @@ PartList parsePartList(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parsePartListContent(out, el); + parsePartListContent(out, el, context); return out; } void parsePartListContent(PartList &out, pugi::xml_node el) +{ + parsePartListContent(out, el, ParseContext{}); +} + +void parsePartListContent(PartList &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); while (cursorIs(cursor, "part-group")) { - out.addPartGroup(parsePartGroup(cursor)); + out.addPartGroup(parsePartGroup(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "score-part")) { - out.setScorePart(parseScorePart(cursor)); + out.setScorePart(parseScorePart(cursor, context)); cursor = nextElement(cursor); } else @@ -85,7 +96,7 @@ void parsePartListContent(PartList &out, pugi::xml_node el) } while (cursor && (cursorIs(cursor, "part-group") || cursorIs(cursor, "score-part"))) { - out.addChoice(parsePartListChoice(el, cursor)); + out.addChoice(parsePartListChoice(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/PartList.h b/src/private/mx/core/generated/PartList.h index 79e77f976..360c58bc4 100644 --- a/src/private/mx/core/generated/PartList.h +++ b/src/private/mx/core/generated/PartList.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The part-list identifies the different musical parts in this document. Each part has an ID that /// is used later within the musical data. Since parts may be encoded separately and combined later, /// identification elements are present at both the score and score-part levels. There must be at @@ -48,8 +50,12 @@ class PartList final PartList parsePartList(pugi::xml_node el); +PartList parsePartList(pugi::xml_node el, const ParseContext &context); + void parsePartListContent(PartList &out, pugi::xml_node el); +void parsePartListContent(PartList &out, pugi::xml_node el, const ParseContext &context); + void serializePartList(const PartList &v, pugi::xml_node parent, const char *tag); void serializePartListContent(const PartList &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/PartListChoice.cpp b/src/private/mx/core/generated/PartListChoice.cpp index 6d17c7829..fe25275b2 100644 --- a/src/private/mx/core/generated/PartListChoice.cpp +++ b/src/private/mx/core/generated/PartListChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/PartListChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -26,16 +27,21 @@ PartListChoice PartListChoice::scorePart(ScorePart value) } PartListChoice parsePartListChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parsePartListChoice(el, cursor, ParseContext{}); +} + +PartListChoice parsePartListChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "part-group"))) { - PartGroup value = parsePartGroup(cursor); + PartGroup value = parsePartGroup(cursor, context); cursor = nextElement(cursor); return PartListChoice::partGroup(std::move(value)); } if (cursor && (cursorIs(cursor, "score-part"))) { - ScorePart value = parseScorePart(cursor); + ScorePart value = parseScorePart(cursor, context); cursor = nextElement(cursor); return PartListChoice::scorePart(std::move(value)); } diff --git a/src/private/mx/core/generated/PartListChoice.h b/src/private/mx/core/generated/PartListChoice.h index d11ecf977..d29dd0e71 100644 --- a/src/private/mx/core/generated/PartListChoice.h +++ b/src/private/mx/core/generated/PartListChoice.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -82,6 +84,8 @@ class PartListChoice final /// the enclosing element, for error paths. PartListChoice parsePartListChoice(pugi::xml_node el, pugi::xml_node &cursor); +PartListChoice parsePartListChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializePartListChoice(const PartListChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/PartName.cpp b/src/private/mx/core/generated/PartName.cpp index c2832bf2e..8e5696195 100644 --- a/src/private/mx/core/generated/PartName.cpp +++ b/src/private/mx/core/generated/PartName.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/PartName.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -131,6 +132,11 @@ void PartName::setValue(std::string value) } PartName parsePartName(pugi::xml_node el) +{ + return parsePartName(el, ParseContext{}); +} + +PartName parsePartName(pugi::xml_node el, const ParseContext &context) { PartName out; for (pugi::xml_attribute a : el.attributes()) @@ -142,58 +148,63 @@ PartName parsePartName(pugi::xml_node el) } if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "print-object") { - out.setPrintObject(YesNo::parse(a.value())); + out.setPrintObject(parseValue(a.value(), context, el, "print-object")); } else if (aname == "justify") { - out.setJustify(LeftCenterRight::parse(a.value())); + out.setJustify(parseValue(a.value(), context, el, "justify")); } else { throwUnknownAttribute(el, a.name()); } } - parsePartNameContent(out, el); + parsePartNameContent(out, el, context); return out; } void parsePartNameContent(PartName &out, pugi::xml_node el) +{ + parsePartNameContent(out, el, ParseContext{}); +} + +void parsePartNameContent(PartName &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/PartName.h b/src/private/mx/core/generated/PartName.h index 6eaca6824..ad64eab2c 100644 --- a/src/private/mx/core/generated/PartName.h +++ b/src/private/mx/core/generated/PartName.h @@ -22,6 +22,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The part-name type describes the name or abbreviation of a score-part element. Formatting /// attributes for the part-name element are deprecated in Version 2.0 in favor of the new /// part-name-display and part-abbreviation-display elements. @@ -71,8 +73,12 @@ class PartName final PartName parsePartName(pugi::xml_node el); +PartName parsePartName(pugi::xml_node el, const ParseContext &context); + void parsePartNameContent(PartName &out, pugi::xml_node el); +void parsePartNameContent(PartName &out, pugi::xml_node el, const ParseContext &context); + void serializePartName(const PartName &v, pugi::xml_node parent, const char *tag); void serializePartNameContent(const PartName &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/PartSymbol.cpp b/src/private/mx/core/generated/PartSymbol.cpp index e0940d609..db44f742b 100644 --- a/src/private/mx/core/generated/PartSymbol.cpp +++ b/src/private/mx/core/generated/PartSymbol.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/PartSymbol.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -91,6 +92,11 @@ void PartSymbol::setValue(GroupSymbolValue value) } PartSymbol parsePartSymbol(pugi::xml_node el) +{ + return parsePartSymbol(el, ParseContext{}); +} + +PartSymbol parsePartSymbol(pugi::xml_node el, const ParseContext &context) { PartSymbol out; for (pugi::xml_attribute a : el.attributes()) @@ -102,44 +108,49 @@ PartSymbol parsePartSymbol(pugi::xml_node el) } if (aname == "top-staff") { - out.setTopStaff(StaffNumber::parse(a.value())); + out.setTopStaff(parseValue(a.value(), context, el, "top-staff")); } else if (aname == "bottom-staff") { - out.setBottomStaff(StaffNumber::parse(a.value())); + out.setBottomStaff(parseValue(a.value(), context, el, "bottom-staff")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else { throwUnknownAttribute(el, a.name()); } } - parsePartSymbolContent(out, el); + parsePartSymbolContent(out, el, context); return out; } void parsePartSymbolContent(PartSymbol &out, pugi::xml_node el) { - out.setValue(GroupSymbolValue::parse(childText(el))); + parsePartSymbolContent(out, el, ParseContext{}); +} + +void parsePartSymbolContent(PartSymbol &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/PartSymbol.h b/src/private/mx/core/generated/PartSymbol.h index e6bdf48b2..8f967d43e 100644 --- a/src/private/mx/core/generated/PartSymbol.h +++ b/src/private/mx/core/generated/PartSymbol.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The part-symbol type indicates how a symbol for a multi-staff part is indicated in the score; /// brace is the default value. The top-staff and bottom-staff attributes are used when the brace /// does not extend across the entire part. For example, in a 3-staff organ part, the top-staff will @@ -59,8 +61,12 @@ class PartSymbol final PartSymbol parsePartSymbol(pugi::xml_node el); +PartSymbol parsePartSymbol(pugi::xml_node el, const ParseContext &context); + void parsePartSymbolContent(PartSymbol &out, pugi::xml_node el); +void parsePartSymbolContent(PartSymbol &out, pugi::xml_node el, const ParseContext &context); + void serializePartSymbol(const PartSymbol &v, pugi::xml_node parent, const char *tag); void serializePartSymbolContent(const PartSymbol &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/PartTranspose.cpp b/src/private/mx/core/generated/PartTranspose.cpp index e3e8733de..ac3250d98 100644 --- a/src/private/mx/core/generated/PartTranspose.cpp +++ b/src/private/mx/core/generated/PartTranspose.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/PartTranspose.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -21,6 +22,11 @@ void PartTranspose::setTranspose(TransposeGroup value) } PartTranspose parsePartTranspose(pugi::xml_node el) +{ + return parsePartTranspose(el, ParseContext{}); +} + +PartTranspose parsePartTranspose(pugi::xml_node el, const ParseContext &context) { PartTranspose out; for (pugi::xml_attribute a : el.attributes()) @@ -32,16 +38,21 @@ PartTranspose parsePartTranspose(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parsePartTransposeContent(out, el); + parsePartTransposeContent(out, el, context); return out; } void parsePartTransposeContent(PartTranspose &out, pugi::xml_node el) +{ + parsePartTransposeContent(out, el, ParseContext{}); +} + +void parsePartTransposeContent(PartTranspose &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "diatonic") || cursorIs(cursor, "chromatic"))) { - out.setTranspose(parseTransposeGroup(el, cursor)); + out.setTranspose(parseTransposeGroup(el, cursor, context)); } else { diff --git a/src/private/mx/core/generated/PartTranspose.h b/src/private/mx/core/generated/PartTranspose.h index 9d6feb989..06efe6354 100644 --- a/src/private/mx/core/generated/PartTranspose.h +++ b/src/private/mx/core/generated/PartTranspose.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The child elements of the part-transpose type have the same meaning as for the transpose type. /// However that meaning applies to a transposed part created from the existing score file. /// Content fields mirror the schema grammar in declaration order; the @@ -34,8 +36,12 @@ class PartTranspose final PartTranspose parsePartTranspose(pugi::xml_node el); +PartTranspose parsePartTranspose(pugi::xml_node el, const ParseContext &context); + void parsePartTransposeContent(PartTranspose &out, pugi::xml_node el); +void parsePartTransposeContent(PartTranspose &out, pugi::xml_node el, const ParseContext &context); + void serializePartTranspose(const PartTranspose &v, pugi::xml_node parent, const char *tag); void serializePartTransposeContent(const PartTranspose &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/PartwiseMeasure.cpp b/src/private/mx/core/generated/PartwiseMeasure.cpp index 97ed0a17b..b97160e18 100644 --- a/src/private/mx/core/generated/PartwiseMeasure.cpp +++ b/src/private/mx/core/generated/PartwiseMeasure.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/PartwiseMeasure.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -86,6 +87,11 @@ void PartwiseMeasure::setMusicData(std::vector value) } PartwiseMeasure parsePartwiseMeasure(pugi::xml_node el) +{ + return parsePartwiseMeasure(el, ParseContext{}); +} + +PartwiseMeasure parsePartwiseMeasure(pugi::xml_node el, const ParseContext &context) { PartwiseMeasure out; bool seen_number = false; @@ -103,19 +109,19 @@ PartwiseMeasure parsePartwiseMeasure(pugi::xml_node el) } else if (aname == "text") { - out.setText(MeasureText::parse(a.value())); + out.setText(parseValue(a.value(), context, el, "text")); } else if (aname == "implicit") { - out.setImplicit(YesNo::parse(a.value())); + out.setImplicit(parseValue(a.value(), context, el, "implicit")); } else if (aname == "non-controlling") { - out.setNonControlling(YesNo::parse(a.value())); + out.setNonControlling(parseValue(a.value(), context, el, "non-controlling")); } else if (aname == "width") { - out.setWidth(Tenths::parse(a.value())); + out.setWidth(parseValue(a.value(), context, el, "width")); } else if (aname == "id") { @@ -130,11 +136,16 @@ PartwiseMeasure parsePartwiseMeasure(pugi::xml_node el) { throwMissingAttribute(el, "number"); } - parsePartwiseMeasureContent(out, el); + parsePartwiseMeasureContent(out, el, context); return out; } void parsePartwiseMeasureContent(PartwiseMeasure &out, pugi::xml_node el) +{ + parsePartwiseMeasureContent(out, el, ParseContext{}); +} + +void parsePartwiseMeasureContent(PartwiseMeasure &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); while (cursor && (cursorIs(cursor, "note") || cursorIs(cursor, "backup") || cursorIs(cursor, "forward") || @@ -143,7 +154,7 @@ void parsePartwiseMeasureContent(PartwiseMeasure &out, pugi::xml_node el) cursorIs(cursor, "listening") || cursorIs(cursor, "barline") || cursorIs(cursor, "grouping") || cursorIs(cursor, "link") || cursorIs(cursor, "bookmark"))) { - out.addMusicData(parseMusicDataChoice(el, cursor)); + out.addMusicData(parseMusicDataChoice(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/PartwiseMeasure.h b/src/private/mx/core/generated/PartwiseMeasure.h index 6868a76de..b81f83b2a 100644 --- a/src/private/mx/core/generated/PartwiseMeasure.h +++ b/src/private/mx/core/generated/PartwiseMeasure.h @@ -22,6 +22,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Content fields mirror the schema grammar in declaration order; the /// serializer walks them, so a wrong order is unrepresentable (plan ยง2.3). class PartwiseMeasure final @@ -56,8 +58,12 @@ class PartwiseMeasure final PartwiseMeasure parsePartwiseMeasure(pugi::xml_node el); +PartwiseMeasure parsePartwiseMeasure(pugi::xml_node el, const ParseContext &context); + void parsePartwiseMeasureContent(PartwiseMeasure &out, pugi::xml_node el); +void parsePartwiseMeasureContent(PartwiseMeasure &out, pugi::xml_node el, const ParseContext &context); + void serializePartwiseMeasure(const PartwiseMeasure &v, pugi::xml_node parent, const char *tag); void serializePartwiseMeasureContent(const PartwiseMeasure &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/PartwisePart.cpp b/src/private/mx/core/generated/PartwisePart.cpp index 6bf7988e3..237104200 100644 --- a/src/private/mx/core/generated/PartwisePart.cpp +++ b/src/private/mx/core/generated/PartwisePart.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/PartwisePart.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -36,6 +37,11 @@ void PartwisePart::setMeasure(OneOrMore value) } PartwisePart parsePartwisePart(pugi::xml_node el) +{ + return parsePartwisePart(el, ParseContext{}); +} + +PartwisePart parsePartwisePart(pugi::xml_node el, const ParseContext &context) { PartwisePart out; bool seen_id = false; @@ -60,22 +66,27 @@ PartwisePart parsePartwisePart(pugi::xml_node el) { throwMissingAttribute(el, "id"); } - parsePartwisePartContent(out, el); + parsePartwisePartContent(out, el, context); return out; } void parsePartwisePartContent(PartwisePart &out, pugi::xml_node el) +{ + parsePartwisePartContent(out, el, ParseContext{}); +} + +void parsePartwisePartContent(PartwisePart &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (!cursorIs(cursor, "measure")) { throwMissingOrMisplaced(el, cursor, "measure"); } - out.setMeasure(OneOrMore{parsePartwiseMeasure(cursor)}); + out.setMeasure(OneOrMore{parsePartwiseMeasure(cursor, context)}); cursor = nextElement(cursor); while (cursorIs(cursor, "measure")) { - out.addMeasure(parsePartwiseMeasure(cursor)); + out.addMeasure(parsePartwiseMeasure(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/PartwisePart.h b/src/private/mx/core/generated/PartwisePart.h index c7f1fcb83..6ebb27b7d 100644 --- a/src/private/mx/core/generated/PartwisePart.h +++ b/src/private/mx/core/generated/PartwisePart.h @@ -20,6 +20,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Content fields mirror the schema grammar in declaration order; the /// serializer walks them, so a wrong order is unrepresentable (plan ยง2.3). class PartwisePart final @@ -39,8 +41,12 @@ class PartwisePart final PartwisePart parsePartwisePart(pugi::xml_node el); +PartwisePart parsePartwisePart(pugi::xml_node el, const ParseContext &context); + void parsePartwisePartContent(PartwisePart &out, pugi::xml_node el); +void parsePartwisePartContent(PartwisePart &out, pugi::xml_node el, const ParseContext &context); + void serializePartwisePart(const PartwisePart &v, pugi::xml_node parent, const char *tag); void serializePartwisePartContent(const PartwisePart &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Pedal.cpp b/src/private/mx/core/generated/Pedal.cpp index 2b624a0f1..24632fa81 100644 --- a/src/private/mx/core/generated/Pedal.cpp +++ b/src/private/mx/core/generated/Pedal.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Pedal.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -181,6 +182,11 @@ void Pedal::setID(std::optional value) } Pedal parsePedal(pugi::xml_node el) +{ + return parsePedal(el, ParseContext{}); +} + +Pedal parsePedal(pugi::xml_node el, const ParseContext &context) { Pedal out; bool seen_type = false; @@ -194,67 +200,67 @@ Pedal parsePedal(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(PedalType::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "number") { - out.setNumber(NumberLevel::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else if (aname == "line") { - out.setLine(YesNo::parse(a.value())); + out.setLine(parseValue(a.value(), context, el, "line")); } else if (aname == "sign") { - out.setSign(YesNo::parse(a.value())); + out.setSign(parseValue(a.value(), context, el, "sign")); } else if (aname == "abbreviated") { - out.setAbbreviated(YesNo::parse(a.value())); + out.setAbbreviated(parseValue(a.value(), context, el, "abbreviated")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "halign") { - out.setHalign(LeftCenterRight::parse(a.value())); + out.setHalign(parseValue(a.value(), context, el, "halign")); } else if (aname == "valign") { - out.setValign(Valign::parse(a.value())); + out.setValign(parseValue(a.value(), context, el, "valign")); } else if (aname == "id") { @@ -269,13 +275,19 @@ Pedal parsePedal(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parsePedalContent(out, el); + parsePedalContent(out, el, context); return out; } void parsePedalContent(Pedal &out, pugi::xml_node el) +{ + parsePedalContent(out, el, ParseContext{}); +} + +void parsePedalContent(Pedal &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Pedal.h b/src/private/mx/core/generated/Pedal.h index 82ec81877..9d813aeae 100644 --- a/src/private/mx/core/generated/Pedal.h +++ b/src/private/mx/core/generated/Pedal.h @@ -27,6 +27,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The pedal type represents piano pedal marks, including damper and sostenuto pedal marks. The line /// attribute is yes if pedal lines are used. The sign attribute is yes if Ped, Sost, and * signs are /// used. For compatibility with older versions, the sign attribute is yes by default if the line @@ -96,8 +98,12 @@ class Pedal final Pedal parsePedal(pugi::xml_node el); +Pedal parsePedal(pugi::xml_node el, const ParseContext &context); + void parsePedalContent(Pedal &out, pugi::xml_node el); +void parsePedalContent(Pedal &out, pugi::xml_node el, const ParseContext &context); + void serializePedal(const Pedal &v, pugi::xml_node parent, const char *tag); void serializePedalContent(const Pedal &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/PedalTuning.cpp b/src/private/mx/core/generated/PedalTuning.cpp index 4ed2fb7d5..c228e8294 100644 --- a/src/private/mx/core/generated/PedalTuning.cpp +++ b/src/private/mx/core/generated/PedalTuning.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/PedalTuning.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void PedalTuning::setPedalAlter(Semitones value) } PedalTuning parsePedalTuning(pugi::xml_node el) +{ + return parsePedalTuning(el, ParseContext{}); +} + +PedalTuning parsePedalTuning(pugi::xml_node el, const ParseContext &context) { PedalTuning out; for (pugi::xml_attribute a : el.attributes()) @@ -42,16 +48,21 @@ PedalTuning parsePedalTuning(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parsePedalTuningContent(out, el); + parsePedalTuningContent(out, el, context); return out; } void parsePedalTuningContent(PedalTuning &out, pugi::xml_node el) +{ + parsePedalTuningContent(out, el, ParseContext{}); +} + +void parsePedalTuningContent(PedalTuning &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "pedal-step")) { - out.setPedalStep(Step::parse(childText(cursor))); + out.setPedalStep(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -60,7 +71,7 @@ void parsePedalTuningContent(PedalTuning &out, pugi::xml_node el) } if (cursorIs(cursor, "pedal-alter")) { - out.setPedalAlter(Semitones::parse(childText(cursor))); + out.setPedalAlter(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else diff --git a/src/private/mx/core/generated/PedalTuning.h b/src/private/mx/core/generated/PedalTuning.h index 91e3cdec9..079c10b59 100644 --- a/src/private/mx/core/generated/PedalTuning.h +++ b/src/private/mx/core/generated/PedalTuning.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The pedal-tuning type specifies the tuning of a single harp pedal. /// Content fields mirror the schema grammar in declaration order; the /// serializer walks them, so a wrong order is unrepresentable (plan ยง2.3). @@ -37,8 +39,12 @@ class PedalTuning final PedalTuning parsePedalTuning(pugi::xml_node el); +PedalTuning parsePedalTuning(pugi::xml_node el, const ParseContext &context); + void parsePedalTuningContent(PedalTuning &out, pugi::xml_node el); +void parsePedalTuningContent(PedalTuning &out, pugi::xml_node el, const ParseContext &context); + void serializePedalTuning(const PedalTuning &v, pugi::xml_node parent, const char *tag); void serializePedalTuningContent(const PedalTuning &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/PedalType.cpp b/src/private/mx/core/generated/PedalType.cpp index 00a5b5823..a7731c07b 100644 --- a/src/private/mx/core/generated/PedalType.cpp +++ b/src/private/mx/core/generated/PedalType.cpp @@ -66,9 +66,15 @@ bool PedalType::tryParse(std::string_view text, PedalType &out) noexcept } PedalType PedalType::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +PedalType PedalType::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { PedalType v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/PedalType.h b/src/private/mx/core/generated/PedalType.h index 180c910b4..1259d2e68 100644 --- a/src/private/mx/core/generated/PedalType.h +++ b/src/private/mx/core/generated/PedalType.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -61,6 +63,9 @@ class PedalType final /// (the import leniency policy; never produces an invalid value). static PedalType parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static PedalType parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const PedalType &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/PerMinute.cpp b/src/private/mx/core/generated/PerMinute.cpp index 09fc93e99..fd0249e3d 100644 --- a/src/private/mx/core/generated/PerMinute.cpp +++ b/src/private/mx/core/generated/PerMinute.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/PerMinute.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -61,6 +62,11 @@ void PerMinute::setValue(std::string value) } PerMinute parsePerMinute(pugi::xml_node el) +{ + return parsePerMinute(el, ParseContext{}); +} + +PerMinute parsePerMinute(pugi::xml_node el, const ParseContext &context) { PerMinute out; for (pugi::xml_attribute a : el.attributes()) @@ -72,30 +78,35 @@ PerMinute parsePerMinute(pugi::xml_node el) } if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else { throwUnknownAttribute(el, a.name()); } } - parsePerMinuteContent(out, el); + parsePerMinuteContent(out, el, context); return out; } void parsePerMinuteContent(PerMinute &out, pugi::xml_node el) +{ + parsePerMinuteContent(out, el, ParseContext{}); +} + +void parsePerMinuteContent(PerMinute &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/PerMinute.h b/src/private/mx/core/generated/PerMinute.h index a0d94a226..4cc57c6d2 100644 --- a/src/private/mx/core/generated/PerMinute.h +++ b/src/private/mx/core/generated/PerMinute.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The per-minute type can be a number, or a text description including numbers. If a font is /// specified, it overrides the font specified for the overall metronome element. This allows /// separate specification of a music font for the beat-unit and a text font for the numeric value, @@ -47,8 +49,12 @@ class PerMinute final PerMinute parsePerMinute(pugi::xml_node el); +PerMinute parsePerMinute(pugi::xml_node el, const ParseContext &context); + void parsePerMinuteContent(PerMinute &out, pugi::xml_node el); +void parsePerMinuteContent(PerMinute &out, pugi::xml_node el, const ParseContext &context); + void serializePerMinute(const PerMinute &v, pugi::xml_node parent, const char *tag); void serializePerMinuteContent(const PerMinute &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Percent.cpp b/src/private/mx/core/generated/Percent.cpp index 524abe4fc..f08a19140 100644 --- a/src/private/mx/core/generated/Percent.cpp +++ b/src/private/mx/core/generated/Percent.cpp @@ -42,20 +42,33 @@ std::string Percent::toString() const bool Percent::tryParse(std::string_view text, Percent &out) { - Decimal v; - if (!Decimal::tryParse(text, v)) + ValueParseOutcome outcome = ValueParseOutcome::valid; + Percent parsed = parse(text, outcome); + if (outcome == ValueParseOutcome::invalid) { return false; } - out = Percent{std::move(v)}; + out = std::move(parsed); return true; } Percent Percent::parse(std::string_view text) { - Percent v; - tryParse(text, v); - return v; + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +Percent Percent::parse(std::string_view text, ValueParseOutcome &outcome) +{ + Decimal v; + if (!Decimal::tryParse(text, v)) + { + outcome = ValueParseOutcome::invalid; + return Percent{}; + } + Percent out{v}; + outcome = out.value() == v ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; } } // namespace mx::core diff --git a/src/private/mx/core/generated/Percent.h b/src/private/mx/core/generated/Percent.h index 109b5bd03..c3c7cca0d 100644 --- a/src/private/mx/core/generated/Percent.h +++ b/src/private/mx/core/generated/Percent.h @@ -3,6 +3,7 @@ #pragma once #include "mx/core/Decimal.h" +#include "mx/core/Lexical.h" #include #include @@ -37,6 +38,9 @@ class Percent final /// Lenient: non-numeric text yields the clamped zero. static Percent parse(std::string_view text); + /// Lenient, and says whether the text was non-numeric or clamped. + static Percent parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const Percent &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Percussion.cpp b/src/private/mx/core/generated/Percussion.cpp index e2adc3992..53af7fcf7 100644 --- a/src/private/mx/core/generated/Percussion.cpp +++ b/src/private/mx/core/generated/Percussion.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Percussion.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -151,6 +152,11 @@ void Percussion::setChoice(PercussionChoice value) } Percussion parsePercussion(pugi::xml_node el) +{ + return parsePercussion(el, ParseContext{}); +} + +Percussion parsePercussion(pugi::xml_node el, const ParseContext &context) { Percussion out; for (pugi::xml_attribute a : el.attributes()) @@ -162,51 +168,51 @@ Percussion parsePercussion(pugi::xml_node el) } if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "halign") { - out.setHalign(LeftCenterRight::parse(a.value())); + out.setHalign(parseValue(a.value(), context, el, "halign")); } else if (aname == "valign") { - out.setValign(Valign::parse(a.value())); + out.setValign(parseValue(a.value(), context, el, "valign")); } else if (aname == "enclosure") { - out.setEnclosure(EnclosureShape::parse(a.value())); + out.setEnclosure(parseValue(a.value(), context, el, "enclosure")); } else if (aname == "id") { @@ -217,11 +223,16 @@ Percussion parsePercussion(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parsePercussionContent(out, el); + parsePercussionContent(out, el, context); return out; } void parsePercussionContent(Percussion &out, pugi::xml_node el) +{ + parsePercussionContent(out, el, ParseContext{}); +} + +void parsePercussionContent(Percussion &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "glass") || cursorIs(cursor, "metal") || cursorIs(cursor, "wood") || @@ -229,7 +240,7 @@ void parsePercussionContent(Percussion &out, pugi::xml_node el) cursorIs(cursor, "timpani") || cursorIs(cursor, "beater") || cursorIs(cursor, "stick") || cursorIs(cursor, "stick-location") || cursorIs(cursor, "other-percussion"))) { - out.setChoice(parsePercussionChoice(el, cursor)); + out.setChoice(parsePercussionChoice(el, cursor, context)); } else { diff --git a/src/private/mx/core/generated/Percussion.h b/src/private/mx/core/generated/Percussion.h index 00ebf1715..cfc480a92 100644 --- a/src/private/mx/core/generated/Percussion.h +++ b/src/private/mx/core/generated/Percussion.h @@ -28,6 +28,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The percussion element is used to define percussion pictogram symbols. Definitions for these /// symbols can be found in Kurt Stone's "Music Notation in the Twentieth Century" on pages 206-212 /// and 223. Some values are added to these based on how usage has evolved in the 30 years since @@ -86,8 +88,12 @@ class Percussion final Percussion parsePercussion(pugi::xml_node el); +Percussion parsePercussion(pugi::xml_node el, const ParseContext &context); + void parsePercussionContent(Percussion &out, pugi::xml_node el); +void parsePercussionContent(Percussion &out, pugi::xml_node el, const ParseContext &context); + void serializePercussion(const Percussion &v, pugi::xml_node parent, const char *tag); void serializePercussionContent(const Percussion &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/PercussionChoice.cpp b/src/private/mx/core/generated/PercussionChoice.cpp index 53a0b6fcd..792073f77 100644 --- a/src/private/mx/core/generated/PercussionChoice.cpp +++ b/src/private/mx/core/generated/PercussionChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/PercussionChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -71,70 +72,75 @@ PercussionChoice PercussionChoice::otherPercussion(OtherText value) } PercussionChoice parsePercussionChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parsePercussionChoice(el, cursor, ParseContext{}); +} + +PercussionChoice parsePercussionChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "glass"))) { - Glass value = parseGlass(cursor); + Glass value = parseGlass(cursor, context); cursor = nextElement(cursor); return PercussionChoice::glass(std::move(value)); } if (cursor && (cursorIs(cursor, "metal"))) { - Metal value = parseMetal(cursor); + Metal value = parseMetal(cursor, context); cursor = nextElement(cursor); return PercussionChoice::metal(std::move(value)); } if (cursor && (cursorIs(cursor, "wood"))) { - Wood value = parseWood(cursor); + Wood value = parseWood(cursor, context); cursor = nextElement(cursor); return PercussionChoice::wood(std::move(value)); } if (cursor && (cursorIs(cursor, "pitched"))) { - Pitched value = parsePitched(cursor); + Pitched value = parsePitched(cursor, context); cursor = nextElement(cursor); return PercussionChoice::pitched(std::move(value)); } if (cursor && (cursorIs(cursor, "membrane"))) { - Membrane value = parseMembrane(cursor); + Membrane value = parseMembrane(cursor, context); cursor = nextElement(cursor); return PercussionChoice::membrane(std::move(value)); } if (cursor && (cursorIs(cursor, "effect"))) { - Effect value = parseEffect(cursor); + Effect value = parseEffect(cursor, context); cursor = nextElement(cursor); return PercussionChoice::effect(std::move(value)); } if (cursor && (cursorIs(cursor, "timpani"))) { - Timpani value = parseTimpani(cursor); + Timpani value = parseTimpani(cursor, context); cursor = nextElement(cursor); return PercussionChoice::timpani(std::move(value)); } if (cursor && (cursorIs(cursor, "beater"))) { - Beater value = parseBeater(cursor); + Beater value = parseBeater(cursor, context); cursor = nextElement(cursor); return PercussionChoice::beater(std::move(value)); } if (cursor && (cursorIs(cursor, "stick"))) { - Stick value = parseStick(cursor); + Stick value = parseStick(cursor, context); cursor = nextElement(cursor); return PercussionChoice::stick(std::move(value)); } if (cursor && (cursorIs(cursor, "stick-location"))) { - StickLocation value = StickLocation::parse(childText(cursor)); + StickLocation value = parseValue(childText(cursor), context, cursor, nullptr); cursor = nextElement(cursor); return PercussionChoice::stickLocation(std::move(value)); } if (cursor && (cursorIs(cursor, "other-percussion"))) { - OtherText value = parseOtherText(cursor); + OtherText value = parseOtherText(cursor, context); cursor = nextElement(cursor); return PercussionChoice::otherPercussion(std::move(value)); } diff --git a/src/private/mx/core/generated/PercussionChoice.h b/src/private/mx/core/generated/PercussionChoice.h index f06cdbccd..f1b8b3079 100644 --- a/src/private/mx/core/generated/PercussionChoice.h +++ b/src/private/mx/core/generated/PercussionChoice.h @@ -27,6 +27,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -218,6 +220,8 @@ class PercussionChoice final /// the enclosing element, for error paths. PercussionChoice parsePercussionChoice(pugi::xml_node el, pugi::xml_node &cursor); +PercussionChoice parsePercussionChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializePercussionChoice(const PercussionChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/Pitch.cpp b/src/private/mx/core/generated/Pitch.cpp index 82cd46e18..fde8c26d4 100644 --- a/src/private/mx/core/generated/Pitch.cpp +++ b/src/private/mx/core/generated/Pitch.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Pitch.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,6 +42,11 @@ void Pitch::setOctave(Octave value) } Pitch parsePitch(pugi::xml_node el) +{ + return parsePitch(el, ParseContext{}); +} + +Pitch parsePitch(pugi::xml_node el, const ParseContext &context) { Pitch out; for (pugi::xml_attribute a : el.attributes()) @@ -52,16 +58,21 @@ Pitch parsePitch(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parsePitchContent(out, el); + parsePitchContent(out, el, context); return out; } void parsePitchContent(Pitch &out, pugi::xml_node el) +{ + parsePitchContent(out, el, ParseContext{}); +} + +void parsePitchContent(Pitch &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "step")) { - out.setStep(Step::parse(childText(cursor))); + out.setStep(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -70,12 +81,12 @@ void parsePitchContent(Pitch &out, pugi::xml_node el) } if (cursorIs(cursor, "alter")) { - out.setAlter(Semitones::parse(childText(cursor))); + out.setAlter(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (cursorIs(cursor, "octave")) { - out.setOctave(Octave::parse(childText(cursor))); + out.setOctave(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else diff --git a/src/private/mx/core/generated/Pitch.h b/src/private/mx/core/generated/Pitch.h index 04c153ed7..8929b2594 100644 --- a/src/private/mx/core/generated/Pitch.h +++ b/src/private/mx/core/generated/Pitch.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Pitch is represented as a combination of the step of the diatonic scale, the chromatic /// alteration, and the octave. /// Content fields mirror the schema grammar in declaration order; the @@ -42,8 +44,12 @@ class Pitch final Pitch parsePitch(pugi::xml_node el); +Pitch parsePitch(pugi::xml_node el, const ParseContext &context); + void parsePitchContent(Pitch &out, pugi::xml_node el); +void parsePitchContent(Pitch &out, pugi::xml_node el, const ParseContext &context); + void serializePitch(const Pitch &v, pugi::xml_node parent, const char *tag); void serializePitchContent(const Pitch &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Pitched.cpp b/src/private/mx/core/generated/Pitched.cpp index 548ab8298..cc515049c 100644 --- a/src/private/mx/core/generated/Pitched.cpp +++ b/src/private/mx/core/generated/Pitched.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Pitched.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void Pitched::setValue(PitchedValue value) } Pitched parsePitched(pugi::xml_node el) +{ + return parsePitched(el, ParseContext{}); +} + +Pitched parsePitched(pugi::xml_node el, const ParseContext &context) { Pitched out; for (pugi::xml_attribute a : el.attributes()) @@ -42,20 +48,25 @@ Pitched parsePitched(pugi::xml_node el) } if (aname == "smufl") { - out.setSmufl(SmuflPictogramGlyphName::parse(a.value())); + out.setSmufl(parseValue(a.value(), context, el, "smufl")); } else { throwUnknownAttribute(el, a.name()); } } - parsePitchedContent(out, el); + parsePitchedContent(out, el, context); return out; } void parsePitchedContent(Pitched &out, pugi::xml_node el) { - out.setValue(PitchedValue::parse(childText(el))); + parsePitchedContent(out, el, ParseContext{}); +} + +void parsePitchedContent(Pitched &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Pitched.h b/src/private/mx/core/generated/Pitched.h index a8d577826..532e04841 100644 --- a/src/private/mx/core/generated/Pitched.h +++ b/src/private/mx/core/generated/Pitched.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The pitched-value type represents pictograms for pitched percussion instruments. The smufl /// attribute is used to distinguish different SMuFL glyphs for a particular pictogram within the /// Tuned mallet percussion pictograms range. @@ -35,8 +37,12 @@ class Pitched final Pitched parsePitched(pugi::xml_node el); +Pitched parsePitched(pugi::xml_node el, const ParseContext &context); + void parsePitchedContent(Pitched &out, pugi::xml_node el); +void parsePitchedContent(Pitched &out, pugi::xml_node el, const ParseContext &context); + void serializePitched(const Pitched &v, pugi::xml_node parent, const char *tag); void serializePitchedContent(const Pitched &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/PitchedValue.cpp b/src/private/mx/core/generated/PitchedValue.cpp index 929c0b528..bc37f12dc 100644 --- a/src/private/mx/core/generated/PitchedValue.cpp +++ b/src/private/mx/core/generated/PitchedValue.cpp @@ -87,9 +87,15 @@ bool PitchedValue::tryParse(std::string_view text, PitchedValue &out) noexcept } PitchedValue PitchedValue::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +PitchedValue PitchedValue::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { PitchedValue v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/PitchedValue.h b/src/private/mx/core/generated/PitchedValue.h index d5b0e6397..3fd94975a 100644 --- a/src/private/mx/core/generated/PitchedValue.h +++ b/src/private/mx/core/generated/PitchedValue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -59,6 +61,9 @@ class PitchedValue final /// (the import leniency policy; never produces an invalid value). static PitchedValue parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static PitchedValue parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const PitchedValue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/PlacementText.cpp b/src/private/mx/core/generated/PlacementText.cpp index 65d79f1b5..e2a257c88 100644 --- a/src/private/mx/core/generated/PlacementText.cpp +++ b/src/private/mx/core/generated/PlacementText.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/PlacementText.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -121,6 +122,11 @@ void PlacementText::setValue(std::string value) } PlacementText parsePlacementText(pugi::xml_node el) +{ + return parsePlacementText(el, ParseContext{}); +} + +PlacementText parsePlacementText(pugi::xml_node el, const ParseContext &context) { PlacementText out; for (pugi::xml_attribute a : el.attributes()) @@ -132,54 +138,59 @@ PlacementText parsePlacementText(pugi::xml_node el) } if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else { throwUnknownAttribute(el, a.name()); } } - parsePlacementTextContent(out, el); + parsePlacementTextContent(out, el, context); return out; } void parsePlacementTextContent(PlacementText &out, pugi::xml_node el) +{ + parsePlacementTextContent(out, el, ParseContext{}); +} + +void parsePlacementTextContent(PlacementText &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/PlacementText.h b/src/private/mx/core/generated/PlacementText.h index d72111cb2..39fed3d24 100644 --- a/src/private/mx/core/generated/PlacementText.h +++ b/src/private/mx/core/generated/PlacementText.h @@ -21,6 +21,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The placement-text type represents a text element with print-style and placement attribute /// groups. class PlacementText final @@ -66,8 +68,12 @@ class PlacementText final PlacementText parsePlacementText(pugi::xml_node el); +PlacementText parsePlacementText(pugi::xml_node el, const ParseContext &context); + void parsePlacementTextContent(PlacementText &out, pugi::xml_node el); +void parsePlacementTextContent(PlacementText &out, pugi::xml_node el, const ParseContext &context); + void serializePlacementText(const PlacementText &v, pugi::xml_node parent, const char *tag); void serializePlacementTextContent(const PlacementText &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Play.cpp b/src/private/mx/core/generated/Play.cpp index 6745eb48c..8a881c3f6 100644 --- a/src/private/mx/core/generated/Play.cpp +++ b/src/private/mx/core/generated/Play.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Play.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -36,6 +37,11 @@ void Play::setChoice(std::vector value) } Play parsePlay(pugi::xml_node el) +{ + return parsePlay(el, ParseContext{}); +} + +Play parsePlay(pugi::xml_node el, const ParseContext &context) { Play out; for (pugi::xml_attribute a : el.attributes()) @@ -54,17 +60,22 @@ Play parsePlay(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parsePlayContent(out, el); + parsePlayContent(out, el, context); return out; } void parsePlayContent(Play &out, pugi::xml_node el) +{ + parsePlayContent(out, el, ParseContext{}); +} + +void parsePlayContent(Play &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); while (cursor && (cursorIs(cursor, "ipa") || cursorIs(cursor, "mute") || cursorIs(cursor, "semi-pitched") || cursorIs(cursor, "other-play"))) { - out.addChoice(parsePlayChoice(el, cursor)); + out.addChoice(parsePlayChoice(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/Play.h b/src/private/mx/core/generated/Play.h index 51737531f..c3e3623d4 100644 --- a/src/private/mx/core/generated/Play.h +++ b/src/private/mx/core/generated/Play.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The play type specifies playback techniques to be used in conjunction with the instrument-sound /// element. When used as part of a sound element, it applies to all notes going forward in score /// order. In multi-instrument parts, the affected instrument should be specified using the id @@ -42,8 +44,12 @@ class Play final Play parsePlay(pugi::xml_node el); +Play parsePlay(pugi::xml_node el, const ParseContext &context); + void parsePlayContent(Play &out, pugi::xml_node el); +void parsePlayContent(Play &out, pugi::xml_node el, const ParseContext &context); + void serializePlay(const Play &v, pugi::xml_node parent, const char *tag); void serializePlayContent(const Play &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/PlayChoice.cpp b/src/private/mx/core/generated/PlayChoice.cpp index 3b4cc2d83..1b27dada0 100644 --- a/src/private/mx/core/generated/PlayChoice.cpp +++ b/src/private/mx/core/generated/PlayChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/PlayChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -36,6 +37,11 @@ PlayChoice PlayChoice::otherPlay(OtherPlay value) } PlayChoice parsePlayChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parsePlayChoice(el, cursor, ParseContext{}); +} + +PlayChoice parsePlayChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "ipa"))) { @@ -45,19 +51,19 @@ PlayChoice parsePlayChoice(pugi::xml_node el, pugi::xml_node &cursor) } if (cursor && (cursorIs(cursor, "mute"))) { - Mute value = Mute::parse(childText(cursor)); + Mute value = parseValue(childText(cursor), context, cursor, nullptr); cursor = nextElement(cursor); return PlayChoice::mute(std::move(value)); } if (cursor && (cursorIs(cursor, "semi-pitched"))) { - SemiPitched value = SemiPitched::parse(childText(cursor)); + SemiPitched value = parseValue(childText(cursor), context, cursor, nullptr); cursor = nextElement(cursor); return PlayChoice::semiPitched(std::move(value)); } if (cursor && (cursorIs(cursor, "other-play"))) { - OtherPlay value = parseOtherPlay(cursor); + OtherPlay value = parseOtherPlay(cursor, context); cursor = nextElement(cursor); return PlayChoice::otherPlay(std::move(value)); } diff --git a/src/private/mx/core/generated/PlayChoice.h b/src/private/mx/core/generated/PlayChoice.h index 8c167cd65..c1f104200 100644 --- a/src/private/mx/core/generated/PlayChoice.h +++ b/src/private/mx/core/generated/PlayChoice.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -111,6 +113,8 @@ class PlayChoice final /// the enclosing element, for error paths. PlayChoice parsePlayChoice(pugi::xml_node el, pugi::xml_node &cursor); +PlayChoice parsePlayChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializePlayChoice(const PlayChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/Player.cpp b/src/private/mx/core/generated/Player.cpp index f408054d1..1718151a8 100644 --- a/src/private/mx/core/generated/Player.cpp +++ b/src/private/mx/core/generated/Player.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Player.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void Player::setPlayerName(std::string value) } Player parsePlayer(pugi::xml_node el) +{ + return parsePlayer(el, ParseContext{}); +} + +Player parsePlayer(pugi::xml_node el, const ParseContext &context) { Player out; bool seen_id = false; @@ -55,11 +61,16 @@ Player parsePlayer(pugi::xml_node el) { throwMissingAttribute(el, "id"); } - parsePlayerContent(out, el); + parsePlayerContent(out, el, context); return out; } void parsePlayerContent(Player &out, pugi::xml_node el) +{ + parsePlayerContent(out, el, ParseContext{}); +} + +void parsePlayerContent(Player &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "player-name")) diff --git a/src/private/mx/core/generated/Player.h b/src/private/mx/core/generated/Player.h index 851b3317d..9cdfb478b 100644 --- a/src/private/mx/core/generated/Player.h +++ b/src/private/mx/core/generated/Player.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The player type allows for multiple players per score-part for use in listening applications. One /// player may play multiple instruments, while a single instrument may include multiple players in /// divisi sections. @@ -39,8 +41,12 @@ class Player final Player parsePlayer(pugi::xml_node el); +Player parsePlayer(pugi::xml_node el, const ParseContext &context); + void parsePlayerContent(Player &out, pugi::xml_node el); +void parsePlayerContent(Player &out, pugi::xml_node el, const ParseContext &context); + void serializePlayer(const Player &v, pugi::xml_node parent, const char *tag); void serializePlayerContent(const Player &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/PositiveDivisions.cpp b/src/private/mx/core/generated/PositiveDivisions.cpp index 73d5cfa66..fd7ef10b8 100644 --- a/src/private/mx/core/generated/PositiveDivisions.cpp +++ b/src/private/mx/core/generated/PositiveDivisions.cpp @@ -38,20 +38,33 @@ std::string PositiveDivisions::toString() const bool PositiveDivisions::tryParse(std::string_view text, PositiveDivisions &out) { - Decimal v; - if (!Decimal::tryParse(text, v)) + ValueParseOutcome outcome = ValueParseOutcome::valid; + PositiveDivisions parsed = parse(text, outcome); + if (outcome == ValueParseOutcome::invalid) { return false; } - out = PositiveDivisions{std::move(v)}; + out = std::move(parsed); return true; } PositiveDivisions PositiveDivisions::parse(std::string_view text) { - PositiveDivisions v; - tryParse(text, v); - return v; + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +PositiveDivisions PositiveDivisions::parse(std::string_view text, ValueParseOutcome &outcome) +{ + Decimal v; + if (!Decimal::tryParse(text, v)) + { + outcome = ValueParseOutcome::invalid; + return PositiveDivisions{}; + } + PositiveDivisions out{v}; + outcome = out.value() == v ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; } } // namespace mx::core diff --git a/src/private/mx/core/generated/PositiveDivisions.h b/src/private/mx/core/generated/PositiveDivisions.h index bf23bbdcd..324c9e043 100644 --- a/src/private/mx/core/generated/PositiveDivisions.h +++ b/src/private/mx/core/generated/PositiveDivisions.h @@ -3,6 +3,7 @@ #pragma once #include "mx/core/Decimal.h" +#include "mx/core/Lexical.h" #include #include @@ -37,6 +38,9 @@ class PositiveDivisions final /// Lenient: non-numeric text yields the clamped zero. static PositiveDivisions parse(std::string_view text); + /// Lenient, and says whether the text was non-numeric or clamped. + static PositiveDivisions parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const PositiveDivisions &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/PositiveIntegerOrEmpty.cpp b/src/private/mx/core/generated/PositiveIntegerOrEmpty.cpp index 6b4543d82..353f4e2aa 100644 --- a/src/private/mx/core/generated/PositiveIntegerOrEmpty.cpp +++ b/src/private/mx/core/generated/PositiveIntegerOrEmpty.cpp @@ -60,12 +60,24 @@ bool PositiveIntegerOrEmpty::tryParse(std::string_view text, PositiveIntegerOrEm } PositiveIntegerOrEmpty PositiveIntegerOrEmpty::parse(std::string_view text) +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +PositiveIntegerOrEmpty PositiveIntegerOrEmpty::parse(std::string_view text, ValueParseOutcome &outcome) { PositiveIntegerOrEmpty out; if (tryParse(text, out)) { + outcome = ValueParseOutcome::valid; + if (int raw{}; out.isPositiveInteger() && tryParseInt(text, raw) && out.asPositiveInteger() != raw) + { + outcome = ValueParseOutcome::adjusted; + } return out; } + outcome = ValueParseOutcome::invalid; return PositiveIntegerOrEmpty::positiveInteger(parseInt(text)); } diff --git a/src/private/mx/core/generated/PositiveIntegerOrEmpty.h b/src/private/mx/core/generated/PositiveIntegerOrEmpty.h index 791729511..e68813ef1 100644 --- a/src/private/mx/core/generated/PositiveIntegerOrEmpty.h +++ b/src/private/mx/core/generated/PositiveIntegerOrEmpty.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include #include @@ -65,6 +67,10 @@ class PositiveIntegerOrEmpty final /// parse (never produces an invalid value). static PositiveIntegerOrEmpty parse(std::string_view text); + /// Lenient, and says whether no member matched or a matched number was + /// clamped. + static PositiveIntegerOrEmpty parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const PositiveIntegerOrEmpty &other) const = default; private: diff --git a/src/private/mx/core/generated/PrincipalVoice.cpp b/src/private/mx/core/generated/PrincipalVoice.cpp index 463652755..bb96c62d7 100644 --- a/src/private/mx/core/generated/PrincipalVoice.cpp +++ b/src/private/mx/core/generated/PrincipalVoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/PrincipalVoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -161,6 +162,11 @@ void PrincipalVoice::setValue(std::string value) } PrincipalVoice parsePrincipalVoice(pugi::xml_node el) +{ + return parsePrincipalVoice(el, ParseContext{}); +} + +PrincipalVoice parsePrincipalVoice(pugi::xml_node el, const ParseContext &context) { PrincipalVoice out; bool seen_type = false; @@ -175,56 +181,56 @@ PrincipalVoice parsePrincipalVoice(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(StartStop::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "symbol") { seen_symbol = true; - out.setSymbol(PrincipalVoiceSymbol::parse(a.value())); + out.setSymbol(parseValue(a.value(), context, el, "symbol")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "halign") { - out.setHalign(LeftCenterRight::parse(a.value())); + out.setHalign(parseValue(a.value(), context, el, "halign")); } else if (aname == "valign") { - out.setValign(Valign::parse(a.value())); + out.setValign(parseValue(a.value(), context, el, "valign")); } else if (aname == "id") { @@ -243,11 +249,16 @@ PrincipalVoice parsePrincipalVoice(pugi::xml_node el) { throwMissingAttribute(el, "symbol"); } - parsePrincipalVoiceContent(out, el); + parsePrincipalVoiceContent(out, el, context); return out; } void parsePrincipalVoiceContent(PrincipalVoice &out, pugi::xml_node el) +{ + parsePrincipalVoiceContent(out, el, ParseContext{}); +} + +void parsePrincipalVoiceContent(PrincipalVoice &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/PrincipalVoice.h b/src/private/mx/core/generated/PrincipalVoice.h index 7d6ed9f49..daeb5c185 100644 --- a/src/private/mx/core/generated/PrincipalVoice.h +++ b/src/private/mx/core/generated/PrincipalVoice.h @@ -26,6 +26,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The principal-voice type represents principal and secondary voices in a score, either for /// analysis or for square bracket symbols that appear in a score. The element content is used for /// analysis and may be any text value. The symbol attribute indicates the type of symbol used. When @@ -86,8 +88,12 @@ class PrincipalVoice final PrincipalVoice parsePrincipalVoice(pugi::xml_node el); +PrincipalVoice parsePrincipalVoice(pugi::xml_node el, const ParseContext &context); + void parsePrincipalVoiceContent(PrincipalVoice &out, pugi::xml_node el); +void parsePrincipalVoiceContent(PrincipalVoice &out, pugi::xml_node el, const ParseContext &context); + void serializePrincipalVoice(const PrincipalVoice &v, pugi::xml_node parent, const char *tag); void serializePrincipalVoiceContent(const PrincipalVoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/PrincipalVoiceSymbol.cpp b/src/private/mx/core/generated/PrincipalVoiceSymbol.cpp index f360ac000..9d24ba0ac 100644 --- a/src/private/mx/core/generated/PrincipalVoiceSymbol.cpp +++ b/src/private/mx/core/generated/PrincipalVoiceSymbol.cpp @@ -54,9 +54,15 @@ bool PrincipalVoiceSymbol::tryParse(std::string_view text, PrincipalVoiceSymbol } PrincipalVoiceSymbol PrincipalVoiceSymbol::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +PrincipalVoiceSymbol PrincipalVoiceSymbol::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { PrincipalVoiceSymbol v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/PrincipalVoiceSymbol.h b/src/private/mx/core/generated/PrincipalVoiceSymbol.h index 0eb3481b1..e739b1faa 100644 --- a/src/private/mx/core/generated/PrincipalVoiceSymbol.h +++ b/src/private/mx/core/generated/PrincipalVoiceSymbol.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -47,6 +49,9 @@ class PrincipalVoiceSymbol final /// (the import leniency policy; never produces an invalid value). static PrincipalVoiceSymbol parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static PrincipalVoiceSymbol parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const PrincipalVoiceSymbol &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Print.cpp b/src/private/mx/core/generated/Print.cpp index fd28a4991..65a1ee3ff 100644 --- a/src/private/mx/core/generated/Print.cpp +++ b/src/private/mx/core/generated/Print.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Print.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -121,6 +122,11 @@ void Print::setPartAbbreviationDisplay(std::optional value) } Print parsePrint(pugi::xml_node el) +{ + return parsePrint(el, ParseContext{}); +} + +Print parsePrint(pugi::xml_node el, const ParseContext &context) { Print out; for (pugi::xml_attribute a : el.attributes()) @@ -132,19 +138,19 @@ Print parsePrint(pugi::xml_node el) } if (aname == "staff-spacing") { - out.setStaffSpacing(Tenths::parse(a.value())); + out.setStaffSpacing(parseValue(a.value(), context, el, "staff-spacing")); } else if (aname == "new-system") { - out.setNewSystem(YesNo::parse(a.value())); + out.setNewSystem(parseValue(a.value(), context, el, "new-system")); } else if (aname == "new-page") { - out.setNewPage(YesNo::parse(a.value())); + out.setNewPage(parseValue(a.value(), context, el, "new-page")); } else if (aname == "blank-page") { - out.setBlankPage(parseInt(a.value())); + out.setBlankPage(parseIntegerValue(a.value(), context, el, "blank-page")); } else if (aname == "page-number") { @@ -159,36 +165,41 @@ Print parsePrint(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parsePrintContent(out, el); + parsePrintContent(out, el, context); return out; } void parsePrintContent(Print &out, pugi::xml_node el) +{ + parsePrintContent(out, el, ParseContext{}); +} + +void parsePrintContent(Print &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "page-layout") || cursorIs(cursor, "system-layout") || cursorIs(cursor, "staff-layout"))) { - out.setLayout(parseLayoutGroup(el, cursor)); + out.setLayout(parseLayoutGroup(el, cursor, context)); } if (cursorIs(cursor, "measure-layout")) { - out.setMeasureLayout(parseMeasureLayout(cursor)); + out.setMeasureLayout(parseMeasureLayout(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "measure-numbering")) { - out.setMeasureNumbering(parseMeasureNumbering(cursor)); + out.setMeasureNumbering(parseMeasureNumbering(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "part-name-display")) { - out.setPartNameDisplay(parseNameDisplay(cursor)); + out.setPartNameDisplay(parseNameDisplay(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "part-abbreviation-display")) { - out.setPartAbbreviationDisplay(parseNameDisplay(cursor)); + out.setPartAbbreviationDisplay(parseNameDisplay(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/Print.h b/src/private/mx/core/generated/Print.h index a94e7c8f8..3899831e3 100644 --- a/src/private/mx/core/generated/Print.h +++ b/src/private/mx/core/generated/Print.h @@ -24,6 +24,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The print type contains general printing parameters, including layout elements. The /// part-name-display and part-abbreviation-display elements may also be used here to change how a /// part name or abbreviation is displayed over the course of a piece. They take effect when the @@ -75,8 +77,12 @@ class Print final Print parsePrint(pugi::xml_node el); +Print parsePrint(pugi::xml_node el, const ParseContext &context); + void parsePrintContent(Print &out, pugi::xml_node el); +void parsePrintContent(Print &out, pugi::xml_node el, const ParseContext &context); + void serializePrint(const Print &v, pugi::xml_node parent, const char *tag); void serializePrintContent(const Print &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Release.cpp b/src/private/mx/core/generated/Release.cpp index d0e63f7dc..daef7ed38 100644 --- a/src/private/mx/core/generated/Release.cpp +++ b/src/private/mx/core/generated/Release.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Release.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -21,6 +22,11 @@ void Release::setOffset(std::optional value) } Release parseRelease(pugi::xml_node el) +{ + return parseRelease(el, ParseContext{}); +} + +Release parseRelease(pugi::xml_node el, const ParseContext &context) { Release out; for (pugi::xml_attribute a : el.attributes()) @@ -32,14 +38,14 @@ Release parseRelease(pugi::xml_node el) } if (aname == "offset") { - out.setOffset(Divisions::parse(a.value())); + out.setOffset(parseValue(a.value(), context, el, "offset")); } else { throwUnknownAttribute(el, a.name()); } } - parseEmptyContent(out, el); + parseEmptyContent(out, el, context); return out; } diff --git a/src/private/mx/core/generated/Release.h b/src/private/mx/core/generated/Release.h index d9a9aef64..4c38a8a5b 100644 --- a/src/private/mx/core/generated/Release.h +++ b/src/private/mx/core/generated/Release.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The release type indicates that a bend is a release rather than a normal bend or pre-bend. The /// offset attribute specifies where the release starts in terms of divisions relative to the current /// note. The first-beat and last-beat attributes of the parent bend element are relative to the @@ -35,6 +37,8 @@ class Release : public Empty Release parseRelease(pugi::xml_node el); +Release parseRelease(pugi::xml_node el, const ParseContext &context); + void serializeRelease(const Release &v, pugi::xml_node parent, const char *tag); } // namespace mx::core diff --git a/src/private/mx/core/generated/Repeat.cpp b/src/private/mx/core/generated/Repeat.cpp index 7a3e7c557..6e3ab7cbd 100644 --- a/src/private/mx/core/generated/Repeat.cpp +++ b/src/private/mx/core/generated/Repeat.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Repeat.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -51,6 +52,11 @@ void Repeat::setWinged(std::optional value) } Repeat parseRepeat(pugi::xml_node el) +{ + return parseRepeat(el, ParseContext{}); +} + +Repeat parseRepeat(pugi::xml_node el, const ParseContext &context) { Repeat out; bool seen_direction = false; @@ -64,19 +70,19 @@ Repeat parseRepeat(pugi::xml_node el) if (aname == "direction") { seen_direction = true; - out.setDirection(BackwardForward::parse(a.value())); + out.setDirection(parseValue(a.value(), context, el, "direction")); } else if (aname == "times") { - out.setTimes(parseInt(a.value())); + out.setTimes(parseIntegerValue(a.value(), context, el, "times")); } else if (aname == "after-jump") { - out.setAfterJump(YesNo::parse(a.value())); + out.setAfterJump(parseValue(a.value(), context, el, "after-jump")); } else if (aname == "winged") { - out.setWinged(Winged::parse(a.value())); + out.setWinged(parseValue(a.value(), context, el, "winged")); } else { @@ -87,13 +93,19 @@ Repeat parseRepeat(pugi::xml_node el) { throwMissingAttribute(el, "direction"); } - parseRepeatContent(out, el); + parseRepeatContent(out, el, context); return out; } void parseRepeatContent(Repeat &out, pugi::xml_node el) +{ + parseRepeatContent(out, el, ParseContext{}); +} + +void parseRepeatContent(Repeat &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Repeat.h b/src/private/mx/core/generated/Repeat.h index 3818602c7..ce3f360cc 100644 --- a/src/private/mx/core/generated/Repeat.h +++ b/src/private/mx/core/generated/Repeat.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The repeat type represents repeat marks. The start of the repeat has a forward direction while /// the end of the repeat has a backward direction. The times and after-jump attributes are only used /// with backward repeats that are not part of an ending. The times attribute indicates the number of @@ -44,8 +46,12 @@ class Repeat final Repeat parseRepeat(pugi::xml_node el); +Repeat parseRepeat(pugi::xml_node el, const ParseContext &context); + void parseRepeatContent(Repeat &out, pugi::xml_node el); +void parseRepeatContent(Repeat &out, pugi::xml_node el, const ParseContext &context); + void serializeRepeat(const Repeat &v, pugi::xml_node parent, const char *tag); void serializeRepeatContent(const Repeat &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Rest.cpp b/src/private/mx/core/generated/Rest.cpp index c74da8625..2f87e248d 100644 --- a/src/private/mx/core/generated/Rest.cpp +++ b/src/private/mx/core/generated/Rest.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Rest.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void Rest::setDisplayStepOctave(std::optional value) } Rest parseRest(pugi::xml_node el) +{ + return parseRest(el, ParseContext{}); +} + +Rest parseRest(pugi::xml_node el, const ParseContext &context) { Rest out; for (pugi::xml_attribute a : el.attributes()) @@ -42,23 +48,28 @@ Rest parseRest(pugi::xml_node el) } if (aname == "measure") { - out.setMeasure(YesNo::parse(a.value())); + out.setMeasure(parseValue(a.value(), context, el, "measure")); } else { throwUnknownAttribute(el, a.name()); } } - parseRestContent(out, el); + parseRestContent(out, el, context); return out; } void parseRestContent(Rest &out, pugi::xml_node el) +{ + parseRestContent(out, el, ParseContext{}); +} + +void parseRestContent(Rest &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "display-step"))) { - out.setDisplayStepOctave(parseDisplayStepOctaveGroup(el, cursor)); + out.setDisplayStepOctave(parseDisplayStepOctaveGroup(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/Rest.h b/src/private/mx/core/generated/Rest.h index a5f41f733..8154e8571 100644 --- a/src/private/mx/core/generated/Rest.h +++ b/src/private/mx/core/generated/Rest.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The rest element indicates notated rests or silences. Rest elements are usually empty, but /// placement on the staff can be specified using display-step and display-octave elements. If the /// measure attribute is set to yes, this indicates this is a complete measure rest. @@ -39,8 +41,12 @@ class Rest final Rest parseRest(pugi::xml_node el); +Rest parseRest(pugi::xml_node el, const ParseContext &context); + void parseRestContent(Rest &out, pugi::xml_node el); +void parseRestContent(Rest &out, pugi::xml_node el, const ParseContext &context); + void serializeRest(const Rest &v, pugi::xml_node parent, const char *tag); void serializeRestContent(const Rest &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/RightLeftMiddle.cpp b/src/private/mx/core/generated/RightLeftMiddle.cpp index a73f7ffc1..cc2dd4a37 100644 --- a/src/private/mx/core/generated/RightLeftMiddle.cpp +++ b/src/private/mx/core/generated/RightLeftMiddle.cpp @@ -48,9 +48,15 @@ bool RightLeftMiddle::tryParse(std::string_view text, RightLeftMiddle &out) noex } RightLeftMiddle RightLeftMiddle::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +RightLeftMiddle RightLeftMiddle::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { RightLeftMiddle v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/RightLeftMiddle.h b/src/private/mx/core/generated/RightLeftMiddle.h index 2347b4276..190dca905 100644 --- a/src/private/mx/core/generated/RightLeftMiddle.h +++ b/src/private/mx/core/generated/RightLeftMiddle.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -42,6 +44,9 @@ class RightLeftMiddle final /// (the import leniency policy; never produces an invalid value). static RightLeftMiddle parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static RightLeftMiddle parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const RightLeftMiddle &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Root.cpp b/src/private/mx/core/generated/Root.cpp index ad53df3f8..2098acddf 100644 --- a/src/private/mx/core/generated/Root.cpp +++ b/src/private/mx/core/generated/Root.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Root.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void Root::setRootAlter(std::optional value) } Root parseRoot(pugi::xml_node el) +{ + return parseRoot(el, ParseContext{}); +} + +Root parseRoot(pugi::xml_node el, const ParseContext &context) { Root out; for (pugi::xml_attribute a : el.attributes()) @@ -42,16 +48,21 @@ Root parseRoot(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseRootContent(out, el); + parseRootContent(out, el, context); return out; } void parseRootContent(Root &out, pugi::xml_node el) +{ + parseRootContent(out, el, ParseContext{}); +} + +void parseRootContent(Root &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "root-step")) { - out.setRootStep(parseRootStep(cursor)); + out.setRootStep(parseRootStep(cursor, context)); cursor = nextElement(cursor); } else @@ -60,7 +71,7 @@ void parseRootContent(Root &out, pugi::xml_node el) } if (cursorIs(cursor, "root-alter")) { - out.setRootAlter(parseHarmonyAlter(cursor)); + out.setRootAlter(parseHarmonyAlter(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/Root.h b/src/private/mx/core/generated/Root.h index 003ccdc02..580fdb7d6 100644 --- a/src/private/mx/core/generated/Root.h +++ b/src/private/mx/core/generated/Root.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The root type indicates a pitch like C, D, E vs. a scale degree like 1, 2, 3. It is used with /// chord symbols in popular music. The root element has a root-step and optional root-alter element /// similar to the step and alter elements, but renamed to distinguish the different musical @@ -40,8 +42,12 @@ class Root final Root parseRoot(pugi::xml_node el); +Root parseRoot(pugi::xml_node el, const ParseContext &context); + void parseRootContent(Root &out, pugi::xml_node el); +void parseRootContent(Root &out, pugi::xml_node el, const ParseContext &context); + void serializeRoot(const Root &v, pugi::xml_node parent, const char *tag); void serializeRootContent(const Root &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/RootStep.cpp b/src/private/mx/core/generated/RootStep.cpp index 9c64d1ebb..e7113dd4a 100644 --- a/src/private/mx/core/generated/RootStep.cpp +++ b/src/private/mx/core/generated/RootStep.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/RootStep.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -121,6 +122,11 @@ void RootStep::setValue(Step value) } RootStep parseRootStep(pugi::xml_node el) +{ + return parseRootStep(el, ParseContext{}); +} + +RootStep parseRootStep(pugi::xml_node el, const ParseContext &context) { RootStep out; for (pugi::xml_attribute a : el.attributes()) @@ -136,52 +142,57 @@ RootStep parseRootStep(pugi::xml_node el) } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else { throwUnknownAttribute(el, a.name()); } } - parseRootStepContent(out, el); + parseRootStepContent(out, el, context); return out; } void parseRootStepContent(RootStep &out, pugi::xml_node el) { - out.setValue(Step::parse(childText(el))); + parseRootStepContent(out, el, ParseContext{}); +} + +void parseRootStepContent(RootStep &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/RootStep.h b/src/private/mx/core/generated/RootStep.h index c83b570bc..cf0f2deb1 100644 --- a/src/private/mx/core/generated/RootStep.h +++ b/src/private/mx/core/generated/RootStep.h @@ -21,6 +21,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The root-step type represents the pitch step of the root of the current chord within the harmony /// element. The text attribute indicates how the root should appear in a score if not using the /// element contents. @@ -67,8 +69,12 @@ class RootStep final RootStep parseRootStep(pugi::xml_node el); +RootStep parseRootStep(pugi::xml_node el, const ParseContext &context); + void parseRootStepContent(RootStep &out, pugi::xml_node el); +void parseRootStepContent(RootStep &out, pugi::xml_node el, const ParseContext &context); + void serializeRootStep(const RootStep &v, pugi::xml_node parent, const char *tag); void serializeRootStepContent(const RootStep &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/RotationDegrees.cpp b/src/private/mx/core/generated/RotationDegrees.cpp index a7f4dbd87..c4cfde395 100644 --- a/src/private/mx/core/generated/RotationDegrees.cpp +++ b/src/private/mx/core/generated/RotationDegrees.cpp @@ -42,20 +42,33 @@ std::string RotationDegrees::toString() const bool RotationDegrees::tryParse(std::string_view text, RotationDegrees &out) { - Decimal v; - if (!Decimal::tryParse(text, v)) + ValueParseOutcome outcome = ValueParseOutcome::valid; + RotationDegrees parsed = parse(text, outcome); + if (outcome == ValueParseOutcome::invalid) { return false; } - out = RotationDegrees{std::move(v)}; + out = std::move(parsed); return true; } RotationDegrees RotationDegrees::parse(std::string_view text) { - RotationDegrees v; - tryParse(text, v); - return v; + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +RotationDegrees RotationDegrees::parse(std::string_view text, ValueParseOutcome &outcome) +{ + Decimal v; + if (!Decimal::tryParse(text, v)) + { + outcome = ValueParseOutcome::invalid; + return RotationDegrees{}; + } + RotationDegrees out{v}; + outcome = out.value() == v ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; } } // namespace mx::core diff --git a/src/private/mx/core/generated/RotationDegrees.h b/src/private/mx/core/generated/RotationDegrees.h index 224c98e60..bd4485c63 100644 --- a/src/private/mx/core/generated/RotationDegrees.h +++ b/src/private/mx/core/generated/RotationDegrees.h @@ -3,6 +3,7 @@ #pragma once #include "mx/core/Decimal.h" +#include "mx/core/Lexical.h" #include #include @@ -38,6 +39,9 @@ class RotationDegrees final /// Lenient: non-numeric text yields the clamped zero. static RotationDegrees parse(std::string_view text); + /// Lenient, and says whether the text was non-numeric or clamped. + static RotationDegrees parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const RotationDegrees &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Scaling.cpp b/src/private/mx/core/generated/Scaling.cpp index 22fa1d682..31428e416 100644 --- a/src/private/mx/core/generated/Scaling.cpp +++ b/src/private/mx/core/generated/Scaling.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Scaling.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void Scaling::setTenths(Tenths value) } Scaling parseScaling(pugi::xml_node el) +{ + return parseScaling(el, ParseContext{}); +} + +Scaling parseScaling(pugi::xml_node el, const ParseContext &context) { Scaling out; for (pugi::xml_attribute a : el.attributes()) @@ -42,16 +48,21 @@ Scaling parseScaling(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseScalingContent(out, el); + parseScalingContent(out, el, context); return out; } void parseScalingContent(Scaling &out, pugi::xml_node el) +{ + parseScalingContent(out, el, ParseContext{}); +} + +void parseScalingContent(Scaling &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "millimeters")) { - out.setMillimeters(Millimeters::parse(childText(cursor))); + out.setMillimeters(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -60,7 +71,7 @@ void parseScalingContent(Scaling &out, pugi::xml_node el) } if (cursorIs(cursor, "tenths")) { - out.setTenths(Tenths::parse(childText(cursor))); + out.setTenths(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else diff --git a/src/private/mx/core/generated/Scaling.h b/src/private/mx/core/generated/Scaling.h index 851a2aa8b..cea1f27a0 100644 --- a/src/private/mx/core/generated/Scaling.h +++ b/src/private/mx/core/generated/Scaling.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Margins, page sizes, and distances are all measured in tenths to keep MusicXML data in a /// consistent coordinate system as much as possible. The translation to absolute units is done with /// the scaling type, which specifies how many millimeters are equal to how many tenths. For a staff @@ -41,8 +43,12 @@ class Scaling final Scaling parseScaling(pugi::xml_node el); +Scaling parseScaling(pugi::xml_node el, const ParseContext &context); + void parseScalingContent(Scaling &out, pugi::xml_node el); +void parseScalingContent(Scaling &out, pugi::xml_node el, const ParseContext &context); + void serializeScaling(const Scaling &v, pugi::xml_node parent, const char *tag); void serializeScalingContent(const Scaling &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Scordatura.cpp b/src/private/mx/core/generated/Scordatura.cpp index c8bd60b56..fac988b3b 100644 --- a/src/private/mx/core/generated/Scordatura.cpp +++ b/src/private/mx/core/generated/Scordatura.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Scordatura.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -36,6 +37,11 @@ void Scordatura::setAccord(OneOrMore value) } Scordatura parseScordatura(pugi::xml_node el) +{ + return parseScordatura(el, ParseContext{}); +} + +Scordatura parseScordatura(pugi::xml_node el, const ParseContext &context) { Scordatura out; for (pugi::xml_attribute a : el.attributes()) @@ -54,22 +60,27 @@ Scordatura parseScordatura(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseScordaturaContent(out, el); + parseScordaturaContent(out, el, context); return out; } void parseScordaturaContent(Scordatura &out, pugi::xml_node el) +{ + parseScordaturaContent(out, el, ParseContext{}); +} + +void parseScordaturaContent(Scordatura &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (!cursorIs(cursor, "accord")) { throwMissingOrMisplaced(el, cursor, "accord"); } - out.setAccord(OneOrMore{parseAccord(cursor)}); + out.setAccord(OneOrMore{parseAccord(cursor, context)}); cursor = nextElement(cursor); while (cursorIs(cursor, "accord")) { - out.addAccord(parseAccord(cursor)); + out.addAccord(parseAccord(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/Scordatura.h b/src/private/mx/core/generated/Scordatura.h index 86b30fca0..17f09cecb 100644 --- a/src/private/mx/core/generated/Scordatura.h +++ b/src/private/mx/core/generated/Scordatura.h @@ -20,6 +20,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Scordatura string tunings are represented by a series of accord elements, similar to the /// staff-tuning elements. Strings are numbered from high to low. /// Content fields mirror the schema grammar in declaration order; the @@ -41,8 +43,12 @@ class Scordatura final Scordatura parseScordatura(pugi::xml_node el); +Scordatura parseScordatura(pugi::xml_node el, const ParseContext &context); + void parseScordaturaContent(Scordatura &out, pugi::xml_node el); +void parseScordaturaContent(Scordatura &out, pugi::xml_node el, const ParseContext &context); + void serializeScordatura(const Scordatura &v, pugi::xml_node parent, const char *tag); void serializeScordaturaContent(const Scordatura &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/ScoreHeaderGroup.cpp b/src/private/mx/core/generated/ScoreHeaderGroup.cpp index ab7f5cca6..244099846 100644 --- a/src/private/mx/core/generated/ScoreHeaderGroup.cpp +++ b/src/private/mx/core/generated/ScoreHeaderGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/ScoreHeaderGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -86,11 +87,16 @@ void ScoreHeaderGroup::setPartList(PartList value) } ScoreHeaderGroup parseScoreHeaderGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseScoreHeaderGroup(el, cursor, ParseContext{}); +} + +ScoreHeaderGroup parseScoreHeaderGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { ScoreHeaderGroup out; if (cursorIs(cursor, "work")) { - out.setWork(parseWork(cursor)); + out.setWork(parseWork(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "movement-number")) @@ -105,22 +111,22 @@ ScoreHeaderGroup parseScoreHeaderGroup(pugi::xml_node el, pugi::xml_node &cursor } if (cursorIs(cursor, "identification")) { - out.setIdentification(parseIdentification(cursor)); + out.setIdentification(parseIdentification(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "defaults")) { - out.setDefaults(parseDefaults(cursor)); + out.setDefaults(parseDefaults(cursor, context)); cursor = nextElement(cursor); } while (cursorIs(cursor, "credit")) { - out.addCredit(parseCredit(cursor)); + out.addCredit(parseCredit(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "part-list")) { - out.setPartList(parsePartList(cursor)); + out.setPartList(parsePartList(cursor, context)); cursor = nextElement(cursor); } else diff --git a/src/private/mx/core/generated/ScoreHeaderGroup.h b/src/private/mx/core/generated/ScoreHeaderGroup.h index ec055eac9..15a405274 100644 --- a/src/private/mx/core/generated/ScoreHeaderGroup.h +++ b/src/private/mx/core/generated/ScoreHeaderGroup.h @@ -21,6 +21,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The score-header group contains basic score metadata about the work and movement, score-wide /// defaults for layout and fonts, credits that appear on the first or following pages, and the part /// list. @@ -60,6 +62,8 @@ class ScoreHeaderGroup final /// is the enclosing element, for error paths. ScoreHeaderGroup parseScoreHeaderGroup(pugi::xml_node el, pugi::xml_node &cursor); +ScoreHeaderGroup parseScoreHeaderGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeScoreHeaderGroup(const ScoreHeaderGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/ScoreInstrument.cpp b/src/private/mx/core/generated/ScoreInstrument.cpp index 8b806ccbc..3e0630ae1 100644 --- a/src/private/mx/core/generated/ScoreInstrument.cpp +++ b/src/private/mx/core/generated/ScoreInstrument.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/ScoreInstrument.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -51,6 +52,11 @@ void ScoreInstrument::setVirtualInstrumentData(VirtualInstrumentDataGroup value) } ScoreInstrument parseScoreInstrument(pugi::xml_node el) +{ + return parseScoreInstrument(el, ParseContext{}); +} + +ScoreInstrument parseScoreInstrument(pugi::xml_node el, const ParseContext &context) { ScoreInstrument out; bool seen_id = false; @@ -75,11 +81,16 @@ ScoreInstrument parseScoreInstrument(pugi::xml_node el) { throwMissingAttribute(el, "id"); } - parseScoreInstrumentContent(out, el); + parseScoreInstrumentContent(out, el, context); return out; } void parseScoreInstrumentContent(ScoreInstrument &out, pugi::xml_node el) +{ + parseScoreInstrumentContent(out, el, ParseContext{}); +} + +void parseScoreInstrumentContent(ScoreInstrument &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "instrument-name")) @@ -99,7 +110,7 @@ void parseScoreInstrumentContent(ScoreInstrument &out, pugi::xml_node el) if (cursor && (cursorIs(cursor, "instrument-sound") || cursorIs(cursor, "solo") || cursorIs(cursor, "ensemble") || cursorIs(cursor, "virtual-instrument"))) { - out.setVirtualInstrumentData(parseVirtualInstrumentDataGroup(el, cursor)); + out.setVirtualInstrumentData(parseVirtualInstrumentDataGroup(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/ScoreInstrument.h b/src/private/mx/core/generated/ScoreInstrument.h index c99512201..11bee93b7 100644 --- a/src/private/mx/core/generated/ScoreInstrument.h +++ b/src/private/mx/core/generated/ScoreInstrument.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The score-instrument type represents a single instrument within a score-part. As with the /// score-part type, each score-instrument has a required ID attribute, a name, and an optional /// abbreviation. A score-instrument type is also required if the score specifies MIDI 1.0 channels, @@ -51,8 +53,12 @@ class ScoreInstrument final ScoreInstrument parseScoreInstrument(pugi::xml_node el); +ScoreInstrument parseScoreInstrument(pugi::xml_node el, const ParseContext &context); + void parseScoreInstrumentContent(ScoreInstrument &out, pugi::xml_node el); +void parseScoreInstrumentContent(ScoreInstrument &out, pugi::xml_node el, const ParseContext &context); + void serializeScoreInstrument(const ScoreInstrument &v, pugi::xml_node parent, const char *tag); void serializeScoreInstrumentContent(const ScoreInstrument &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/ScorePart.cpp b/src/private/mx/core/generated/ScorePart.cpp index e538e9811..0107e4537 100644 --- a/src/private/mx/core/generated/ScorePart.cpp +++ b/src/private/mx/core/generated/ScorePart.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/ScorePart.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -146,6 +147,11 @@ void ScorePart::setMIDIGroup(std::vector value) } ScorePart parseScorePart(pugi::xml_node el) +{ + return parseScorePart(el, ParseContext{}); +} + +ScorePart parseScorePart(pugi::xml_node el, const ParseContext &context) { ScorePart out; bool seen_id = false; @@ -170,26 +176,31 @@ ScorePart parseScorePart(pugi::xml_node el) { throwMissingAttribute(el, "id"); } - parseScorePartContent(out, el); + parseScorePartContent(out, el, context); return out; } void parseScorePartContent(ScorePart &out, pugi::xml_node el) +{ + parseScorePartContent(out, el, ParseContext{}); +} + +void parseScorePartContent(ScorePart &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "identification")) { - out.setIdentification(parseIdentification(cursor)); + out.setIdentification(parseIdentification(cursor, context)); cursor = nextElement(cursor); } while (cursorIs(cursor, "part-link")) { - out.addPartLink(parsePartLink(cursor)); + out.addPartLink(parsePartLink(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "part-name")) { - out.setPartName(parsePartName(cursor)); + out.setPartName(parsePartName(cursor, context)); cursor = nextElement(cursor); } else @@ -198,17 +209,17 @@ void parseScorePartContent(ScorePart &out, pugi::xml_node el) } if (cursorIs(cursor, "part-name-display")) { - out.setPartNameDisplay(parseNameDisplay(cursor)); + out.setPartNameDisplay(parseNameDisplay(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "part-abbreviation")) { - out.setPartAbbreviation(parsePartName(cursor)); + out.setPartAbbreviation(parsePartName(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "part-abbreviation-display")) { - out.setPartAbbreviationDisplay(parseNameDisplay(cursor)); + out.setPartAbbreviationDisplay(parseNameDisplay(cursor, context)); cursor = nextElement(cursor); } while (cursorIs(cursor, "group")) @@ -218,17 +229,17 @@ void parseScorePartContent(ScorePart &out, pugi::xml_node el) } while (cursorIs(cursor, "score-instrument")) { - out.addScoreInstrument(parseScoreInstrument(cursor)); + out.addScoreInstrument(parseScoreInstrument(cursor, context)); cursor = nextElement(cursor); } while (cursorIs(cursor, "player")) { - out.addPlayer(parsePlayer(cursor)); + out.addPlayer(parsePlayer(cursor, context)); cursor = nextElement(cursor); } while (cursor && (cursorIs(cursor, "midi-device") || cursorIs(cursor, "midi-instrument"))) { - out.addMIDIGroup(parseScorePartMIDIGroup(el, cursor)); + out.addMIDIGroup(parseScorePartMIDIGroup(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/ScorePart.h b/src/private/mx/core/generated/ScorePart.h index f4ec1e793..ee6d3796e 100644 --- a/src/private/mx/core/generated/ScorePart.h +++ b/src/private/mx/core/generated/ScorePart.h @@ -25,6 +25,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The score-part type collects part-wide information for each part in a score. Often, each MusicXML /// part corresponds to a track in a Standard MIDI Format 1 file. In this case, the midi-device /// element is used to make a MIDI device or port assignment for the given track or specific MIDI @@ -80,8 +82,12 @@ class ScorePart final ScorePart parseScorePart(pugi::xml_node el); +ScorePart parseScorePart(pugi::xml_node el, const ParseContext &context); + void parseScorePartContent(ScorePart &out, pugi::xml_node el); +void parseScorePartContent(ScorePart &out, pugi::xml_node el, const ParseContext &context); + void serializeScorePart(const ScorePart &v, pugi::xml_node parent, const char *tag); void serializeScorePartContent(const ScorePart &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/ScorePartMIDIGroup.cpp b/src/private/mx/core/generated/ScorePartMIDIGroup.cpp index ff58619c2..963afab40 100644 --- a/src/private/mx/core/generated/ScorePartMIDIGroup.cpp +++ b/src/private/mx/core/generated/ScorePartMIDIGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/ScorePartMIDIGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,16 +32,21 @@ void ScorePartMIDIGroup::setMIDIInstrument(std::optional value) } ScorePartMIDIGroup parseScorePartMIDIGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseScorePartMIDIGroup(el, cursor, ParseContext{}); +} + +ScorePartMIDIGroup parseScorePartMIDIGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { ScorePartMIDIGroup out; if (cursorIs(cursor, "midi-device")) { - out.setMIDIDevice(parseMIDIDevice(cursor)); + out.setMIDIDevice(parseMIDIDevice(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "midi-instrument")) { - out.setMIDIInstrument(parseMIDIInstrument(cursor)); + out.setMIDIInstrument(parseMIDIInstrument(cursor, context)); cursor = nextElement(cursor); } return out; diff --git a/src/private/mx/core/generated/ScorePartMIDIGroup.h b/src/private/mx/core/generated/ScorePartMIDIGroup.h index 4f1f512e9..2c7ff73e8 100644 --- a/src/private/mx/core/generated/ScorePartMIDIGroup.h +++ b/src/private/mx/core/generated/ScorePartMIDIGroup.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A shared content group (synthesized from an anonymous /// particle of the schema): transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -39,6 +41,8 @@ class ScorePartMIDIGroup final /// is the enclosing element, for error paths. ScorePartMIDIGroup parseScorePartMIDIGroup(pugi::xml_node el, pugi::xml_node &cursor); +ScorePartMIDIGroup parseScorePartMIDIGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeScorePartMIDIGroup(const ScorePartMIDIGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/ScorePartwise.cpp b/src/private/mx/core/generated/ScorePartwise.cpp index c13b023f7..c16af5fc9 100644 --- a/src/private/mx/core/generated/ScorePartwise.cpp +++ b/src/private/mx/core/generated/ScorePartwise.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/ScorePartwise.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -46,6 +47,11 @@ void ScorePartwise::setPart(OneOrMore value) } ScorePartwise parseScorePartwise(pugi::xml_node el) +{ + return parseScorePartwise(el, ParseContext{}); +} + +ScorePartwise parseScorePartwise(pugi::xml_node el, const ParseContext &context) { ScorePartwise out; for (pugi::xml_attribute a : el.attributes()) @@ -64,18 +70,23 @@ ScorePartwise parseScorePartwise(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseScorePartwiseContent(out, el); + parseScorePartwiseContent(out, el, context); return out; } void parseScorePartwiseContent(ScorePartwise &out, pugi::xml_node el) +{ + parseScorePartwiseContent(out, el, ParseContext{}); +} + +void parseScorePartwiseContent(ScorePartwise &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "work") || cursorIs(cursor, "movement-number") || cursorIs(cursor, "movement-title") || cursorIs(cursor, "identification") || cursorIs(cursor, "defaults") || cursorIs(cursor, "credit") || cursorIs(cursor, "part-list"))) { - out.setScoreHeader(parseScoreHeaderGroup(el, cursor)); + out.setScoreHeader(parseScoreHeaderGroup(el, cursor, context)); } else { @@ -85,11 +96,11 @@ void parseScorePartwiseContent(ScorePartwise &out, pugi::xml_node el) { throwMissingOrMisplaced(el, cursor, "part"); } - out.setPart(OneOrMore{parsePartwisePart(cursor)}); + out.setPart(OneOrMore{parsePartwisePart(cursor, context)}); cursor = nextElement(cursor); while (cursorIs(cursor, "part")) { - out.addPart(parsePartwisePart(cursor)); + out.addPart(parsePartwisePart(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/ScorePartwise.h b/src/private/mx/core/generated/ScorePartwise.h index f88a481e4..b3bb9002e 100644 --- a/src/private/mx/core/generated/ScorePartwise.h +++ b/src/private/mx/core/generated/ScorePartwise.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Content fields mirror the schema grammar in declaration order; the /// serializer walks them, so a wrong order is unrepresentable (plan ยง2.3). class ScorePartwise final @@ -41,8 +43,12 @@ class ScorePartwise final ScorePartwise parseScorePartwise(pugi::xml_node el); +ScorePartwise parseScorePartwise(pugi::xml_node el, const ParseContext &context); + void parseScorePartwiseContent(ScorePartwise &out, pugi::xml_node el); +void parseScorePartwiseContent(ScorePartwise &out, pugi::xml_node el, const ParseContext &context); + void serializeScorePartwise(const ScorePartwise &v, pugi::xml_node parent, const char *tag); void serializeScorePartwiseContent(const ScorePartwise &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/ScoreTimewise.cpp b/src/private/mx/core/generated/ScoreTimewise.cpp index 2447a3f01..feee89a52 100644 --- a/src/private/mx/core/generated/ScoreTimewise.cpp +++ b/src/private/mx/core/generated/ScoreTimewise.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/ScoreTimewise.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -46,6 +47,11 @@ void ScoreTimewise::setMeasure(OneOrMore value) } ScoreTimewise parseScoreTimewise(pugi::xml_node el) +{ + return parseScoreTimewise(el, ParseContext{}); +} + +ScoreTimewise parseScoreTimewise(pugi::xml_node el, const ParseContext &context) { ScoreTimewise out; for (pugi::xml_attribute a : el.attributes()) @@ -64,18 +70,23 @@ ScoreTimewise parseScoreTimewise(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseScoreTimewiseContent(out, el); + parseScoreTimewiseContent(out, el, context); return out; } void parseScoreTimewiseContent(ScoreTimewise &out, pugi::xml_node el) +{ + parseScoreTimewiseContent(out, el, ParseContext{}); +} + +void parseScoreTimewiseContent(ScoreTimewise &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "work") || cursorIs(cursor, "movement-number") || cursorIs(cursor, "movement-title") || cursorIs(cursor, "identification") || cursorIs(cursor, "defaults") || cursorIs(cursor, "credit") || cursorIs(cursor, "part-list"))) { - out.setScoreHeader(parseScoreHeaderGroup(el, cursor)); + out.setScoreHeader(parseScoreHeaderGroup(el, cursor, context)); } else { @@ -85,11 +96,11 @@ void parseScoreTimewiseContent(ScoreTimewise &out, pugi::xml_node el) { throwMissingOrMisplaced(el, cursor, "measure"); } - out.setMeasure(OneOrMore{parseTimewiseMeasure(cursor)}); + out.setMeasure(OneOrMore{parseTimewiseMeasure(cursor, context)}); cursor = nextElement(cursor); while (cursorIs(cursor, "measure")) { - out.addMeasure(parseTimewiseMeasure(cursor)); + out.addMeasure(parseTimewiseMeasure(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/ScoreTimewise.h b/src/private/mx/core/generated/ScoreTimewise.h index c0d0b9fe8..13936241d 100644 --- a/src/private/mx/core/generated/ScoreTimewise.h +++ b/src/private/mx/core/generated/ScoreTimewise.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Content fields mirror the schema grammar in declaration order; the /// serializer walks them, so a wrong order is unrepresentable (plan ยง2.3). class ScoreTimewise final @@ -41,8 +43,12 @@ class ScoreTimewise final ScoreTimewise parseScoreTimewise(pugi::xml_node el); +ScoreTimewise parseScoreTimewise(pugi::xml_node el, const ParseContext &context); + void parseScoreTimewiseContent(ScoreTimewise &out, pugi::xml_node el); +void parseScoreTimewiseContent(ScoreTimewise &out, pugi::xml_node el, const ParseContext &context); + void serializeScoreTimewise(const ScoreTimewise &v, pugi::xml_node parent, const char *tag); void serializeScoreTimewiseContent(const ScoreTimewise &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Segno.cpp b/src/private/mx/core/generated/Segno.cpp index 2d25e3058..be9519efb 100644 --- a/src/private/mx/core/generated/Segno.cpp +++ b/src/private/mx/core/generated/Segno.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Segno.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -141,6 +142,11 @@ void Segno::setID(std::optional value) } Segno parseSegno(pugi::xml_node el) +{ + return parseSegno(el, ParseContext{}); +} + +Segno parseSegno(pugi::xml_node el, const ParseContext &context) { Segno out; for (pugi::xml_attribute a : el.attributes()) @@ -152,51 +158,51 @@ Segno parseSegno(pugi::xml_node el) } if (aname == "smufl") { - out.setSmufl(SmuflSegnoGlyphName::parse(a.value())); + out.setSmufl(parseValue(a.value(), context, el, "smufl")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "halign") { - out.setHalign(LeftCenterRight::parse(a.value())); + out.setHalign(parseValue(a.value(), context, el, "halign")); } else if (aname == "valign") { - out.setValign(Valign::parse(a.value())); + out.setValign(parseValue(a.value(), context, el, "valign")); } else if (aname == "id") { @@ -207,13 +213,19 @@ Segno parseSegno(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseSegnoContent(out, el); + parseSegnoContent(out, el, context); return out; } void parseSegnoContent(Segno &out, pugi::xml_node el) +{ + parseSegnoContent(out, el, ParseContext{}); +} + +void parseSegnoContent(Segno &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Segno.h b/src/private/mx/core/generated/Segno.h index fdb31d8b1..179ed4502 100644 --- a/src/private/mx/core/generated/Segno.h +++ b/src/private/mx/core/generated/Segno.h @@ -25,6 +25,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The segno type is the visual indicator of a segno sign. The exact glyph can be specified with the /// smufl attribute. A sound element is also needed to guide playback applications reliably. class Segno final @@ -76,8 +78,12 @@ class Segno final Segno parseSegno(pugi::xml_node el); +Segno parseSegno(pugi::xml_node el, const ParseContext &context); + void parseSegnoContent(Segno &out, pugi::xml_node el); +void parseSegnoContent(Segno &out, pugi::xml_node el, const ParseContext &context); + void serializeSegno(const Segno &v, pugi::xml_node parent, const char *tag); void serializeSegnoContent(const Segno &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/SemiPitched.cpp b/src/private/mx/core/generated/SemiPitched.cpp index 2a71be7aa..7f94173da 100644 --- a/src/private/mx/core/generated/SemiPitched.cpp +++ b/src/private/mx/core/generated/SemiPitched.cpp @@ -61,9 +61,15 @@ bool SemiPitched::tryParse(std::string_view text, SemiPitched &out) noexcept } SemiPitched SemiPitched::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +SemiPitched SemiPitched::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { SemiPitched v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/SemiPitched.h b/src/private/mx/core/generated/SemiPitched.h index ceb8ffdfc..731ae9f3f 100644 --- a/src/private/mx/core/generated/SemiPitched.h +++ b/src/private/mx/core/generated/SemiPitched.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -48,6 +50,9 @@ class SemiPitched final /// (the import leniency policy; never produces an invalid value). static SemiPitched parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static SemiPitched parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const SemiPitched &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Semitones.cpp b/src/private/mx/core/generated/Semitones.cpp index bb24a41af..1ed8c5024 100644 --- a/src/private/mx/core/generated/Semitones.cpp +++ b/src/private/mx/core/generated/Semitones.cpp @@ -34,20 +34,33 @@ std::string Semitones::toString() const bool Semitones::tryParse(std::string_view text, Semitones &out) { - Decimal v; - if (!Decimal::tryParse(text, v)) + ValueParseOutcome outcome = ValueParseOutcome::valid; + Semitones parsed = parse(text, outcome); + if (outcome == ValueParseOutcome::invalid) { return false; } - out = Semitones{std::move(v)}; + out = std::move(parsed); return true; } Semitones Semitones::parse(std::string_view text) { - Semitones v; - tryParse(text, v); - return v; + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +Semitones Semitones::parse(std::string_view text, ValueParseOutcome &outcome) +{ + Decimal v; + if (!Decimal::tryParse(text, v)) + { + outcome = ValueParseOutcome::invalid; + return Semitones{}; + } + Semitones out{v}; + outcome = out.value() == v ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; } } // namespace mx::core diff --git a/src/private/mx/core/generated/Semitones.h b/src/private/mx/core/generated/Semitones.h index d09d8a45c..e109fdd3d 100644 --- a/src/private/mx/core/generated/Semitones.h +++ b/src/private/mx/core/generated/Semitones.h @@ -3,6 +3,7 @@ #pragma once #include "mx/core/Decimal.h" +#include "mx/core/Lexical.h" #include #include @@ -39,6 +40,9 @@ class Semitones final /// Lenient: non-numeric text yields the clamped zero. static Semitones parse(std::string_view text); + /// Lenient, and says whether the text was non-numeric or clamped. + static Semitones parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const Semitones &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/ShowFrets.cpp b/src/private/mx/core/generated/ShowFrets.cpp index 73771b48d..ae7d7e596 100644 --- a/src/private/mx/core/generated/ShowFrets.cpp +++ b/src/private/mx/core/generated/ShowFrets.cpp @@ -42,9 +42,15 @@ bool ShowFrets::tryParse(std::string_view text, ShowFrets &out) noexcept } ShowFrets ShowFrets::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +ShowFrets ShowFrets::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { ShowFrets v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/ShowFrets.h b/src/private/mx/core/generated/ShowFrets.h index 55e38ee9f..f148609df 100644 --- a/src/private/mx/core/generated/ShowFrets.h +++ b/src/private/mx/core/generated/ShowFrets.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -41,6 +43,9 @@ class ShowFrets final /// (the import leniency policy; never produces an invalid value). static ShowFrets parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static ShowFrets parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const ShowFrets &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/ShowTuplet.cpp b/src/private/mx/core/generated/ShowTuplet.cpp index 489a7d07b..a6793087e 100644 --- a/src/private/mx/core/generated/ShowTuplet.cpp +++ b/src/private/mx/core/generated/ShowTuplet.cpp @@ -48,9 +48,15 @@ bool ShowTuplet::tryParse(std::string_view text, ShowTuplet &out) noexcept } ShowTuplet ShowTuplet::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +ShowTuplet ShowTuplet::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { ShowTuplet v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/ShowTuplet.h b/src/private/mx/core/generated/ShowTuplet.h index 5b132e7c8..1b56b13b6 100644 --- a/src/private/mx/core/generated/ShowTuplet.h +++ b/src/private/mx/core/generated/ShowTuplet.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -43,6 +45,9 @@ class ShowTuplet final /// (the import leniency policy; never produces an invalid value). static ShowTuplet parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static ShowTuplet parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const ShowTuplet &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Slash.cpp b/src/private/mx/core/generated/Slash.cpp index d8c62afd1..51b43e82c 100644 --- a/src/private/mx/core/generated/Slash.cpp +++ b/src/private/mx/core/generated/Slash.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Slash.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -51,6 +52,11 @@ void Slash::setSlash(std::optional value) } Slash parseSlash(pugi::xml_node el) +{ + return parseSlash(el, ParseContext{}); +} + +Slash parseSlash(pugi::xml_node el, const ParseContext &context) { Slash out; bool seen_type = false; @@ -64,15 +70,15 @@ Slash parseSlash(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(StartStop::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "use-dots") { - out.setUseDots(YesNo::parse(a.value())); + out.setUseDots(parseValue(a.value(), context, el, "use-dots")); } else if (aname == "use-stems") { - out.setUseStems(YesNo::parse(a.value())); + out.setUseStems(parseValue(a.value(), context, el, "use-stems")); } else { @@ -83,16 +89,21 @@ Slash parseSlash(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseSlashContent(out, el); + parseSlashContent(out, el, context); return out; } void parseSlashContent(Slash &out, pugi::xml_node el) +{ + parseSlashContent(out, el, ParseContext{}); +} + +void parseSlashContent(Slash &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "slash-type") || cursorIs(cursor, "except-voice"))) { - out.setSlash(parseSlashGroup(el, cursor)); + out.setSlash(parseSlashGroup(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/Slash.h b/src/private/mx/core/generated/Slash.h index f52c2ca1b..32cb59911 100644 --- a/src/private/mx/core/generated/Slash.h +++ b/src/private/mx/core/generated/Slash.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The slash type is used to indicate that slash notation is to be used. If the slash is on every /// beat, use-stems is no (the default). To indicate rhythms but not pitches, use-stems is set to /// yes. The type attribute indicates whether this is the start or stop of a slash notation style. @@ -48,8 +50,12 @@ class Slash final Slash parseSlash(pugi::xml_node el); +Slash parseSlash(pugi::xml_node el, const ParseContext &context); + void parseSlashContent(Slash &out, pugi::xml_node el); +void parseSlashContent(Slash &out, pugi::xml_node el, const ParseContext &context); + void serializeSlash(const Slash &v, pugi::xml_node parent, const char *tag); void serializeSlashContent(const Slash &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/SlashGroup.cpp b/src/private/mx/core/generated/SlashGroup.cpp index c6386c09d..0618fcc56 100644 --- a/src/private/mx/core/generated/SlashGroup.cpp +++ b/src/private/mx/core/generated/SlashGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/SlashGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -36,11 +37,16 @@ void SlashGroup::setExceptVoice(std::vector value) } SlashGroup parseSlashGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseSlashGroup(el, cursor, ParseContext{}); +} + +SlashGroup parseSlashGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { SlashGroup out; if (cursor && (cursorIs(cursor, "slash-type"))) { - out.setGroup(parseSlashGroupGroup(el, cursor)); + out.setGroup(parseSlashGroupGroup(el, cursor, context)); } while (cursorIs(cursor, "except-voice")) { diff --git a/src/private/mx/core/generated/SlashGroup.h b/src/private/mx/core/generated/SlashGroup.h index 0cf878865..8ff186115 100644 --- a/src/private/mx/core/generated/SlashGroup.h +++ b/src/private/mx/core/generated/SlashGroup.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The slash group combines elements used for more complete specification of the slash and /// beat-repeat measure-style elements. They have the same values as the type and dot elements, and /// define what the beat is for the display of repetition marks. If not present, the beat is based on @@ -42,6 +44,8 @@ class SlashGroup final /// is the enclosing element, for error paths. SlashGroup parseSlashGroup(pugi::xml_node el, pugi::xml_node &cursor); +SlashGroup parseSlashGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeSlashGroup(const SlashGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/SlashGroupGroup.cpp b/src/private/mx/core/generated/SlashGroupGroup.cpp index 5b9b61f45..70a9b5ce0 100644 --- a/src/private/mx/core/generated/SlashGroupGroup.cpp +++ b/src/private/mx/core/generated/SlashGroupGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/SlashGroupGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -36,11 +37,16 @@ void SlashGroupGroup::setSlashDot(std::vector value) } SlashGroupGroup parseSlashGroupGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseSlashGroupGroup(el, cursor, ParseContext{}); +} + +SlashGroupGroup parseSlashGroupGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { SlashGroupGroup out; if (cursorIs(cursor, "slash-type")) { - out.setSlashType(NoteTypeValue::parse(childText(cursor))); + out.setSlashType(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -49,7 +55,7 @@ SlashGroupGroup parseSlashGroupGroup(pugi::xml_node el, pugi::xml_node &cursor) } while (cursorIs(cursor, "slash-dot")) { - out.addSlashDot(parseEmpty(cursor)); + out.addSlashDot(parseEmpty(cursor, context)); cursor = nextElement(cursor); } return out; diff --git a/src/private/mx/core/generated/SlashGroupGroup.h b/src/private/mx/core/generated/SlashGroupGroup.h index 91e7a9c08..120e98944 100644 --- a/src/private/mx/core/generated/SlashGroupGroup.h +++ b/src/private/mx/core/generated/SlashGroupGroup.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A shared content group (synthesized from an anonymous /// particle of the schema): transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -40,6 +42,8 @@ class SlashGroupGroup final /// is the enclosing element, for error paths. SlashGroupGroup parseSlashGroupGroup(pugi::xml_node el, pugi::xml_node &cursor); +SlashGroupGroup parseSlashGroupGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeSlashGroupGroup(const SlashGroupGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/Slide.cpp b/src/private/mx/core/generated/Slide.cpp index 1cddb4502..4dc5225ee 100644 --- a/src/private/mx/core/generated/Slide.cpp +++ b/src/private/mx/core/generated/Slide.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Slide.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -211,6 +212,11 @@ void Slide::setValue(std::string value) } Slide parseSlide(pugi::xml_node el) +{ + return parseSlide(el, ParseContext{}); +} + +Slide parseSlide(pugi::xml_node el, const ParseContext &context) { Slide out; bool seen_type = false; @@ -224,75 +230,75 @@ Slide parseSlide(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(StartStop::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "number") { - out.setNumber(NumberLevel::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else if (aname == "line-type") { - out.setLineType(LineType::parse(a.value())); + out.setLineType(parseValue(a.value(), context, el, "line-type")); } else if (aname == "dash-length") { - out.setDashLength(Tenths::parse(a.value())); + out.setDashLength(parseValue(a.value(), context, el, "dash-length")); } else if (aname == "space-length") { - out.setSpaceLength(Tenths::parse(a.value())); + out.setSpaceLength(parseValue(a.value(), context, el, "space-length")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "accelerate") { - out.setAccelerate(YesNo::parse(a.value())); + out.setAccelerate(parseValue(a.value(), context, el, "accelerate")); } else if (aname == "beats") { - out.setBeats(TrillBeats::parse(a.value())); + out.setBeats(parseValue(a.value(), context, el, "beats")); } else if (aname == "first-beat") { - out.setFirstBeat(Percent::parse(a.value())); + out.setFirstBeat(parseValue(a.value(), context, el, "first-beat")); } else if (aname == "last-beat") { - out.setLastBeat(Percent::parse(a.value())); + out.setLastBeat(parseValue(a.value(), context, el, "last-beat")); } else if (aname == "id") { @@ -307,11 +313,16 @@ Slide parseSlide(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseSlideContent(out, el); + parseSlideContent(out, el, context); return out; } void parseSlideContent(Slide &out, pugi::xml_node el) +{ + parseSlideContent(out, el, ParseContext{}); +} + +void parseSlideContent(Slide &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/Slide.h b/src/private/mx/core/generated/Slide.h index 5b83d8a37..78198164e 100644 --- a/src/private/mx/core/generated/Slide.h +++ b/src/private/mx/core/generated/Slide.h @@ -28,6 +28,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Glissando and slide types both indicate rapidly moving from one pitch to the other so that /// individual notes are not discerned. A slide is continuous between the two pitches and defaults to /// a solid line. The optional text for a is printed alongside the line. @@ -101,8 +103,12 @@ class Slide final Slide parseSlide(pugi::xml_node el); +Slide parseSlide(pugi::xml_node el, const ParseContext &context); + void parseSlideContent(Slide &out, pugi::xml_node el); +void parseSlideContent(Slide &out, pugi::xml_node el, const ParseContext &context); + void serializeSlide(const Slide &v, pugi::xml_node parent, const char *tag); void serializeSlideContent(const Slide &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Slur.cpp b/src/private/mx/core/generated/Slur.cpp index a35c9bf40..b5a5d6977 100644 --- a/src/private/mx/core/generated/Slur.cpp +++ b/src/private/mx/core/generated/Slur.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Slur.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -201,6 +202,11 @@ void Slur::setID(std::optional value) } Slur parseSlur(pugi::xml_node el) +{ + return parseSlur(el, ParseContext{}); +} + +Slur parseSlur(pugi::xml_node el, const ParseContext &context) { Slur out; bool seen_type = false; @@ -214,75 +220,75 @@ Slur parseSlur(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(StartStopContinue::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "number") { - out.setNumber(NumberLevel::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else if (aname == "line-type") { - out.setLineType(LineType::parse(a.value())); + out.setLineType(parseValue(a.value(), context, el, "line-type")); } else if (aname == "dash-length") { - out.setDashLength(Tenths::parse(a.value())); + out.setDashLength(parseValue(a.value(), context, el, "dash-length")); } else if (aname == "space-length") { - out.setSpaceLength(Tenths::parse(a.value())); + out.setSpaceLength(parseValue(a.value(), context, el, "space-length")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else if (aname == "orientation") { - out.setOrientation(OverUnder::parse(a.value())); + out.setOrientation(parseValue(a.value(), context, el, "orientation")); } else if (aname == "bezier-x") { - out.setBezierX(Tenths::parse(a.value())); + out.setBezierX(parseValue(a.value(), context, el, "bezier-x")); } else if (aname == "bezier-y") { - out.setBezierY(Tenths::parse(a.value())); + out.setBezierY(parseValue(a.value(), context, el, "bezier-y")); } else if (aname == "bezier-x2") { - out.setBezierX2(Tenths::parse(a.value())); + out.setBezierX2(parseValue(a.value(), context, el, "bezier-x2")); } else if (aname == "bezier-y2") { - out.setBezierY2(Tenths::parse(a.value())); + out.setBezierY2(parseValue(a.value(), context, el, "bezier-y2")); } else if (aname == "bezier-offset") { - out.setBezierOffset(Divisions::parse(a.value())); + out.setBezierOffset(parseValue(a.value(), context, el, "bezier-offset")); } else if (aname == "bezier-offset2") { - out.setBezierOffset2(Divisions::parse(a.value())); + out.setBezierOffset2(parseValue(a.value(), context, el, "bezier-offset2")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "id") { @@ -297,13 +303,19 @@ Slur parseSlur(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseSlurContent(out, el); + parseSlurContent(out, el, context); return out; } void parseSlurContent(Slur &out, pugi::xml_node el) +{ + parseSlurContent(out, el, ParseContext{}); +} + +void parseSlurContent(Slur &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Slur.h b/src/private/mx/core/generated/Slur.h index 6347c3778..10d22acec 100644 --- a/src/private/mx/core/generated/Slur.h +++ b/src/private/mx/core/generated/Slur.h @@ -24,6 +24,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Slur types are empty. Most slurs are represented with two elements: one with a start type, and /// one with a stop type. Slurs can add more elements using a continue type. This is typically used /// to specify the formatting of cross-system slurs, or to specify the shape of very complex slurs. @@ -94,8 +96,12 @@ class Slur final Slur parseSlur(pugi::xml_node el); +Slur parseSlur(pugi::xml_node el, const ParseContext &context); + void parseSlurContent(Slur &out, pugi::xml_node el); +void parseSlurContent(Slur &out, pugi::xml_node el, const ParseContext &context); + void serializeSlur(const Slur &v, pugi::xml_node parent, const char *tag); void serializeSlurContent(const Slur &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Sound.cpp b/src/private/mx/core/generated/Sound.cpp index ed1ec7ef5..3c7103c29 100644 --- a/src/private/mx/core/generated/Sound.cpp +++ b/src/private/mx/core/generated/Sound.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Sound.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -226,6 +227,11 @@ void Sound::setOffset(std::optional value) } Sound parseSound(pugi::xml_node el) +{ + return parseSound(el, ParseContext{}); +} + +Sound parseSound(pugi::xml_node el, const ParseContext &context) { Sound out; for (pugi::xml_attribute a : el.attributes()) @@ -237,15 +243,15 @@ Sound parseSound(pugi::xml_node el) } if (aname == "tempo") { - out.setTempo(NonNegativeDecimal::parse(a.value())); + out.setTempo(parseValue(a.value(), context, el, "tempo")); } else if (aname == "dynamics") { - out.setDynamics(NonNegativeDecimal::parse(a.value())); + out.setDynamics(parseValue(a.value(), context, el, "dynamics")); } else if (aname == "dacapo") { - out.setDacapo(YesNo::parse(a.value())); + out.setDacapo(parseValue(a.value(), context, el, "dacapo")); } else if (aname == "segno") { @@ -265,11 +271,11 @@ Sound parseSound(pugi::xml_node el) } else if (aname == "divisions") { - out.setDivisions(Divisions::parse(a.value())); + out.setDivisions(parseValue(a.value(), context, el, "divisions")); } else if (aname == "forward-repeat") { - out.setForwardRepeat(YesNo::parse(a.value())); + out.setForwardRepeat(parseValue(a.value(), context, el, "forward-repeat")); } else if (aname == "fine") { @@ -277,31 +283,31 @@ Sound parseSound(pugi::xml_node el) } else if (aname == "time-only") { - out.setTimeOnly(TimeOnly::parse(a.value())); + out.setTimeOnly(parseValue(a.value(), context, el, "time-only")); } else if (aname == "pizzicato") { - out.setPizzicato(YesNo::parse(a.value())); + out.setPizzicato(parseValue(a.value(), context, el, "pizzicato")); } else if (aname == "pan") { - out.setPan(RotationDegrees::parse(a.value())); + out.setPan(parseValue(a.value(), context, el, "pan")); } else if (aname == "elevation") { - out.setElevation(RotationDegrees::parse(a.value())); + out.setElevation(parseValue(a.value(), context, el, "elevation")); } else if (aname == "damper-pedal") { - out.setDamperPedal(YesNoNumber::parse(a.value())); + out.setDamperPedal(parseValue(a.value(), context, el, "damper-pedal")); } else if (aname == "soft-pedal") { - out.setSoftPedal(YesNoNumber::parse(a.value())); + out.setSoftPedal(parseValue(a.value(), context, el, "soft-pedal")); } else if (aname == "sostenuto-pedal") { - out.setSostenutoPedal(YesNoNumber::parse(a.value())); + out.setSostenutoPedal(parseValue(a.value(), context, el, "sostenuto-pedal")); } else if (aname == "id") { @@ -312,26 +318,31 @@ Sound parseSound(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseSoundContent(out, el); + parseSoundContent(out, el, context); return out; } void parseSoundContent(Sound &out, pugi::xml_node el) +{ + parseSoundContent(out, el, ParseContext{}); +} + +void parseSoundContent(Sound &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); while (cursor && (cursorIs(cursor, "instrument-change") || cursorIs(cursor, "midi-device") || cursorIs(cursor, "midi-instrument") || cursorIs(cursor, "play"))) { - out.addGroup(parseSoundGroup(el, cursor)); + out.addGroup(parseSoundGroup(el, cursor, context)); } if (cursorIs(cursor, "swing")) { - out.setSwing(parseSwing(cursor)); + out.setSwing(parseSwing(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "offset")) { - out.setOffset(parseOffset(cursor)); + out.setOffset(parseOffset(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/Sound.h b/src/private/mx/core/generated/Sound.h index 5aff35ba2..ee007c533 100644 --- a/src/private/mx/core/generated/Sound.h +++ b/src/private/mx/core/generated/Sound.h @@ -27,6 +27,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The sound element contains general playback parameters. They can stand alone within a /// part/measure, or be a component element within a direction. Tempo is expressed in quarter notes /// per minute. If 0, the sound-generating program should prompt the user at the time of compiling a @@ -141,8 +143,12 @@ class Sound final Sound parseSound(pugi::xml_node el); +Sound parseSound(pugi::xml_node el, const ParseContext &context); + void parseSoundContent(Sound &out, pugi::xml_node el); +void parseSoundContent(Sound &out, pugi::xml_node el, const ParseContext &context); + void serializeSound(const Sound &v, pugi::xml_node parent, const char *tag); void serializeSoundContent(const Sound &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/SoundGroup.cpp b/src/private/mx/core/generated/SoundGroup.cpp index 7e68a20d7..4af19a78f 100644 --- a/src/private/mx/core/generated/SoundGroup.cpp +++ b/src/private/mx/core/generated/SoundGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/SoundGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -51,26 +52,31 @@ void SoundGroup::setPlay(std::optional value) } SoundGroup parseSoundGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseSoundGroup(el, cursor, ParseContext{}); +} + +SoundGroup parseSoundGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { SoundGroup out; if (cursorIs(cursor, "instrument-change")) { - out.setInstrumentChange(parseInstrumentChange(cursor)); + out.setInstrumentChange(parseInstrumentChange(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "midi-device")) { - out.setMIDIDevice(parseMIDIDevice(cursor)); + out.setMIDIDevice(parseMIDIDevice(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "midi-instrument")) { - out.setMIDIInstrument(parseMIDIInstrument(cursor)); + out.setMIDIInstrument(parseMIDIInstrument(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "play")) { - out.setPlay(parsePlay(cursor)); + out.setPlay(parsePlay(cursor, context)); cursor = nextElement(cursor); } return out; diff --git a/src/private/mx/core/generated/SoundGroup.h b/src/private/mx/core/generated/SoundGroup.h index 33ed6860a..68a98a637 100644 --- a/src/private/mx/core/generated/SoundGroup.h +++ b/src/private/mx/core/generated/SoundGroup.h @@ -20,6 +20,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A shared content group (synthesized from an anonymous /// particle of the schema): transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -47,6 +49,8 @@ class SoundGroup final /// is the enclosing element, for error paths. SoundGroup parseSoundGroup(pugi::xml_node el, pugi::xml_node &cursor); +SoundGroup parseSoundGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeSoundGroup(const SoundGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/SoundID.cpp b/src/private/mx/core/generated/SoundID.cpp index 9bc2d2dda..5775e9138 100644 --- a/src/private/mx/core/generated/SoundID.cpp +++ b/src/private/mx/core/generated/SoundID.cpp @@ -5394,9 +5394,15 @@ bool SoundID::tryParse(std::string_view text, SoundID &out) noexcept } SoundID SoundID::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +SoundID SoundID::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { SoundID v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/SoundID.h b/src/private/mx/core/generated/SoundID.h index 6ccef581f..23b1cff14 100644 --- a/src/private/mx/core/generated/SoundID.h +++ b/src/private/mx/core/generated/SoundID.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -1825,6 +1827,9 @@ class SoundID final /// (the import leniency policy; never produces an invalid value). static SoundID parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static SoundID parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const SoundID &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/StaffDetails.cpp b/src/private/mx/core/generated/StaffDetails.cpp index 47dc1558f..6c4ac9b13 100644 --- a/src/private/mx/core/generated/StaffDetails.cpp +++ b/src/private/mx/core/generated/StaffDetails.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/StaffDetails.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -106,6 +107,11 @@ void StaffDetails::setStaffSize(std::optional value) } StaffDetails parseStaffDetails(pugi::xml_node el) +{ + return parseStaffDetails(el, ParseContext{}); +} + +StaffDetails parseStaffDetails(pugi::xml_node el, const ParseContext &context) { StaffDetails out; for (pugi::xml_attribute a : el.attributes()) @@ -117,54 +123,59 @@ StaffDetails parseStaffDetails(pugi::xml_node el) } if (aname == "number") { - out.setNumber(StaffNumber::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else if (aname == "show-frets") { - out.setShowFrets(ShowFrets::parse(a.value())); + out.setShowFrets(parseValue(a.value(), context, el, "show-frets")); } else if (aname == "print-object") { - out.setPrintObject(YesNo::parse(a.value())); + out.setPrintObject(parseValue(a.value(), context, el, "print-object")); } else if (aname == "print-spacing") { - out.setPrintSpacing(YesNo::parse(a.value())); + out.setPrintSpacing(parseValue(a.value(), context, el, "print-spacing")); } else { throwUnknownAttribute(el, a.name()); } } - parseStaffDetailsContent(out, el); + parseStaffDetailsContent(out, el, context); return out; } void parseStaffDetailsContent(StaffDetails &out, pugi::xml_node el) +{ + parseStaffDetailsContent(out, el, ParseContext{}); +} + +void parseStaffDetailsContent(StaffDetails &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "staff-type")) { - out.setStaffType(StaffType::parse(childText(cursor))); + out.setStaffType(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (cursor && (cursorIs(cursor, "staff-lines"))) { - out.setGroup(parseStaffDetailsGroup(el, cursor)); + out.setGroup(parseStaffDetailsGroup(el, cursor, context)); } while (cursorIs(cursor, "staff-tuning")) { - out.addStaffTuning(parseStaffTuning(cursor)); + out.addStaffTuning(parseStaffTuning(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "capo")) { - out.setCapo(parseInt(childText(cursor))); + out.setCapo(parseIntegerValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (cursorIs(cursor, "staff-size")) { - out.setStaffSize(parseStaffSize(cursor)); + out.setStaffSize(parseStaffSize(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/StaffDetails.h b/src/private/mx/core/generated/StaffDetails.h index dc2fcd09e..f5015866e 100644 --- a/src/private/mx/core/generated/StaffDetails.h +++ b/src/private/mx/core/generated/StaffDetails.h @@ -23,6 +23,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The staff-details element is used to indicate different types of staves. The optional number /// attribute specifies the staff number from top to bottom on the system, as with clef. The /// print-object attribute is used to indicate when a staff is not printed in a part, usually in @@ -69,8 +71,12 @@ class StaffDetails final StaffDetails parseStaffDetails(pugi::xml_node el); +StaffDetails parseStaffDetails(pugi::xml_node el, const ParseContext &context); + void parseStaffDetailsContent(StaffDetails &out, pugi::xml_node el); +void parseStaffDetailsContent(StaffDetails &out, pugi::xml_node el, const ParseContext &context); + void serializeStaffDetails(const StaffDetails &v, pugi::xml_node parent, const char *tag); void serializeStaffDetailsContent(const StaffDetails &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/StaffDetailsGroup.cpp b/src/private/mx/core/generated/StaffDetailsGroup.cpp index 12a0d8117..6cef32925 100644 --- a/src/private/mx/core/generated/StaffDetailsGroup.cpp +++ b/src/private/mx/core/generated/StaffDetailsGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/StaffDetailsGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -36,11 +37,16 @@ void StaffDetailsGroup::setLineDetail(std::vector value) } StaffDetailsGroup parseStaffDetailsGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseStaffDetailsGroup(el, cursor, ParseContext{}); +} + +StaffDetailsGroup parseStaffDetailsGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { StaffDetailsGroup out; if (cursorIs(cursor, "staff-lines")) { - out.setStaffLines(parseInt(childText(cursor))); + out.setStaffLines(parseIntegerValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -49,7 +55,7 @@ StaffDetailsGroup parseStaffDetailsGroup(pugi::xml_node el, pugi::xml_node &curs } while (cursorIs(cursor, "line-detail")) { - out.addLineDetail(parseLineDetail(cursor)); + out.addLineDetail(parseLineDetail(cursor, context)); cursor = nextElement(cursor); } return out; diff --git a/src/private/mx/core/generated/StaffDetailsGroup.h b/src/private/mx/core/generated/StaffDetailsGroup.h index 4229dca35..a354bc89c 100644 --- a/src/private/mx/core/generated/StaffDetailsGroup.h +++ b/src/private/mx/core/generated/StaffDetailsGroup.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A shared content group (synthesized from an anonymous /// particle of the schema): transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -39,6 +41,8 @@ class StaffDetailsGroup final /// is the enclosing element, for error paths. StaffDetailsGroup parseStaffDetailsGroup(pugi::xml_node el, pugi::xml_node &cursor); +StaffDetailsGroup parseStaffDetailsGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeStaffDetailsGroup(const StaffDetailsGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/StaffDivide.cpp b/src/private/mx/core/generated/StaffDivide.cpp index cba472496..3cd1ef034 100644 --- a/src/private/mx/core/generated/StaffDivide.cpp +++ b/src/private/mx/core/generated/StaffDivide.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/StaffDivide.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -141,6 +142,11 @@ void StaffDivide::setID(std::optional value) } StaffDivide parseStaffDivide(pugi::xml_node el) +{ + return parseStaffDivide(el, ParseContext{}); +} + +StaffDivide parseStaffDivide(pugi::xml_node el, const ParseContext &context) { StaffDivide out; bool seen_type = false; @@ -154,51 +160,51 @@ StaffDivide parseStaffDivide(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(StaffDivideSymbol::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "halign") { - out.setHalign(LeftCenterRight::parse(a.value())); + out.setHalign(parseValue(a.value(), context, el, "halign")); } else if (aname == "valign") { - out.setValign(Valign::parse(a.value())); + out.setValign(parseValue(a.value(), context, el, "valign")); } else if (aname == "id") { @@ -213,13 +219,19 @@ StaffDivide parseStaffDivide(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseStaffDivideContent(out, el); + parseStaffDivideContent(out, el, context); return out; } void parseStaffDivideContent(StaffDivide &out, pugi::xml_node el) +{ + parseStaffDivideContent(out, el, ParseContext{}); +} + +void parseStaffDivideContent(StaffDivide &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/StaffDivide.h b/src/private/mx/core/generated/StaffDivide.h index c851b5122..442f3052f 100644 --- a/src/private/mx/core/generated/StaffDivide.h +++ b/src/private/mx/core/generated/StaffDivide.h @@ -25,6 +25,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The staff-divide element represents the staff division arrow symbols found at SMuFL code points /// U+E00B, U+E00C, and U+E00D. class StaffDivide final @@ -76,8 +78,12 @@ class StaffDivide final StaffDivide parseStaffDivide(pugi::xml_node el); +StaffDivide parseStaffDivide(pugi::xml_node el, const ParseContext &context); + void parseStaffDivideContent(StaffDivide &out, pugi::xml_node el); +void parseStaffDivideContent(StaffDivide &out, pugi::xml_node el, const ParseContext &context); + void serializeStaffDivide(const StaffDivide &v, pugi::xml_node parent, const char *tag); void serializeStaffDivideContent(const StaffDivide &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/StaffDivideSymbol.cpp b/src/private/mx/core/generated/StaffDivideSymbol.cpp index 89ca86e9d..7fb9e2bc8 100644 --- a/src/private/mx/core/generated/StaffDivideSymbol.cpp +++ b/src/private/mx/core/generated/StaffDivideSymbol.cpp @@ -48,9 +48,15 @@ bool StaffDivideSymbol::tryParse(std::string_view text, StaffDivideSymbol &out) } StaffDivideSymbol StaffDivideSymbol::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +StaffDivideSymbol StaffDivideSymbol::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { StaffDivideSymbol v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/StaffDivideSymbol.h b/src/private/mx/core/generated/StaffDivideSymbol.h index 3fdd7ae85..76dbdcace 100644 --- a/src/private/mx/core/generated/StaffDivideSymbol.h +++ b/src/private/mx/core/generated/StaffDivideSymbol.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -43,6 +45,9 @@ class StaffDivideSymbol final /// (the import leniency policy; never produces an invalid value). static StaffDivideSymbol parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static StaffDivideSymbol parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const StaffDivideSymbol &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/StaffLayout.cpp b/src/private/mx/core/generated/StaffLayout.cpp index c6ff09891..3c69e05e5 100644 --- a/src/private/mx/core/generated/StaffLayout.cpp +++ b/src/private/mx/core/generated/StaffLayout.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/StaffLayout.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void StaffLayout::setStaffDistance(std::optional value) } StaffLayout parseStaffLayout(pugi::xml_node el) +{ + return parseStaffLayout(el, ParseContext{}); +} + +StaffLayout parseStaffLayout(pugi::xml_node el, const ParseContext &context) { StaffLayout out; for (pugi::xml_attribute a : el.attributes()) @@ -42,23 +48,28 @@ StaffLayout parseStaffLayout(pugi::xml_node el) } if (aname == "number") { - out.setNumber(StaffNumber::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else { throwUnknownAttribute(el, a.name()); } } - parseStaffLayoutContent(out, el); + parseStaffLayoutContent(out, el, context); return out; } void parseStaffLayoutContent(StaffLayout &out, pugi::xml_node el) +{ + parseStaffLayoutContent(out, el, ParseContext{}); +} + +void parseStaffLayoutContent(StaffLayout &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "staff-distance")) { - out.setStaffDistance(Tenths::parse(childText(cursor))); + out.setStaffDistance(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/StaffLayout.h b/src/private/mx/core/generated/StaffLayout.h index 2818adf6e..bbd050ab4 100644 --- a/src/private/mx/core/generated/StaffLayout.h +++ b/src/private/mx/core/generated/StaffLayout.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Staff layout includes the vertical distance from the bottom line of the previous staff in this /// system to the top line of the staff specified by the number attribute. The optional number /// attribute refers to staff numbers within the part, from top to bottom on the system. A value of 1 @@ -42,8 +44,12 @@ class StaffLayout final StaffLayout parseStaffLayout(pugi::xml_node el); +StaffLayout parseStaffLayout(pugi::xml_node el, const ParseContext &context); + void parseStaffLayoutContent(StaffLayout &out, pugi::xml_node el); +void parseStaffLayoutContent(StaffLayout &out, pugi::xml_node el, const ParseContext &context); + void serializeStaffLayout(const StaffLayout &v, pugi::xml_node parent, const char *tag); void serializeStaffLayoutContent(const StaffLayout &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/StaffLine.cpp b/src/private/mx/core/generated/StaffLine.cpp index c17ac0c51..f0c5775f3 100644 --- a/src/private/mx/core/generated/StaffLine.cpp +++ b/src/private/mx/core/generated/StaffLine.cpp @@ -38,20 +38,33 @@ std::string StaffLine::toString() const bool StaffLine::tryParse(std::string_view text, StaffLine &out) { - int v{}; - if (!tryParseInt(text, v)) + ValueParseOutcome outcome = ValueParseOutcome::valid; + StaffLine parsed = parse(text, outcome); + if (outcome == ValueParseOutcome::invalid) { return false; } - out = StaffLine{v}; + out = std::move(parsed); return true; } StaffLine StaffLine::parse(std::string_view text) { - StaffLine v; - tryParse(text, v); - return v; + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +StaffLine StaffLine::parse(std::string_view text, ValueParseOutcome &outcome) +{ + int v{}; + if (!tryParseInt(text, v)) + { + outcome = ValueParseOutcome::invalid; + return StaffLine{}; + } + StaffLine out{v}; + outcome = out.value() == v ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; } } // namespace mx::core diff --git a/src/private/mx/core/generated/StaffLine.h b/src/private/mx/core/generated/StaffLine.h index cbfd1f22c..5da64b2aa 100644 --- a/src/private/mx/core/generated/StaffLine.h +++ b/src/private/mx/core/generated/StaffLine.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -36,6 +38,9 @@ class StaffLine final /// Lenient: non-numeric text yields the clamped zero. static StaffLine parse(std::string_view text); + /// Lenient, and says whether the text was non-numeric or clamped. + static StaffLine parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const StaffLine &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/StaffLinePosition.cpp b/src/private/mx/core/generated/StaffLinePosition.cpp index 82b39c163..a932473a0 100644 --- a/src/private/mx/core/generated/StaffLinePosition.cpp +++ b/src/private/mx/core/generated/StaffLinePosition.cpp @@ -34,20 +34,33 @@ std::string StaffLinePosition::toString() const bool StaffLinePosition::tryParse(std::string_view text, StaffLinePosition &out) { - int v{}; - if (!tryParseInt(text, v)) + ValueParseOutcome outcome = ValueParseOutcome::valid; + StaffLinePosition parsed = parse(text, outcome); + if (outcome == ValueParseOutcome::invalid) { return false; } - out = StaffLinePosition{v}; + out = std::move(parsed); return true; } StaffLinePosition StaffLinePosition::parse(std::string_view text) { - StaffLinePosition v; - tryParse(text, v); - return v; + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +StaffLinePosition StaffLinePosition::parse(std::string_view text, ValueParseOutcome &outcome) +{ + int v{}; + if (!tryParseInt(text, v)) + { + outcome = ValueParseOutcome::invalid; + return StaffLinePosition{}; + } + StaffLinePosition out{v}; + outcome = out.value() == v ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; } } // namespace mx::core diff --git a/src/private/mx/core/generated/StaffLinePosition.h b/src/private/mx/core/generated/StaffLinePosition.h index e4ebc798d..96ce77627 100644 --- a/src/private/mx/core/generated/StaffLinePosition.h +++ b/src/private/mx/core/generated/StaffLinePosition.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -37,6 +39,9 @@ class StaffLinePosition final /// Lenient: non-numeric text yields the clamped zero. static StaffLinePosition parse(std::string_view text); + /// Lenient, and says whether the text was non-numeric or clamped. + static StaffLinePosition parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const StaffLinePosition &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/StaffNumber.cpp b/src/private/mx/core/generated/StaffNumber.cpp index 5d2d57915..41d01a50e 100644 --- a/src/private/mx/core/generated/StaffNumber.cpp +++ b/src/private/mx/core/generated/StaffNumber.cpp @@ -38,20 +38,33 @@ std::string StaffNumber::toString() const bool StaffNumber::tryParse(std::string_view text, StaffNumber &out) { - int v{}; - if (!tryParseInt(text, v)) + ValueParseOutcome outcome = ValueParseOutcome::valid; + StaffNumber parsed = parse(text, outcome); + if (outcome == ValueParseOutcome::invalid) { return false; } - out = StaffNumber{v}; + out = std::move(parsed); return true; } StaffNumber StaffNumber::parse(std::string_view text) { - StaffNumber v; - tryParse(text, v); - return v; + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +StaffNumber StaffNumber::parse(std::string_view text, ValueParseOutcome &outcome) +{ + int v{}; + if (!tryParseInt(text, v)) + { + outcome = ValueParseOutcome::invalid; + return StaffNumber{}; + } + StaffNumber out{v}; + outcome = out.value() == v ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; } } // namespace mx::core diff --git a/src/private/mx/core/generated/StaffNumber.h b/src/private/mx/core/generated/StaffNumber.h index cde886f68..b92b6f4c8 100644 --- a/src/private/mx/core/generated/StaffNumber.h +++ b/src/private/mx/core/generated/StaffNumber.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -36,6 +38,9 @@ class StaffNumber final /// Lenient: non-numeric text yields the clamped zero. static StaffNumber parse(std::string_view text); + /// Lenient, and says whether the text was non-numeric or clamped. + static StaffNumber parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const StaffNumber &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/StaffSize.cpp b/src/private/mx/core/generated/StaffSize.cpp index bdce369a7..cab958238 100644 --- a/src/private/mx/core/generated/StaffSize.cpp +++ b/src/private/mx/core/generated/StaffSize.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/StaffSize.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void StaffSize::setValue(NonNegativeDecimal value) } StaffSize parseStaffSize(pugi::xml_node el) +{ + return parseStaffSize(el, ParseContext{}); +} + +StaffSize parseStaffSize(pugi::xml_node el, const ParseContext &context) { StaffSize out; for (pugi::xml_attribute a : el.attributes()) @@ -42,20 +48,25 @@ StaffSize parseStaffSize(pugi::xml_node el) } if (aname == "scaling") { - out.setScaling(NonNegativeDecimal::parse(a.value())); + out.setScaling(parseValue(a.value(), context, el, "scaling")); } else { throwUnknownAttribute(el, a.name()); } } - parseStaffSizeContent(out, el); + parseStaffSizeContent(out, el, context); return out; } void parseStaffSizeContent(StaffSize &out, pugi::xml_node el) { - out.setValue(NonNegativeDecimal::parse(childText(el))); + parseStaffSizeContent(out, el, ParseContext{}); +} + +void parseStaffSizeContent(StaffSize &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/StaffSize.h b/src/private/mx/core/generated/StaffSize.h index 73d568e12..67fe47283 100644 --- a/src/private/mx/core/generated/StaffSize.h +++ b/src/private/mx/core/generated/StaffSize.h @@ -15,6 +15,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The staff-size element indicates how large a staff space is on this staff, expressed as a /// percentage of the work's default scaling. Values less than 100 make the staff space smaller while /// values over 100 make the staff space larger. A staff-type of cue, ossia, or editorial implies a @@ -42,8 +44,12 @@ class StaffSize final StaffSize parseStaffSize(pugi::xml_node el); +StaffSize parseStaffSize(pugi::xml_node el, const ParseContext &context); + void parseStaffSizeContent(StaffSize &out, pugi::xml_node el); +void parseStaffSizeContent(StaffSize &out, pugi::xml_node el, const ParseContext &context); + void serializeStaffSize(const StaffSize &v, pugi::xml_node parent, const char *tag); void serializeStaffSizeContent(const StaffSize &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/StaffTuning.cpp b/src/private/mx/core/generated/StaffTuning.cpp index add34a7c1..64bd32a66 100644 --- a/src/private/mx/core/generated/StaffTuning.cpp +++ b/src/private/mx/core/generated/StaffTuning.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/StaffTuning.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void StaffTuning::setTuning(TuningGroup value) } StaffTuning parseStaffTuning(pugi::xml_node el) +{ + return parseStaffTuning(el, ParseContext{}); +} + +StaffTuning parseStaffTuning(pugi::xml_node el, const ParseContext &context) { StaffTuning out; bool seen_line = false; @@ -44,7 +50,7 @@ StaffTuning parseStaffTuning(pugi::xml_node el) if (aname == "line") { seen_line = true; - out.setLine(StaffLine::parse(a.value())); + out.setLine(parseValue(a.value(), context, el, "line")); } else { @@ -55,16 +61,21 @@ StaffTuning parseStaffTuning(pugi::xml_node el) { throwMissingAttribute(el, "line"); } - parseStaffTuningContent(out, el); + parseStaffTuningContent(out, el, context); return out; } void parseStaffTuningContent(StaffTuning &out, pugi::xml_node el) +{ + parseStaffTuningContent(out, el, ParseContext{}); +} + +void parseStaffTuningContent(StaffTuning &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "tuning-step"))) { - out.setTuning(parseTuningGroup(el, cursor)); + out.setTuning(parseTuningGroup(el, cursor, context)); } else { diff --git a/src/private/mx/core/generated/StaffTuning.h b/src/private/mx/core/generated/StaffTuning.h index 8b3b4c539..0670771bd 100644 --- a/src/private/mx/core/generated/StaffTuning.h +++ b/src/private/mx/core/generated/StaffTuning.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The staff-tuning type specifies the open, non-capo tuning of the lines on a tablature staff. /// Content fields mirror the schema grammar in declaration order; the /// serializer walks them, so a wrong order is unrepresentable (plan ยง2.3). @@ -37,8 +39,12 @@ class StaffTuning final StaffTuning parseStaffTuning(pugi::xml_node el); +StaffTuning parseStaffTuning(pugi::xml_node el, const ParseContext &context); + void parseStaffTuningContent(StaffTuning &out, pugi::xml_node el); +void parseStaffTuningContent(StaffTuning &out, pugi::xml_node el, const ParseContext &context); + void serializeStaffTuning(const StaffTuning &v, pugi::xml_node parent, const char *tag); void serializeStaffTuningContent(const StaffTuning &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/StaffType.cpp b/src/private/mx/core/generated/StaffType.cpp index da8283bdd..1ffe2fe8a 100644 --- a/src/private/mx/core/generated/StaffType.cpp +++ b/src/private/mx/core/generated/StaffType.cpp @@ -56,9 +56,15 @@ bool StaffType::tryParse(std::string_view text, StaffType &out) noexcept } StaffType StaffType::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +StaffType StaffType::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { StaffType v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/StaffType.h b/src/private/mx/core/generated/StaffType.h index 9528c706c..c43ee47a4 100644 --- a/src/private/mx/core/generated/StaffType.h +++ b/src/private/mx/core/generated/StaffType.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -54,6 +56,9 @@ class StaffType final /// (the import leniency policy; never produces an invalid value). static StaffType parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static StaffType parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const StaffType &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/StartNote.cpp b/src/private/mx/core/generated/StartNote.cpp index fd7048699..aa1d0c2e8 100644 --- a/src/private/mx/core/generated/StartNote.cpp +++ b/src/private/mx/core/generated/StartNote.cpp @@ -48,9 +48,15 @@ bool StartNote::tryParse(std::string_view text, StartNote &out) noexcept } StartNote StartNote::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +StartNote StartNote::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { StartNote v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/StartNote.h b/src/private/mx/core/generated/StartNote.h index 7083347f9..9307d67b3 100644 --- a/src/private/mx/core/generated/StartNote.h +++ b/src/private/mx/core/generated/StartNote.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -43,6 +45,9 @@ class StartNote final /// (the import leniency policy; never produces an invalid value). static StartNote parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static StartNote parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const StartNote &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/StartStop.cpp b/src/private/mx/core/generated/StartStop.cpp index 90d747e7e..7ee3fd1de 100644 --- a/src/private/mx/core/generated/StartStop.cpp +++ b/src/private/mx/core/generated/StartStop.cpp @@ -42,9 +42,15 @@ bool StartStop::tryParse(std::string_view text, StartStop &out) noexcept } StartStop StartStop::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +StartStop StartStop::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { StartStop v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/StartStop.h b/src/private/mx/core/generated/StartStop.h index b87a5934e..ec8360b00 100644 --- a/src/private/mx/core/generated/StartStop.h +++ b/src/private/mx/core/generated/StartStop.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -47,6 +49,9 @@ class StartStop final /// (the import leniency policy; never produces an invalid value). static StartStop parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static StartStop parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const StartStop &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/StartStopContinue.cpp b/src/private/mx/core/generated/StartStopContinue.cpp index c07bf1b16..35a5901f5 100644 --- a/src/private/mx/core/generated/StartStopContinue.cpp +++ b/src/private/mx/core/generated/StartStopContinue.cpp @@ -48,9 +48,15 @@ bool StartStopContinue::tryParse(std::string_view text, StartStopContinue &out) } StartStopContinue StartStopContinue::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +StartStopContinue StartStopContinue::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { StartStopContinue v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/StartStopContinue.h b/src/private/mx/core/generated/StartStopContinue.h index 718ef41f3..f30f9f362 100644 --- a/src/private/mx/core/generated/StartStopContinue.h +++ b/src/private/mx/core/generated/StartStopContinue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -52,6 +54,9 @@ class StartStopContinue final /// (the import leniency policy; never produces an invalid value). static StartStopContinue parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static StartStopContinue parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const StartStopContinue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/StartStopDiscontinue.cpp b/src/private/mx/core/generated/StartStopDiscontinue.cpp index b45e6beb2..a7ba6c574 100644 --- a/src/private/mx/core/generated/StartStopDiscontinue.cpp +++ b/src/private/mx/core/generated/StartStopDiscontinue.cpp @@ -48,9 +48,15 @@ bool StartStopDiscontinue::tryParse(std::string_view text, StartStopDiscontinue } StartStopDiscontinue StartStopDiscontinue::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +StartStopDiscontinue StartStopDiscontinue::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { StartStopDiscontinue v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/StartStopDiscontinue.h b/src/private/mx/core/generated/StartStopDiscontinue.h index a12ffb9f1..6baa17ec8 100644 --- a/src/private/mx/core/generated/StartStopDiscontinue.h +++ b/src/private/mx/core/generated/StartStopDiscontinue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -47,6 +49,9 @@ class StartStopDiscontinue final /// (the import leniency policy; never produces an invalid value). static StartStopDiscontinue parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static StartStopDiscontinue parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const StartStopDiscontinue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/StartStopSingle.cpp b/src/private/mx/core/generated/StartStopSingle.cpp index 751a864bc..be0329917 100644 --- a/src/private/mx/core/generated/StartStopSingle.cpp +++ b/src/private/mx/core/generated/StartStopSingle.cpp @@ -48,9 +48,15 @@ bool StartStopSingle::tryParse(std::string_view text, StartStopSingle &out) noex } StartStopSingle StartStopSingle::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +StartStopSingle StartStopSingle::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { StartStopSingle v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/StartStopSingle.h b/src/private/mx/core/generated/StartStopSingle.h index 99e5c2d17..9835aebaf 100644 --- a/src/private/mx/core/generated/StartStopSingle.h +++ b/src/private/mx/core/generated/StartStopSingle.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -45,6 +47,9 @@ class StartStopSingle final /// (the import leniency policy; never produces an invalid value). static StartStopSingle parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static StartStopSingle parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const StartStopSingle &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Stem.cpp b/src/private/mx/core/generated/Stem.cpp index 09591e938..85dea47de 100644 --- a/src/private/mx/core/generated/Stem.cpp +++ b/src/private/mx/core/generated/Stem.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Stem.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -71,6 +72,11 @@ void Stem::setValue(StemValue value) } Stem parseStem(pugi::xml_node el) +{ + return parseStem(el, ParseContext{}); +} + +Stem parseStem(pugi::xml_node el, const ParseContext &context) { Stem out; for (pugi::xml_attribute a : el.attributes()) @@ -82,36 +88,41 @@ Stem parseStem(pugi::xml_node el) } if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else { throwUnknownAttribute(el, a.name()); } } - parseStemContent(out, el); + parseStemContent(out, el, context); return out; } void parseStemContent(Stem &out, pugi::xml_node el) { - out.setValue(StemValue::parse(childText(el))); + parseStemContent(out, el, ParseContext{}); +} + +void parseStemContent(Stem &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Stem.h b/src/private/mx/core/generated/Stem.h index 07ceaa3ea..c31d58bf9 100644 --- a/src/private/mx/core/generated/Stem.h +++ b/src/private/mx/core/generated/Stem.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Stems can be down, up, none, or double. For down and up stems, the position attributes can be /// used to specify stem length. The relative values specify the end of the stem relative to the /// program default. Default values specify an absolute end stem position. Negative values of @@ -50,8 +52,12 @@ class Stem final Stem parseStem(pugi::xml_node el); +Stem parseStem(pugi::xml_node el, const ParseContext &context); + void parseStemContent(Stem &out, pugi::xml_node el); +void parseStemContent(Stem &out, pugi::xml_node el, const ParseContext &context); + void serializeStem(const Stem &v, pugi::xml_node parent, const char *tag); void serializeStemContent(const Stem &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/StemValue.cpp b/src/private/mx/core/generated/StemValue.cpp index 3053694e8..9897c5e2f 100644 --- a/src/private/mx/core/generated/StemValue.cpp +++ b/src/private/mx/core/generated/StemValue.cpp @@ -54,9 +54,15 @@ bool StemValue::tryParse(std::string_view text, StemValue &out) noexcept } StemValue StemValue::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +StemValue StemValue::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { StemValue v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/StemValue.h b/src/private/mx/core/generated/StemValue.h index d4ea80262..9fac44548 100644 --- a/src/private/mx/core/generated/StemValue.h +++ b/src/private/mx/core/generated/StemValue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -44,6 +46,9 @@ class StemValue final /// (the import leniency policy; never produces an invalid value). static StemValue parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static StemValue parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const StemValue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Step.cpp b/src/private/mx/core/generated/Step.cpp index 1eb1dea67..1f6e95f29 100644 --- a/src/private/mx/core/generated/Step.cpp +++ b/src/private/mx/core/generated/Step.cpp @@ -66,9 +66,15 @@ bool Step::tryParse(std::string_view text, Step &out) noexcept } Step Step::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +Step Step::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { Step v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/Step.h b/src/private/mx/core/generated/Step.h index ac1f36533..1d8f3aebe 100644 --- a/src/private/mx/core/generated/Step.h +++ b/src/private/mx/core/generated/Step.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -51,6 +53,9 @@ class Step final /// (the import leniency policy; never produces an invalid value). static Step parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static Step parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const Step &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Stick.cpp b/src/private/mx/core/generated/Stick.cpp index 2eaef158f..09fa51504 100644 --- a/src/private/mx/core/generated/Stick.cpp +++ b/src/private/mx/core/generated/Stick.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Stick.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -61,6 +62,11 @@ void Stick::setStickMaterial(StickMaterial value) } Stick parseStick(pugi::xml_node el) +{ + return parseStick(el, ParseContext{}); +} + +Stick parseStick(pugi::xml_node el, const ParseContext &context) { Stick out; for (pugi::xml_attribute a : el.attributes()) @@ -72,31 +78,36 @@ Stick parseStick(pugi::xml_node el) } if (aname == "tip") { - out.setTip(TipDirection::parse(a.value())); + out.setTip(parseValue(a.value(), context, el, "tip")); } else if (aname == "parentheses") { - out.setParentheses(YesNo::parse(a.value())); + out.setParentheses(parseValue(a.value(), context, el, "parentheses")); } else if (aname == "dashed-circle") { - out.setDashedCircle(YesNo::parse(a.value())); + out.setDashedCircle(parseValue(a.value(), context, el, "dashed-circle")); } else { throwUnknownAttribute(el, a.name()); } } - parseStickContent(out, el); + parseStickContent(out, el, context); return out; } void parseStickContent(Stick &out, pugi::xml_node el) +{ + parseStickContent(out, el, ParseContext{}); +} + +void parseStickContent(Stick &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "stick-type")) { - out.setStickType(StickType::parse(childText(cursor))); + out.setStickType(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -105,7 +116,7 @@ void parseStickContent(Stick &out, pugi::xml_node el) } if (cursorIs(cursor, "stick-material")) { - out.setStickMaterial(StickMaterial::parse(childText(cursor))); + out.setStickMaterial(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else diff --git a/src/private/mx/core/generated/Stick.h b/src/private/mx/core/generated/Stick.h index c8018179d..e4cadbaba 100644 --- a/src/private/mx/core/generated/Stick.h +++ b/src/private/mx/core/generated/Stick.h @@ -20,6 +20,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The stick type represents pictograms where the material of the stick, mallet, or beater is /// included.The parentheses and dashed-circle attributes indicate the presence of these marks around /// the round beater part of a pictogram. Values for these attributes are "no" if not present. @@ -50,8 +52,12 @@ class Stick final Stick parseStick(pugi::xml_node el); +Stick parseStick(pugi::xml_node el, const ParseContext &context); + void parseStickContent(Stick &out, pugi::xml_node el); +void parseStickContent(Stick &out, pugi::xml_node el, const ParseContext &context); + void serializeStick(const Stick &v, pugi::xml_node parent, const char *tag); void serializeStickContent(const Stick &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/StickLocation.cpp b/src/private/mx/core/generated/StickLocation.cpp index 23956ba76..1fc405b84 100644 --- a/src/private/mx/core/generated/StickLocation.cpp +++ b/src/private/mx/core/generated/StickLocation.cpp @@ -54,9 +54,15 @@ bool StickLocation::tryParse(std::string_view text, StickLocation &out) noexcept } StickLocation StickLocation::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +StickLocation StickLocation::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { StickLocation v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/StickLocation.h b/src/private/mx/core/generated/StickLocation.h index 1cbf346a6..941974db6 100644 --- a/src/private/mx/core/generated/StickLocation.h +++ b/src/private/mx/core/generated/StickLocation.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -45,6 +47,9 @@ class StickLocation final /// (the import leniency policy; never produces an invalid value). static StickLocation parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static StickLocation parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const StickLocation &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/StickMaterial.cpp b/src/private/mx/core/generated/StickMaterial.cpp index 4bcf2667c..af8d93a3a 100644 --- a/src/private/mx/core/generated/StickMaterial.cpp +++ b/src/private/mx/core/generated/StickMaterial.cpp @@ -56,9 +56,15 @@ bool StickMaterial::tryParse(std::string_view text, StickMaterial &out) noexcept } StickMaterial StickMaterial::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +StickMaterial StickMaterial::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { StickMaterial v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/StickMaterial.h b/src/private/mx/core/generated/StickMaterial.h index 5450854e7..dfa79fbdb 100644 --- a/src/private/mx/core/generated/StickMaterial.h +++ b/src/private/mx/core/generated/StickMaterial.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -46,6 +48,9 @@ class StickMaterial final /// (the import leniency policy; never produces an invalid value). static StickMaterial parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static StickMaterial parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const StickMaterial &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/StickType.cpp b/src/private/mx/core/generated/StickType.cpp index 94f1f751c..2bae6c125 100644 --- a/src/private/mx/core/generated/StickType.cpp +++ b/src/private/mx/core/generated/StickType.cpp @@ -82,9 +82,15 @@ bool StickType::tryParse(std::string_view text, StickType &out) noexcept } StickType StickType::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +StickType StickType::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { StickType v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/StickType.h b/src/private/mx/core/generated/StickType.h index 7162f1d5e..ebb6d49e2 100644 --- a/src/private/mx/core/generated/StickType.h +++ b/src/private/mx/core/generated/StickType.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -57,6 +59,9 @@ class StickType final /// (the import leniency policy; never produces an invalid value). static StickType parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static StickType parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const StickType &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/String.cpp b/src/private/mx/core/generated/String.cpp index 0f8c39f56..279e6f9f9 100644 --- a/src/private/mx/core/generated/String.cpp +++ b/src/private/mx/core/generated/String.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/String.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -121,6 +122,11 @@ void String::setValue(StringNumber value) } String parseString(pugi::xml_node el) +{ + return parseString(el, ParseContext{}); +} + +String parseString(pugi::xml_node el, const ParseContext &context) { String out; for (pugi::xml_attribute a : el.attributes()) @@ -132,56 +138,61 @@ String parseString(pugi::xml_node el) } if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else { throwUnknownAttribute(el, a.name()); } } - parseStringContent(out, el); + parseStringContent(out, el, context); return out; } void parseStringContent(String &out, pugi::xml_node el) { - out.setValue(StringNumber::parse(childText(el))); + parseStringContent(out, el, ParseContext{}); +} + +void parseStringContent(String &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/String.h b/src/private/mx/core/generated/String.h index aaceccc6c..1925e8a59 100644 --- a/src/private/mx/core/generated/String.h +++ b/src/private/mx/core/generated/String.h @@ -22,6 +22,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The string type is used with tablature notation, regular notation (where it is often circled), /// and chord diagrams. String numbers start with 1 for the highest pitched full-length string. class String final @@ -67,8 +69,12 @@ class String final String parseString(pugi::xml_node el); +String parseString(pugi::xml_node el, const ParseContext &context); + void parseStringContent(String &out, pugi::xml_node el); +void parseStringContent(String &out, pugi::xml_node el, const ParseContext &context); + void serializeString(const String &v, pugi::xml_node parent, const char *tag); void serializeStringContent(const String &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/StringMute.cpp b/src/private/mx/core/generated/StringMute.cpp index 68f4ff308..4fb5da5f6 100644 --- a/src/private/mx/core/generated/StringMute.cpp +++ b/src/private/mx/core/generated/StringMute.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/StringMute.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -141,6 +142,11 @@ void StringMute::setID(std::optional value) } StringMute parseStringMute(pugi::xml_node el) +{ + return parseStringMute(el, ParseContext{}); +} + +StringMute parseStringMute(pugi::xml_node el, const ParseContext &context) { StringMute out; bool seen_type = false; @@ -154,51 +160,51 @@ StringMute parseStringMute(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(OnOff::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "halign") { - out.setHalign(LeftCenterRight::parse(a.value())); + out.setHalign(parseValue(a.value(), context, el, "halign")); } else if (aname == "valign") { - out.setValign(Valign::parse(a.value())); + out.setValign(parseValue(a.value(), context, el, "valign")); } else if (aname == "id") { @@ -213,13 +219,19 @@ StringMute parseStringMute(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseStringMuteContent(out, el); + parseStringMuteContent(out, el, context); return out; } void parseStringMuteContent(StringMute &out, pugi::xml_node el) +{ + parseStringMuteContent(out, el, ParseContext{}); +} + +void parseStringMuteContent(StringMute &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/StringMute.h b/src/private/mx/core/generated/StringMute.h index 129538ce7..8166d0871 100644 --- a/src/private/mx/core/generated/StringMute.h +++ b/src/private/mx/core/generated/StringMute.h @@ -25,6 +25,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The string-mute type represents string mute on and mute off symbols. class StringMute final { @@ -75,8 +77,12 @@ class StringMute final StringMute parseStringMute(pugi::xml_node el); +StringMute parseStringMute(pugi::xml_node el, const ParseContext &context); + void parseStringMuteContent(StringMute &out, pugi::xml_node el); +void parseStringMuteContent(StringMute &out, pugi::xml_node el, const ParseContext &context); + void serializeStringMute(const StringMute &v, pugi::xml_node parent, const char *tag); void serializeStringMuteContent(const StringMute &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/StringNumber.cpp b/src/private/mx/core/generated/StringNumber.cpp index 687823e62..a33f8308e 100644 --- a/src/private/mx/core/generated/StringNumber.cpp +++ b/src/private/mx/core/generated/StringNumber.cpp @@ -38,20 +38,33 @@ std::string StringNumber::toString() const bool StringNumber::tryParse(std::string_view text, StringNumber &out) { - int v{}; - if (!tryParseInt(text, v)) + ValueParseOutcome outcome = ValueParseOutcome::valid; + StringNumber parsed = parse(text, outcome); + if (outcome == ValueParseOutcome::invalid) { return false; } - out = StringNumber{v}; + out = std::move(parsed); return true; } StringNumber StringNumber::parse(std::string_view text) { - StringNumber v; - tryParse(text, v); - return v; + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +StringNumber StringNumber::parse(std::string_view text, ValueParseOutcome &outcome) +{ + int v{}; + if (!tryParseInt(text, v)) + { + outcome = ValueParseOutcome::invalid; + return StringNumber{}; + } + StringNumber out{v}; + outcome = out.value() == v ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; } } // namespace mx::core diff --git a/src/private/mx/core/generated/StringNumber.h b/src/private/mx/core/generated/StringNumber.h index ebfa2ad36..5e5323677 100644 --- a/src/private/mx/core/generated/StringNumber.h +++ b/src/private/mx/core/generated/StringNumber.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -36,6 +38,9 @@ class StringNumber final /// Lenient: non-numeric text yields the clamped zero. static StringNumber parse(std::string_view text); + /// Lenient, and says whether the text was non-numeric or clamped. + static StringNumber parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const StringNumber &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/StrongAccent.cpp b/src/private/mx/core/generated/StrongAccent.cpp index a24a3c6fb..961133e2b 100644 --- a/src/private/mx/core/generated/StrongAccent.cpp +++ b/src/private/mx/core/generated/StrongAccent.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/StrongAccent.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -21,6 +22,11 @@ void StrongAccent::setType(std::optional value) } StrongAccent parseStrongAccent(pugi::xml_node el) +{ + return parseStrongAccent(el, ParseContext{}); +} + +StrongAccent parseStrongAccent(pugi::xml_node el, const ParseContext &context) { StrongAccent out; for (pugi::xml_attribute a : el.attributes()) @@ -32,54 +38,54 @@ StrongAccent parseStrongAccent(pugi::xml_node el) } if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else if (aname == "type") { - out.setType(UpDown::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else { throwUnknownAttribute(el, a.name()); } } - parseEmptyPlacementContent(out, el); + parseEmptyPlacementContent(out, el, context); return out; } diff --git a/src/private/mx/core/generated/StrongAccent.h b/src/private/mx/core/generated/StrongAccent.h index c664abf83..a4c3c0f5a 100644 --- a/src/private/mx/core/generated/StrongAccent.h +++ b/src/private/mx/core/generated/StrongAccent.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The strong-accent type indicates a vertical accent mark. The type attribute indicates if the /// point of the accent is down or up. /// The schema's complexContent extension: non-polymorphic public @@ -33,6 +35,8 @@ class StrongAccent : public EmptyPlacement StrongAccent parseStrongAccent(pugi::xml_node el); +StrongAccent parseStrongAccent(pugi::xml_node el, const ParseContext &context); + void serializeStrongAccent(const StrongAccent &v, pugi::xml_node parent, const char *tag); } // namespace mx::core diff --git a/src/private/mx/core/generated/StyleText.cpp b/src/private/mx/core/generated/StyleText.cpp index ae9bb9536..266e663c4 100644 --- a/src/private/mx/core/generated/StyleText.cpp +++ b/src/private/mx/core/generated/StyleText.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/StyleText.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -111,6 +112,11 @@ void StyleText::setValue(std::string value) } StyleText parseStyleText(pugi::xml_node el) +{ + return parseStyleText(el, ParseContext{}); +} + +StyleText parseStyleText(pugi::xml_node el, const ParseContext &context) { StyleText out; for (pugi::xml_attribute a : el.attributes()) @@ -122,50 +128,55 @@ StyleText parseStyleText(pugi::xml_node el) } if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else { throwUnknownAttribute(el, a.name()); } } - parseStyleTextContent(out, el); + parseStyleTextContent(out, el, context); return out; } void parseStyleTextContent(StyleText &out, pugi::xml_node el) +{ + parseStyleTextContent(out, el, ParseContext{}); +} + +void parseStyleTextContent(StyleText &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/StyleText.h b/src/private/mx/core/generated/StyleText.h index e18b6bf75..dcaaab9b8 100644 --- a/src/private/mx/core/generated/StyleText.h +++ b/src/private/mx/core/generated/StyleText.h @@ -20,6 +20,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The style-text type represents a text element with a print-style attribute group. class StyleText final { @@ -61,8 +63,12 @@ class StyleText final StyleText parseStyleText(pugi::xml_node el); +StyleText parseStyleText(pugi::xml_node el, const ParseContext &context); + void parseStyleTextContent(StyleText &out, pugi::xml_node el); +void parseStyleTextContent(StyleText &out, pugi::xml_node el, const ParseContext &context); + void serializeStyleText(const StyleText &v, pugi::xml_node parent, const char *tag); void serializeStyleTextContent(const StyleText &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Supports.cpp b/src/private/mx/core/generated/Supports.cpp index 8f627d13b..423bd4a9d 100644 --- a/src/private/mx/core/generated/Supports.cpp +++ b/src/private/mx/core/generated/Supports.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Supports.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -51,6 +52,11 @@ void Supports::setValue(std::optional value) } Supports parseSupports(pugi::xml_node el) +{ + return parseSupports(el, ParseContext{}); +} + +Supports parseSupports(pugi::xml_node el, const ParseContext &context) { Supports out; bool seen_type = false; @@ -65,7 +71,7 @@ Supports parseSupports(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(YesNo::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "element") { @@ -93,13 +99,19 @@ Supports parseSupports(pugi::xml_node el) { throwMissingAttribute(el, "element"); } - parseSupportsContent(out, el); + parseSupportsContent(out, el, context); return out; } void parseSupportsContent(Supports &out, pugi::xml_node el) +{ + parseSupportsContent(out, el, ParseContext{}); +} + +void parseSupportsContent(Supports &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Supports.h b/src/private/mx/core/generated/Supports.h index 36838bf9b..9d26a13bd 100644 --- a/src/private/mx/core/generated/Supports.h +++ b/src/private/mx/core/generated/Supports.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The supports type indicates if a MusicXML encoding supports a particular MusicXML element. This /// is recommended for elements like beam, stem, and accidental, where the absence of an element is /// ambiguous if you do not know if the encoding supports that element. For Version 2.0, the supports @@ -45,8 +47,12 @@ class Supports final Supports parseSupports(pugi::xml_node el); +Supports parseSupports(pugi::xml_node el, const ParseContext &context); + void parseSupportsContent(Supports &out, pugi::xml_node el); +void parseSupportsContent(Supports &out, pugi::xml_node el, const ParseContext &context); + void serializeSupports(const Supports &v, pugi::xml_node parent, const char *tag); void serializeSupportsContent(const Supports &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Swing.cpp b/src/private/mx/core/generated/Swing.cpp index 3dd848114..70cf732d1 100644 --- a/src/private/mx/core/generated/Swing.cpp +++ b/src/private/mx/core/generated/Swing.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Swing.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void Swing::setSwingStyle(std::optional value) } Swing parseSwing(pugi::xml_node el) +{ + return parseSwing(el, ParseContext{}); +} + +Swing parseSwing(pugi::xml_node el, const ParseContext &context) { Swing out; for (pugi::xml_attribute a : el.attributes()) @@ -42,16 +48,21 @@ Swing parseSwing(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseSwingContent(out, el); + parseSwingContent(out, el, context); return out; } void parseSwingContent(Swing &out, pugi::xml_node el) +{ + parseSwingContent(out, el, ParseContext{}); +} + +void parseSwingContent(Swing &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "straight") || cursorIs(cursor, "first"))) { - out.setChoice(parseSwingChoice(el, cursor)); + out.setChoice(parseSwingChoice(el, cursor, context)); } else { diff --git a/src/private/mx/core/generated/Swing.h b/src/private/mx/core/generated/Swing.h index 60efe9e03..186cd30ed 100644 --- a/src/private/mx/core/generated/Swing.h +++ b/src/private/mx/core/generated/Swing.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The swing element specifies whether or not to use swing playback, where consecutive on-beat / /// off-beat eighth or 16th notes are played with unequal nominal durations. The straight element /// specifies that no swing is present, so consecutive notes have equal durations. The first and @@ -49,8 +51,12 @@ class Swing final Swing parseSwing(pugi::xml_node el); +Swing parseSwing(pugi::xml_node el, const ParseContext &context); + void parseSwingContent(Swing &out, pugi::xml_node el); +void parseSwingContent(Swing &out, pugi::xml_node el, const ParseContext &context); + void serializeSwing(const Swing &v, pugi::xml_node parent, const char *tag); void serializeSwingContent(const Swing &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/SwingChoice.cpp b/src/private/mx/core/generated/SwingChoice.cpp index 4236d3bb2..1af044762 100644 --- a/src/private/mx/core/generated/SwingChoice.cpp +++ b/src/private/mx/core/generated/SwingChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/SwingChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -26,16 +27,21 @@ SwingChoice SwingChoice::group(SwingChoiceGroup value) } SwingChoice parseSwingChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseSwingChoice(el, cursor, ParseContext{}); +} + +SwingChoice parseSwingChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "straight"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return SwingChoice::straight(std::move(value)); } if (cursor && (cursorIs(cursor, "first"))) { - return SwingChoice::group(parseSwingChoiceGroup(el, cursor)); + return SwingChoice::group(parseSwingChoiceGroup(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/SwingChoice.h b/src/private/mx/core/generated/SwingChoice.h index e7895c259..cb99765cb 100644 --- a/src/private/mx/core/generated/SwingChoice.h +++ b/src/private/mx/core/generated/SwingChoice.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -82,6 +84,8 @@ class SwingChoice final /// the enclosing element, for error paths. SwingChoice parseSwingChoice(pugi::xml_node el, pugi::xml_node &cursor); +SwingChoice parseSwingChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeSwingChoice(const SwingChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/SwingChoiceGroup.cpp b/src/private/mx/core/generated/SwingChoiceGroup.cpp index 392a9a619..d271579a7 100644 --- a/src/private/mx/core/generated/SwingChoiceGroup.cpp +++ b/src/private/mx/core/generated/SwingChoiceGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/SwingChoiceGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,11 +42,16 @@ void SwingChoiceGroup::setSwingType(std::optional value) } SwingChoiceGroup parseSwingChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseSwingChoiceGroup(el, cursor, ParseContext{}); +} + +SwingChoiceGroup parseSwingChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { SwingChoiceGroup out; if (cursorIs(cursor, "first")) { - out.setFirst(parseInt(childText(cursor))); + out.setFirst(parseIntegerValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -54,7 +60,7 @@ SwingChoiceGroup parseSwingChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor } if (cursorIs(cursor, "second")) { - out.setSecond(parseInt(childText(cursor))); + out.setSecond(parseIntegerValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -63,7 +69,7 @@ SwingChoiceGroup parseSwingChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor } if (cursorIs(cursor, "swing-type")) { - out.setSwingType(SwingTypeValue::parse(childText(cursor))); + out.setSwingType(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } return out; diff --git a/src/private/mx/core/generated/SwingChoiceGroup.h b/src/private/mx/core/generated/SwingChoiceGroup.h index 674f45314..4164c18bf 100644 --- a/src/private/mx/core/generated/SwingChoiceGroup.h +++ b/src/private/mx/core/generated/SwingChoiceGroup.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A shared content group (synthesized from an anonymous /// particle of the schema): transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -41,6 +43,8 @@ class SwingChoiceGroup final /// is the enclosing element, for error paths. SwingChoiceGroup parseSwingChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor); +SwingChoiceGroup parseSwingChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeSwingChoiceGroup(const SwingChoiceGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/SwingTypeValue.cpp b/src/private/mx/core/generated/SwingTypeValue.cpp index a325aeb91..1cf64c570 100644 --- a/src/private/mx/core/generated/SwingTypeValue.cpp +++ b/src/private/mx/core/generated/SwingTypeValue.cpp @@ -42,9 +42,15 @@ bool SwingTypeValue::tryParse(std::string_view text, SwingTypeValue &out) noexce } SwingTypeValue SwingTypeValue::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +SwingTypeValue SwingTypeValue::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { SwingTypeValue v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/SwingTypeValue.h b/src/private/mx/core/generated/SwingTypeValue.h index 4203fd801..07eced4af 100644 --- a/src/private/mx/core/generated/SwingTypeValue.h +++ b/src/private/mx/core/generated/SwingTypeValue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -41,6 +43,9 @@ class SwingTypeValue final /// (the import leniency policy; never produces an invalid value). static SwingTypeValue parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static SwingTypeValue parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const SwingTypeValue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Syllabic.cpp b/src/private/mx/core/generated/Syllabic.cpp index 1481a215d..fb96b6475 100644 --- a/src/private/mx/core/generated/Syllabic.cpp +++ b/src/private/mx/core/generated/Syllabic.cpp @@ -54,9 +54,15 @@ bool Syllabic::tryParse(std::string_view text, Syllabic &out) noexcept } Syllabic Syllabic::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +Syllabic Syllabic::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { Syllabic v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/Syllabic.h b/src/private/mx/core/generated/Syllabic.h index 775390640..7eb5b7db7 100644 --- a/src/private/mx/core/generated/Syllabic.h +++ b/src/private/mx/core/generated/Syllabic.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -46,6 +48,9 @@ class Syllabic final /// (the import leniency policy; never produces an invalid value). static Syllabic parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static Syllabic parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const Syllabic &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/SymbolSize.cpp b/src/private/mx/core/generated/SymbolSize.cpp index 775e29cb9..d474febc4 100644 --- a/src/private/mx/core/generated/SymbolSize.cpp +++ b/src/private/mx/core/generated/SymbolSize.cpp @@ -54,9 +54,15 @@ bool SymbolSize::tryParse(std::string_view text, SymbolSize &out) noexcept } SymbolSize SymbolSize::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +SymbolSize SymbolSize::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { SymbolSize v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/SymbolSize.h b/src/private/mx/core/generated/SymbolSize.h index b143a6b0c..ff5c6f54f 100644 --- a/src/private/mx/core/generated/SymbolSize.h +++ b/src/private/mx/core/generated/SymbolSize.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -45,6 +47,9 @@ class SymbolSize final /// (the import leniency policy; never produces an invalid value). static SymbolSize parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static SymbolSize parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const SymbolSize &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Sync.cpp b/src/private/mx/core/generated/Sync.cpp index 2ba3e2e26..4b83fe501 100644 --- a/src/private/mx/core/generated/Sync.cpp +++ b/src/private/mx/core/generated/Sync.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Sync.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -51,6 +52,11 @@ void Sync::setTimeOnly(std::optional value) } Sync parseSync(pugi::xml_node el) +{ + return parseSync(el, ParseContext{}); +} + +Sync parseSync(pugi::xml_node el, const ParseContext &context) { Sync out; bool seen_type = false; @@ -64,11 +70,11 @@ Sync parseSync(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(SyncType::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "latency") { - out.setLatency(Milliseconds::parse(a.value())); + out.setLatency(parseValue(a.value(), context, el, "latency")); } else if (aname == "player") { @@ -76,7 +82,7 @@ Sync parseSync(pugi::xml_node el) } else if (aname == "time-only") { - out.setTimeOnly(TimeOnly::parse(a.value())); + out.setTimeOnly(parseValue(a.value(), context, el, "time-only")); } else { @@ -87,13 +93,19 @@ Sync parseSync(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseSyncContent(out, el); + parseSyncContent(out, el, context); return out; } void parseSyncContent(Sync &out, pugi::xml_node el) +{ + parseSyncContent(out, el, ParseContext{}); +} + +void parseSyncContent(Sync &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Sync.h b/src/private/mx/core/generated/Sync.h index 03d18e03d..efc2ac6fb 100644 --- a/src/private/mx/core/generated/Sync.h +++ b/src/private/mx/core/generated/Sync.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The sync type specifies the style that a score following application should use the synchronize /// an accompaniment with a performer. If this type is not included in a score, default /// synchronization depends on the application. The optional latency attribute specifies a time in @@ -47,8 +49,12 @@ class Sync final Sync parseSync(pugi::xml_node el); +Sync parseSync(pugi::xml_node el, const ParseContext &context); + void parseSyncContent(Sync &out, pugi::xml_node el); +void parseSyncContent(Sync &out, pugi::xml_node el, const ParseContext &context); + void serializeSync(const Sync &v, pugi::xml_node parent, const char *tag); void serializeSyncContent(const Sync &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/SyncType.cpp b/src/private/mx/core/generated/SyncType.cpp index 06672cb25..92cbb102a 100644 --- a/src/private/mx/core/generated/SyncType.cpp +++ b/src/private/mx/core/generated/SyncType.cpp @@ -61,9 +61,15 @@ bool SyncType::tryParse(std::string_view text, SyncType &out) noexcept } SyncType SyncType::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +SyncType SyncType::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { SyncType v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/SyncType.h b/src/private/mx/core/generated/SyncType.h index 4993200d2..7a1f06714 100644 --- a/src/private/mx/core/generated/SyncType.h +++ b/src/private/mx/core/generated/SyncType.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -55,6 +57,9 @@ class SyncType final /// (the import leniency policy; never produces an invalid value). static SyncType parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static SyncType parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const SyncType &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/SystemDividers.cpp b/src/private/mx/core/generated/SystemDividers.cpp index d2a992619..557f3f72c 100644 --- a/src/private/mx/core/generated/SystemDividers.cpp +++ b/src/private/mx/core/generated/SystemDividers.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/SystemDividers.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void SystemDividers::setRightDivider(EmptyPrintObjectStyleAlign value) } SystemDividers parseSystemDividers(pugi::xml_node el) +{ + return parseSystemDividers(el, ParseContext{}); +} + +SystemDividers parseSystemDividers(pugi::xml_node el, const ParseContext &context) { SystemDividers out; for (pugi::xml_attribute a : el.attributes()) @@ -42,16 +48,21 @@ SystemDividers parseSystemDividers(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseSystemDividersContent(out, el); + parseSystemDividersContent(out, el, context); return out; } void parseSystemDividersContent(SystemDividers &out, pugi::xml_node el) +{ + parseSystemDividersContent(out, el, ParseContext{}); +} + +void parseSystemDividersContent(SystemDividers &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "left-divider")) { - out.setLeftDivider(parseEmptyPrintObjectStyleAlign(cursor)); + out.setLeftDivider(parseEmptyPrintObjectStyleAlign(cursor, context)); cursor = nextElement(cursor); } else @@ -60,7 +71,7 @@ void parseSystemDividersContent(SystemDividers &out, pugi::xml_node el) } if (cursorIs(cursor, "right-divider")) { - out.setRightDivider(parseEmptyPrintObjectStyleAlign(cursor)); + out.setRightDivider(parseEmptyPrintObjectStyleAlign(cursor, context)); cursor = nextElement(cursor); } else diff --git a/src/private/mx/core/generated/SystemDividers.h b/src/private/mx/core/generated/SystemDividers.h index e2359efea..a8fdeb9e3 100644 --- a/src/private/mx/core/generated/SystemDividers.h +++ b/src/private/mx/core/generated/SystemDividers.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The system-dividers element indicates the presence or absence of system dividers (also known as /// system separation marks) between systems displayed on the same page. Dividers on the left and /// right side of the page are controlled by the left-divider and right-divider elements @@ -42,8 +44,12 @@ class SystemDividers final SystemDividers parseSystemDividers(pugi::xml_node el); +SystemDividers parseSystemDividers(pugi::xml_node el, const ParseContext &context); + void parseSystemDividersContent(SystemDividers &out, pugi::xml_node el); +void parseSystemDividersContent(SystemDividers &out, pugi::xml_node el, const ParseContext &context); + void serializeSystemDividers(const SystemDividers &v, pugi::xml_node parent, const char *tag); void serializeSystemDividersContent(const SystemDividers &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/SystemLayout.cpp b/src/private/mx/core/generated/SystemLayout.cpp index 2718e9c6a..8329706a3 100644 --- a/src/private/mx/core/generated/SystemLayout.cpp +++ b/src/private/mx/core/generated/SystemLayout.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/SystemLayout.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -51,6 +52,11 @@ void SystemLayout::setSystemDividers(std::optional value) } SystemLayout parseSystemLayout(pugi::xml_node el) +{ + return parseSystemLayout(el, ParseContext{}); +} + +SystemLayout parseSystemLayout(pugi::xml_node el, const ParseContext &context) { SystemLayout out; for (pugi::xml_attribute a : el.attributes()) @@ -62,31 +68,36 @@ SystemLayout parseSystemLayout(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseSystemLayoutContent(out, el); + parseSystemLayoutContent(out, el, context); return out; } void parseSystemLayoutContent(SystemLayout &out, pugi::xml_node el) +{ + parseSystemLayoutContent(out, el, ParseContext{}); +} + +void parseSystemLayoutContent(SystemLayout &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "system-margins")) { - out.setSystemMargins(parseSystemMargins(cursor)); + out.setSystemMargins(parseSystemMargins(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "system-distance")) { - out.setSystemDistance(Tenths::parse(childText(cursor))); + out.setSystemDistance(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (cursorIs(cursor, "top-system-distance")) { - out.setTopSystemDistance(Tenths::parse(childText(cursor))); + out.setTopSystemDistance(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (cursorIs(cursor, "system-dividers")) { - out.setSystemDividers(parseSystemDividers(cursor)); + out.setSystemDividers(parseSystemDividers(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/SystemLayout.h b/src/private/mx/core/generated/SystemLayout.h index 0cd996814..d1ebf4f1d 100644 --- a/src/private/mx/core/generated/SystemLayout.h +++ b/src/private/mx/core/generated/SystemLayout.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A system is a group of staves that are read and played simultaneously. System layout includes /// left and right margins and the vertical distance from the previous system. The system distance is /// measured from the bottom line of the previous system to the top line of the current system. It is @@ -60,8 +62,12 @@ class SystemLayout final SystemLayout parseSystemLayout(pugi::xml_node el); +SystemLayout parseSystemLayout(pugi::xml_node el, const ParseContext &context); + void parseSystemLayoutContent(SystemLayout &out, pugi::xml_node el); +void parseSystemLayoutContent(SystemLayout &out, pugi::xml_node el, const ParseContext &context); + void serializeSystemLayout(const SystemLayout &v, pugi::xml_node parent, const char *tag); void serializeSystemLayoutContent(const SystemLayout &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/SystemMargins.cpp b/src/private/mx/core/generated/SystemMargins.cpp index cc8298584..96b922916 100644 --- a/src/private/mx/core/generated/SystemMargins.cpp +++ b/src/private/mx/core/generated/SystemMargins.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/SystemMargins.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -21,6 +22,11 @@ void SystemMargins::setLeftRightMargins(LeftRightMarginsGroup value) } SystemMargins parseSystemMargins(pugi::xml_node el) +{ + return parseSystemMargins(el, ParseContext{}); +} + +SystemMargins parseSystemMargins(pugi::xml_node el, const ParseContext &context) { SystemMargins out; for (pugi::xml_attribute a : el.attributes()) @@ -32,16 +38,21 @@ SystemMargins parseSystemMargins(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseSystemMarginsContent(out, el); + parseSystemMarginsContent(out, el, context); return out; } void parseSystemMarginsContent(SystemMargins &out, pugi::xml_node el) +{ + parseSystemMarginsContent(out, el, ParseContext{}); +} + +void parseSystemMarginsContent(SystemMargins &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "left-margin"))) { - out.setLeftRightMargins(parseLeftRightMarginsGroup(el, cursor)); + out.setLeftRightMargins(parseLeftRightMarginsGroup(el, cursor, context)); } else { diff --git a/src/private/mx/core/generated/SystemMargins.h b/src/private/mx/core/generated/SystemMargins.h index 0c0a04fb7..78ade809f 100644 --- a/src/private/mx/core/generated/SystemMargins.h +++ b/src/private/mx/core/generated/SystemMargins.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// System margins are relative to the page margins. Positive values indent and negative values /// reduce the margin size. /// Content fields mirror the schema grammar in declaration order; the @@ -34,8 +36,12 @@ class SystemMargins final SystemMargins parseSystemMargins(pugi::xml_node el); +SystemMargins parseSystemMargins(pugi::xml_node el, const ParseContext &context); + void parseSystemMarginsContent(SystemMargins &out, pugi::xml_node el); +void parseSystemMarginsContent(SystemMargins &out, pugi::xml_node el, const ParseContext &context); + void serializeSystemMargins(const SystemMargins &v, pugi::xml_node parent, const char *tag); void serializeSystemMarginsContent(const SystemMargins &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/SystemRelation.cpp b/src/private/mx/core/generated/SystemRelation.cpp index ed7c0b9e1..fe1c94d40 100644 --- a/src/private/mx/core/generated/SystemRelation.cpp +++ b/src/private/mx/core/generated/SystemRelation.cpp @@ -48,9 +48,15 @@ bool SystemRelation::tryParse(std::string_view text, SystemRelation &out) noexce } SystemRelation SystemRelation::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +SystemRelation SystemRelation::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { SystemRelation v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/SystemRelation.h b/src/private/mx/core/generated/SystemRelation.h index d1db3861c..4e6cf04d3 100644 --- a/src/private/mx/core/generated/SystemRelation.h +++ b/src/private/mx/core/generated/SystemRelation.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -48,6 +50,9 @@ class SystemRelation final /// (the import leniency policy; never produces an invalid value). static SystemRelation parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static SystemRelation parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const SystemRelation &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/SystemRelationNumber.cpp b/src/private/mx/core/generated/SystemRelationNumber.cpp index 0b6beb5d3..93f0abad4 100644 --- a/src/private/mx/core/generated/SystemRelationNumber.cpp +++ b/src/private/mx/core/generated/SystemRelationNumber.cpp @@ -56,9 +56,15 @@ bool SystemRelationNumber::tryParse(std::string_view text, SystemRelationNumber } SystemRelationNumber SystemRelationNumber::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +SystemRelationNumber SystemRelationNumber::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { SystemRelationNumber v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/SystemRelationNumber.h b/src/private/mx/core/generated/SystemRelationNumber.h index c9ba73a69..90deec1a6 100644 --- a/src/private/mx/core/generated/SystemRelationNumber.h +++ b/src/private/mx/core/generated/SystemRelationNumber.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -53,6 +55,9 @@ class SystemRelationNumber final /// (the import leniency policy; never produces an invalid value). static SystemRelationNumber parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static SystemRelationNumber parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const SystemRelationNumber &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Tap.cpp b/src/private/mx/core/generated/Tap.cpp index a17ab2834..8ea61a36e 100644 --- a/src/private/mx/core/generated/Tap.cpp +++ b/src/private/mx/core/generated/Tap.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Tap.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -131,6 +132,11 @@ void Tap::setValue(std::string value) } Tap parseTap(pugi::xml_node el) +{ + return parseTap(el, ParseContext{}); +} + +Tap parseTap(pugi::xml_node el, const ParseContext &context) { Tap out; for (pugi::xml_attribute a : el.attributes()) @@ -142,58 +148,63 @@ Tap parseTap(pugi::xml_node el) } if (aname == "hand") { - out.setHand(TapHand::parse(a.value())); + out.setHand(parseValue(a.value(), context, el, "hand")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else { throwUnknownAttribute(el, a.name()); } } - parseTapContent(out, el); + parseTapContent(out, el, context); return out; } void parseTapContent(Tap &out, pugi::xml_node el) +{ + parseTapContent(out, el, ParseContext{}); +} + +void parseTapContent(Tap &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/Tap.h b/src/private/mx/core/generated/Tap.h index c0de7d951..6228d8134 100644 --- a/src/private/mx/core/generated/Tap.h +++ b/src/private/mx/core/generated/Tap.h @@ -22,6 +22,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The tap type indicates a tap on the fretboard. The text content allows specification of the /// notation; + and T are common choices. If the element is empty, the hand attribute is used to /// specify the symbol to use. The hand attribute is ignored if the tap glyph is already specified by @@ -73,8 +75,12 @@ class Tap final Tap parseTap(pugi::xml_node el); +Tap parseTap(pugi::xml_node el, const ParseContext &context); + void parseTapContent(Tap &out, pugi::xml_node el); +void parseTapContent(Tap &out, pugi::xml_node el, const ParseContext &context); + void serializeTap(const Tap &v, pugi::xml_node parent, const char *tag); void serializeTapContent(const Tap &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/TapHand.cpp b/src/private/mx/core/generated/TapHand.cpp index af037e044..d8a9beafc 100644 --- a/src/private/mx/core/generated/TapHand.cpp +++ b/src/private/mx/core/generated/TapHand.cpp @@ -42,9 +42,15 @@ bool TapHand::tryParse(std::string_view text, TapHand &out) noexcept } TapHand TapHand::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +TapHand TapHand::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { TapHand v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/TapHand.h b/src/private/mx/core/generated/TapHand.h index 7226fc015..ac31f061b 100644 --- a/src/private/mx/core/generated/TapHand.h +++ b/src/private/mx/core/generated/TapHand.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -41,6 +43,9 @@ class TapHand final /// (the import leniency policy; never produces an invalid value). static TapHand parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static TapHand parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const TapHand &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Technical.cpp b/src/private/mx/core/generated/Technical.cpp index bc09a017a..fabfc5ddc 100644 --- a/src/private/mx/core/generated/Technical.cpp +++ b/src/private/mx/core/generated/Technical.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Technical.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -36,6 +37,11 @@ void Technical::setChoice(std::vector value) } Technical parseTechnical(pugi::xml_node el) +{ + return parseTechnical(el, ParseContext{}); +} + +Technical parseTechnical(pugi::xml_node el, const ParseContext &context) { Technical out; for (pugi::xml_attribute a : el.attributes()) @@ -54,11 +60,16 @@ Technical parseTechnical(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseTechnicalContent(out, el); + parseTechnicalContent(out, el, context); return out; } void parseTechnicalContent(Technical &out, pugi::xml_node el) +{ + parseTechnicalContent(out, el, ParseContext{}); +} + +void parseTechnicalContent(Technical &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); while (cursor && @@ -74,7 +85,7 @@ void parseTechnicalContent(Technical &out, pugi::xml_node el) cursorIs(cursor, "half-muted") || cursorIs(cursor, "harmon-mute") || cursorIs(cursor, "golpe") || cursorIs(cursor, "other-technical"))) { - out.addChoice(parseTechnicalChoice(el, cursor)); + out.addChoice(parseTechnicalChoice(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/Technical.h b/src/private/mx/core/generated/Technical.h index 7e78c3db6..8cb8e1a93 100644 --- a/src/private/mx/core/generated/Technical.h +++ b/src/private/mx/core/generated/Technical.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Technical indications give performance information for individual instruments. /// Content fields mirror the schema grammar in declaration order; the /// serializer walks them, so a wrong order is unrepresentable (plan ยง2.3). @@ -39,8 +41,12 @@ class Technical final Technical parseTechnical(pugi::xml_node el); +Technical parseTechnical(pugi::xml_node el, const ParseContext &context); + void parseTechnicalContent(Technical &out, pugi::xml_node el); +void parseTechnicalContent(Technical &out, pugi::xml_node el, const ParseContext &context); + void serializeTechnical(const Technical &v, pugi::xml_node parent, const char *tag); void serializeTechnicalContent(const Technical &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/TechnicalChoice.cpp b/src/private/mx/core/generated/TechnicalChoice.cpp index 6091fd261..9e7f65e12 100644 --- a/src/private/mx/core/generated/TechnicalChoice.cpp +++ b/src/private/mx/core/generated/TechnicalChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/TechnicalChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -171,190 +172,195 @@ TechnicalChoice TechnicalChoice::otherTechnical(OtherPlacementText value) } TechnicalChoice parseTechnicalChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseTechnicalChoice(el, cursor, ParseContext{}); +} + +TechnicalChoice parseTechnicalChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "up-bow"))) { - EmptyPlacement value = parseEmptyPlacement(cursor); + EmptyPlacement value = parseEmptyPlacement(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::upBow(std::move(value)); } if (cursor && (cursorIs(cursor, "down-bow"))) { - EmptyPlacement value = parseEmptyPlacement(cursor); + EmptyPlacement value = parseEmptyPlacement(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::downBow(std::move(value)); } if (cursor && (cursorIs(cursor, "harmonic"))) { - Harmonic value = parseHarmonic(cursor); + Harmonic value = parseHarmonic(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::harmonic(std::move(value)); } if (cursor && (cursorIs(cursor, "open-string"))) { - EmptyPlacement value = parseEmptyPlacement(cursor); + EmptyPlacement value = parseEmptyPlacement(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::openString(std::move(value)); } if (cursor && (cursorIs(cursor, "thumb-position"))) { - EmptyPlacement value = parseEmptyPlacement(cursor); + EmptyPlacement value = parseEmptyPlacement(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::thumbPosition(std::move(value)); } if (cursor && (cursorIs(cursor, "fingering"))) { - Fingering value = parseFingering(cursor); + Fingering value = parseFingering(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::fingering(std::move(value)); } if (cursor && (cursorIs(cursor, "pluck"))) { - PlacementText value = parsePlacementText(cursor); + PlacementText value = parsePlacementText(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::pluck(std::move(value)); } if (cursor && (cursorIs(cursor, "double-tongue"))) { - EmptyPlacement value = parseEmptyPlacement(cursor); + EmptyPlacement value = parseEmptyPlacement(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::doubleTongue(std::move(value)); } if (cursor && (cursorIs(cursor, "triple-tongue"))) { - EmptyPlacement value = parseEmptyPlacement(cursor); + EmptyPlacement value = parseEmptyPlacement(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::tripleTongue(std::move(value)); } if (cursor && (cursorIs(cursor, "stopped"))) { - EmptyPlacementSmufl value = parseEmptyPlacementSmufl(cursor); + EmptyPlacementSmufl value = parseEmptyPlacementSmufl(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::stopped(std::move(value)); } if (cursor && (cursorIs(cursor, "snap-pizzicato"))) { - EmptyPlacement value = parseEmptyPlacement(cursor); + EmptyPlacement value = parseEmptyPlacement(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::snapPizzicato(std::move(value)); } if (cursor && (cursorIs(cursor, "fret"))) { - Fret value = parseFret(cursor); + Fret value = parseFret(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::fret(std::move(value)); } if (cursor && (cursorIs(cursor, "string"))) { - String value = parseString(cursor); + String value = parseString(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::string(std::move(value)); } if (cursor && (cursorIs(cursor, "hammer-on"))) { - HammerOnPullOff value = parseHammerOnPullOff(cursor); + HammerOnPullOff value = parseHammerOnPullOff(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::hammerOn(std::move(value)); } if (cursor && (cursorIs(cursor, "pull-off"))) { - HammerOnPullOff value = parseHammerOnPullOff(cursor); + HammerOnPullOff value = parseHammerOnPullOff(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::pullOff(std::move(value)); } if (cursor && (cursorIs(cursor, "bend"))) { - Bend value = parseBend(cursor); + Bend value = parseBend(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::bend(std::move(value)); } if (cursor && (cursorIs(cursor, "tap"))) { - Tap value = parseTap(cursor); + Tap value = parseTap(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::tap(std::move(value)); } if (cursor && (cursorIs(cursor, "heel"))) { - HeelToe value = parseHeelToe(cursor); + HeelToe value = parseHeelToe(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::heel(std::move(value)); } if (cursor && (cursorIs(cursor, "toe"))) { - HeelToe value = parseHeelToe(cursor); + HeelToe value = parseHeelToe(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::toe(std::move(value)); } if (cursor && (cursorIs(cursor, "fingernails"))) { - EmptyPlacement value = parseEmptyPlacement(cursor); + EmptyPlacement value = parseEmptyPlacement(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::fingernails(std::move(value)); } if (cursor && (cursorIs(cursor, "hole"))) { - Hole value = parseHole(cursor); + Hole value = parseHole(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::hole(std::move(value)); } if (cursor && (cursorIs(cursor, "arrow"))) { - Arrow value = parseArrow(cursor); + Arrow value = parseArrow(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::arrow(std::move(value)); } if (cursor && (cursorIs(cursor, "handbell"))) { - Handbell value = parseHandbell(cursor); + Handbell value = parseHandbell(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::handbell(std::move(value)); } if (cursor && (cursorIs(cursor, "brass-bend"))) { - EmptyPlacement value = parseEmptyPlacement(cursor); + EmptyPlacement value = parseEmptyPlacement(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::brassBend(std::move(value)); } if (cursor && (cursorIs(cursor, "flip"))) { - EmptyPlacement value = parseEmptyPlacement(cursor); + EmptyPlacement value = parseEmptyPlacement(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::flip(std::move(value)); } if (cursor && (cursorIs(cursor, "smear"))) { - EmptyPlacement value = parseEmptyPlacement(cursor); + EmptyPlacement value = parseEmptyPlacement(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::smear(std::move(value)); } if (cursor && (cursorIs(cursor, "open"))) { - EmptyPlacementSmufl value = parseEmptyPlacementSmufl(cursor); + EmptyPlacementSmufl value = parseEmptyPlacementSmufl(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::open(std::move(value)); } if (cursor && (cursorIs(cursor, "half-muted"))) { - EmptyPlacementSmufl value = parseEmptyPlacementSmufl(cursor); + EmptyPlacementSmufl value = parseEmptyPlacementSmufl(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::halfMuted(std::move(value)); } if (cursor && (cursorIs(cursor, "harmon-mute"))) { - HarmonMute value = parseHarmonMute(cursor); + HarmonMute value = parseHarmonMute(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::harmonMute(std::move(value)); } if (cursor && (cursorIs(cursor, "golpe"))) { - EmptyPlacement value = parseEmptyPlacement(cursor); + EmptyPlacement value = parseEmptyPlacement(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::golpe(std::move(value)); } if (cursor && (cursorIs(cursor, "other-technical"))) { - OtherPlacementText value = parseOtherPlacementText(cursor); + OtherPlacementText value = parseOtherPlacementText(cursor, context); cursor = nextElement(cursor); return TechnicalChoice::otherTechnical(std::move(value)); } diff --git a/src/private/mx/core/generated/TechnicalChoice.h b/src/private/mx/core/generated/TechnicalChoice.h index 62ff6d1a2..37de53941 100644 --- a/src/private/mx/core/generated/TechnicalChoice.h +++ b/src/private/mx/core/generated/TechnicalChoice.h @@ -32,6 +32,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -507,6 +509,8 @@ class TechnicalChoice final /// the enclosing element, for error paths. TechnicalChoice parseTechnicalChoice(pugi::xml_node el, pugi::xml_node &cursor); +TechnicalChoice parseTechnicalChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeTechnicalChoice(const TechnicalChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/Tenths.cpp b/src/private/mx/core/generated/Tenths.cpp index aedf464d3..ccedb1e45 100644 --- a/src/private/mx/core/generated/Tenths.cpp +++ b/src/private/mx/core/generated/Tenths.cpp @@ -34,20 +34,33 @@ std::string Tenths::toString() const bool Tenths::tryParse(std::string_view text, Tenths &out) { - Decimal v; - if (!Decimal::tryParse(text, v)) + ValueParseOutcome outcome = ValueParseOutcome::valid; + Tenths parsed = parse(text, outcome); + if (outcome == ValueParseOutcome::invalid) { return false; } - out = Tenths{std::move(v)}; + out = std::move(parsed); return true; } Tenths Tenths::parse(std::string_view text) { - Tenths v; - tryParse(text, v); - return v; + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +Tenths Tenths::parse(std::string_view text, ValueParseOutcome &outcome) +{ + Decimal v; + if (!Decimal::tryParse(text, v)) + { + outcome = ValueParseOutcome::invalid; + return Tenths{}; + } + Tenths out{v}; + outcome = out.value() == v ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; } } // namespace mx::core diff --git a/src/private/mx/core/generated/Tenths.h b/src/private/mx/core/generated/Tenths.h index 021a7d6a7..258b5f246 100644 --- a/src/private/mx/core/generated/Tenths.h +++ b/src/private/mx/core/generated/Tenths.h @@ -3,6 +3,7 @@ #pragma once #include "mx/core/Decimal.h" +#include "mx/core/Lexical.h" #include #include @@ -44,6 +45,9 @@ class Tenths final /// Lenient: non-numeric text yields the clamped zero. static Tenths parse(std::string_view text); + /// Lenient, and says whether the text was non-numeric or clamped. + static Tenths parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const Tenths &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/TextDirection.cpp b/src/private/mx/core/generated/TextDirection.cpp index d3a342904..b059cd1fc 100644 --- a/src/private/mx/core/generated/TextDirection.cpp +++ b/src/private/mx/core/generated/TextDirection.cpp @@ -54,9 +54,15 @@ bool TextDirection::tryParse(std::string_view text, TextDirection &out) noexcept } TextDirection TextDirection::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +TextDirection TextDirection::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { TextDirection v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/TextDirection.h b/src/private/mx/core/generated/TextDirection.h index 409c62f11..ccbd5c03c 100644 --- a/src/private/mx/core/generated/TextDirection.h +++ b/src/private/mx/core/generated/TextDirection.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -50,6 +52,9 @@ class TextDirection final /// (the import leniency policy; never produces an invalid value). static TextDirection parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static TextDirection parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const TextDirection &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/TextElementData.cpp b/src/private/mx/core/generated/TextElementData.cpp index 835e69065..10b58a695 100644 --- a/src/private/mx/core/generated/TextElementData.cpp +++ b/src/private/mx/core/generated/TextElementData.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/TextElementData.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -141,6 +142,11 @@ void TextElementData::setValue(std::string value) } TextElementData parseTextElementData(pugi::xml_node el) +{ + return parseTextElementData(el, ParseContext{}); +} + +TextElementData parseTextElementData(pugi::xml_node el, const ParseContext &context) { TextElementData out; for (pugi::xml_attribute a : el.attributes()) @@ -156,58 +162,63 @@ TextElementData parseTextElementData(pugi::xml_node el) } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "underline") { - out.setUnderline(NumberOfLines::parse(a.value())); + out.setUnderline(parseValue(a.value(), context, el, "underline")); } else if (aname == "overline") { - out.setOverline(NumberOfLines::parse(a.value())); + out.setOverline(parseValue(a.value(), context, el, "overline")); } else if (aname == "line-through") { - out.setLineThrough(NumberOfLines::parse(a.value())); + out.setLineThrough(parseValue(a.value(), context, el, "line-through")); } else if (aname == "rotation") { - out.setRotation(RotationDegrees::parse(a.value())); + out.setRotation(parseValue(a.value(), context, el, "rotation")); } else if (aname == "letter-spacing") { - out.setLetterSpacing(NumberOrNormal::parse(a.value())); + out.setLetterSpacing(parseValue(a.value(), context, el, "letter-spacing")); } else if (aname == "dir") { - out.setDir(TextDirection::parse(a.value())); + out.setDir(parseValue(a.value(), context, el, "dir")); } else { throwUnknownAttribute(el, a.name()); } } - parseTextElementDataContent(out, el); + parseTextElementDataContent(out, el, context); return out; } void parseTextElementDataContent(TextElementData &out, pugi::xml_node el) +{ + parseTextElementDataContent(out, el, ParseContext{}); +} + +void parseTextElementDataContent(TextElementData &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/TextElementData.h b/src/private/mx/core/generated/TextElementData.h index aeb7749d1..14c8e98fa 100644 --- a/src/private/mx/core/generated/TextElementData.h +++ b/src/private/mx/core/generated/TextElementData.h @@ -23,6 +23,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The text-element-data type represents a syllable or portion of a syllable for lyric text /// underlay. A hyphen in the string content should only be used for an actual hyphenated word. /// Language names for text elements come from ISO 639, with optional country subcodes from ISO 3166. @@ -75,8 +77,12 @@ class TextElementData final TextElementData parseTextElementData(pugi::xml_node el); +TextElementData parseTextElementData(pugi::xml_node el, const ParseContext &context); + void parseTextElementDataContent(TextElementData &out, pugi::xml_node el); +void parseTextElementDataContent(TextElementData &out, pugi::xml_node el, const ParseContext &context); + void serializeTextElementData(const TextElementData &v, pugi::xml_node parent, const char *tag); void serializeTextElementDataContent(const TextElementData &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Tie.cpp b/src/private/mx/core/generated/Tie.cpp index f53da18b0..28bc56fed 100644 --- a/src/private/mx/core/generated/Tie.cpp +++ b/src/private/mx/core/generated/Tie.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Tie.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void Tie::setTimeOnly(std::optional value) } Tie parseTie(pugi::xml_node el) +{ + return parseTie(el, ParseContext{}); +} + +Tie parseTie(pugi::xml_node el, const ParseContext &context) { Tie out; bool seen_type = false; @@ -44,11 +50,11 @@ Tie parseTie(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(StartStop::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "time-only") { - out.setTimeOnly(TimeOnly::parse(a.value())); + out.setTimeOnly(parseValue(a.value(), context, el, "time-only")); } else { @@ -59,13 +65,19 @@ Tie parseTie(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseTieContent(out, el); + parseTieContent(out, el, context); return out; } void parseTieContent(Tie &out, pugi::xml_node el) +{ + parseTieContent(out, el, ParseContext{}); +} + +void parseTieContent(Tie &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Tie.h b/src/private/mx/core/generated/Tie.h index 9bee94035..93a4bb2a1 100644 --- a/src/private/mx/core/generated/Tie.h +++ b/src/private/mx/core/generated/Tie.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The tie element indicates that a tie begins or ends with this note. If the tie element applies /// only particular times through a repeat, the time-only attribute indicates which times to apply /// it. The tie element indicates sound; the tied element indicates notation. @@ -35,8 +37,12 @@ class Tie final Tie parseTie(pugi::xml_node el); +Tie parseTie(pugi::xml_node el, const ParseContext &context); + void parseTieContent(Tie &out, pugi::xml_node el); +void parseTieContent(Tie &out, pugi::xml_node el, const ParseContext &context); + void serializeTie(const Tie &v, pugi::xml_node parent, const char *tag); void serializeTieContent(const Tie &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Tied.cpp b/src/private/mx/core/generated/Tied.cpp index 855344c53..1717eb182 100644 --- a/src/private/mx/core/generated/Tied.cpp +++ b/src/private/mx/core/generated/Tied.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Tied.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -201,6 +202,11 @@ void Tied::setID(std::optional value) } Tied parseTied(pugi::xml_node el) +{ + return parseTied(el, ParseContext{}); +} + +Tied parseTied(pugi::xml_node el, const ParseContext &context) { Tied out; bool seen_type = false; @@ -214,75 +220,75 @@ Tied parseTied(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(TiedType::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "number") { - out.setNumber(NumberLevel::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else if (aname == "line-type") { - out.setLineType(LineType::parse(a.value())); + out.setLineType(parseValue(a.value(), context, el, "line-type")); } else if (aname == "dash-length") { - out.setDashLength(Tenths::parse(a.value())); + out.setDashLength(parseValue(a.value(), context, el, "dash-length")); } else if (aname == "space-length") { - out.setSpaceLength(Tenths::parse(a.value())); + out.setSpaceLength(parseValue(a.value(), context, el, "space-length")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else if (aname == "orientation") { - out.setOrientation(OverUnder::parse(a.value())); + out.setOrientation(parseValue(a.value(), context, el, "orientation")); } else if (aname == "bezier-x") { - out.setBezierX(Tenths::parse(a.value())); + out.setBezierX(parseValue(a.value(), context, el, "bezier-x")); } else if (aname == "bezier-y") { - out.setBezierY(Tenths::parse(a.value())); + out.setBezierY(parseValue(a.value(), context, el, "bezier-y")); } else if (aname == "bezier-x2") { - out.setBezierX2(Tenths::parse(a.value())); + out.setBezierX2(parseValue(a.value(), context, el, "bezier-x2")); } else if (aname == "bezier-y2") { - out.setBezierY2(Tenths::parse(a.value())); + out.setBezierY2(parseValue(a.value(), context, el, "bezier-y2")); } else if (aname == "bezier-offset") { - out.setBezierOffset(Divisions::parse(a.value())); + out.setBezierOffset(parseValue(a.value(), context, el, "bezier-offset")); } else if (aname == "bezier-offset2") { - out.setBezierOffset2(Divisions::parse(a.value())); + out.setBezierOffset2(parseValue(a.value(), context, el, "bezier-offset2")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "id") { @@ -297,13 +303,19 @@ Tied parseTied(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseTiedContent(out, el); + parseTiedContent(out, el, context); return out; } void parseTiedContent(Tied &out, pugi::xml_node el) +{ + parseTiedContent(out, el, ParseContext{}); +} + +void parseTiedContent(Tied &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Tied.h b/src/private/mx/core/generated/Tied.h index e73ef0778..cc481a6b3 100644 --- a/src/private/mx/core/generated/Tied.h +++ b/src/private/mx/core/generated/Tied.h @@ -24,6 +24,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The tied element represents the notated tie. The tie element represents the tie sound. The number /// attribute is rarely needed to disambiguate ties, since note pitches will usually suffice. The /// attribute is implied rather than defaulting to 1 as with most elements. It is available for use @@ -103,8 +105,12 @@ class Tied final Tied parseTied(pugi::xml_node el); +Tied parseTied(pugi::xml_node el, const ParseContext &context); + void parseTiedContent(Tied &out, pugi::xml_node el); +void parseTiedContent(Tied &out, pugi::xml_node el, const ParseContext &context); + void serializeTied(const Tied &v, pugi::xml_node parent, const char *tag); void serializeTiedContent(const Tied &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/TiedType.cpp b/src/private/mx/core/generated/TiedType.cpp index 08a915432..eab35c88d 100644 --- a/src/private/mx/core/generated/TiedType.cpp +++ b/src/private/mx/core/generated/TiedType.cpp @@ -54,9 +54,15 @@ bool TiedType::tryParse(std::string_view text, TiedType &out) noexcept } TiedType TiedType::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +TiedType TiedType::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { TiedType v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/TiedType.h b/src/private/mx/core/generated/TiedType.h index 19b7f765b..243bed9d5 100644 --- a/src/private/mx/core/generated/TiedType.h +++ b/src/private/mx/core/generated/TiedType.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -54,6 +56,9 @@ class TiedType final /// (the import leniency policy; never produces an invalid value). static TiedType parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static TiedType parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const TiedType &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Time.cpp b/src/private/mx/core/generated/Time.cpp index de4ab4832..47a2b66ab 100644 --- a/src/private/mx/core/generated/Time.cpp +++ b/src/private/mx/core/generated/Time.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Time.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -181,6 +182,11 @@ void Time::setChoice(TimeChoice value) } Time parseTime(pugi::xml_node el) +{ + return parseTime(el, ParseContext{}); +} + +Time parseTime(pugi::xml_node el, const ParseContext &context) { Time out; for (pugi::xml_attribute a : el.attributes()) @@ -192,63 +198,63 @@ Time parseTime(pugi::xml_node el) } if (aname == "number") { - out.setNumber(StaffNumber::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else if (aname == "symbol") { - out.setSymbol(TimeSymbol::parse(a.value())); + out.setSymbol(parseValue(a.value(), context, el, "symbol")); } else if (aname == "separator") { - out.setSeparator(TimeSeparator::parse(a.value())); + out.setSeparator(parseValue(a.value(), context, el, "separator")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "halign") { - out.setHalign(LeftCenterRight::parse(a.value())); + out.setHalign(parseValue(a.value(), context, el, "halign")); } else if (aname == "valign") { - out.setValign(Valign::parse(a.value())); + out.setValign(parseValue(a.value(), context, el, "valign")); } else if (aname == "print-object") { - out.setPrintObject(YesNo::parse(a.value())); + out.setPrintObject(parseValue(a.value(), context, el, "print-object")); } else if (aname == "id") { @@ -259,16 +265,21 @@ Time parseTime(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseTimeContent(out, el); + parseTimeContent(out, el, context); return out; } void parseTimeContent(Time &out, pugi::xml_node el) +{ + parseTimeContent(out, el, ParseContext{}); +} + +void parseTimeContent(Time &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "beats") || cursorIs(cursor, "senza-misura"))) { - out.setChoice(parseTimeChoice(el, cursor)); + out.setChoice(parseTimeChoice(el, cursor, context)); } else { diff --git a/src/private/mx/core/generated/Time.h b/src/private/mx/core/generated/Time.h index 5c8f9de63..d5fb2f520 100644 --- a/src/private/mx/core/generated/Time.h +++ b/src/private/mx/core/generated/Time.h @@ -31,6 +31,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Time signatures are represented by the beats element for the numerator and the beat-type element /// for the denominator. The symbol attribute is used to indicate common and cut time symbols as well /// as a single number display. Multiple pairs of beat and beat-type elements are used for composite @@ -102,8 +104,12 @@ class Time final Time parseTime(pugi::xml_node el); +Time parseTime(pugi::xml_node el, const ParseContext &context); + void parseTimeContent(Time &out, pugi::xml_node el); +void parseTimeContent(Time &out, pugi::xml_node el, const ParseContext &context); + void serializeTime(const Time &v, pugi::xml_node parent, const char *tag); void serializeTimeContent(const Time &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/TimeChoice.cpp b/src/private/mx/core/generated/TimeChoice.cpp index 8a7bf5eb3..eb2e9c778 100644 --- a/src/private/mx/core/generated/TimeChoice.cpp +++ b/src/private/mx/core/generated/TimeChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/TimeChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -26,10 +27,15 @@ TimeChoice TimeChoice::senzaMisura(std::string value) } TimeChoice parseTimeChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseTimeChoice(el, cursor, ParseContext{}); +} + +TimeChoice parseTimeChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "beats"))) { - return TimeChoice::group(parseTimeChoiceGroup(el, cursor)); + return TimeChoice::group(parseTimeChoiceGroup(el, cursor, context)); } if (cursor && (cursorIs(cursor, "senza-misura"))) { diff --git a/src/private/mx/core/generated/TimeChoice.h b/src/private/mx/core/generated/TimeChoice.h index 1fe03fc95..867db15ce 100644 --- a/src/private/mx/core/generated/TimeChoice.h +++ b/src/private/mx/core/generated/TimeChoice.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -81,6 +83,8 @@ class TimeChoice final /// the enclosing element, for error paths. TimeChoice parseTimeChoice(pugi::xml_node el, pugi::xml_node &cursor); +TimeChoice parseTimeChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeTimeChoice(const TimeChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/TimeChoiceGroup.cpp b/src/private/mx/core/generated/TimeChoiceGroup.cpp index 50029a2ac..2cf91a9c9 100644 --- a/src/private/mx/core/generated/TimeChoiceGroup.cpp +++ b/src/private/mx/core/generated/TimeChoiceGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/TimeChoiceGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -36,20 +37,25 @@ void TimeChoiceGroup::setInterchangeable(std::optional value) } TimeChoiceGroup parseTimeChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseTimeChoiceGroup(el, cursor, ParseContext{}); +} + +TimeChoiceGroup parseTimeChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { TimeChoiceGroup out; if (!(cursor && (cursorIs(cursor, "beats")))) { throwMissingElement(el, "beats"); } - out.setTimeSignature(OneOrMore{parseTimeSignatureGroup(el, cursor)}); + out.setTimeSignature(OneOrMore{parseTimeSignatureGroup(el, cursor, context)}); while (cursor && (cursorIs(cursor, "beats"))) { - out.addTimeSignature(parseTimeSignatureGroup(el, cursor)); + out.addTimeSignature(parseTimeSignatureGroup(el, cursor, context)); } if (cursorIs(cursor, "interchangeable")) { - out.setInterchangeable(parseInterchangeable(cursor)); + out.setInterchangeable(parseInterchangeable(cursor, context)); cursor = nextElement(cursor); } return out; diff --git a/src/private/mx/core/generated/TimeChoiceGroup.h b/src/private/mx/core/generated/TimeChoiceGroup.h index e570ce8b8..e74225528 100644 --- a/src/private/mx/core/generated/TimeChoiceGroup.h +++ b/src/private/mx/core/generated/TimeChoiceGroup.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A shared content group (synthesized from an anonymous /// particle of the schema): transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -41,6 +43,8 @@ class TimeChoiceGroup final /// is the enclosing element, for error paths. TimeChoiceGroup parseTimeChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor); +TimeChoiceGroup parseTimeChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeTimeChoiceGroup(const TimeChoiceGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/TimeModification.cpp b/src/private/mx/core/generated/TimeModification.cpp index da79cf974..9e8d12860 100644 --- a/src/private/mx/core/generated/TimeModification.cpp +++ b/src/private/mx/core/generated/TimeModification.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/TimeModification.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,6 +42,11 @@ void TimeModification::setGroup(std::optional value) } TimeModification parseTimeModification(pugi::xml_node el) +{ + return parseTimeModification(el, ParseContext{}); +} + +TimeModification parseTimeModification(pugi::xml_node el, const ParseContext &context) { TimeModification out; for (pugi::xml_attribute a : el.attributes()) @@ -52,16 +58,21 @@ TimeModification parseTimeModification(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseTimeModificationContent(out, el); + parseTimeModificationContent(out, el, context); return out; } void parseTimeModificationContent(TimeModification &out, pugi::xml_node el) +{ + parseTimeModificationContent(out, el, ParseContext{}); +} + +void parseTimeModificationContent(TimeModification &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "actual-notes")) { - out.setActualNotes(parseInt(childText(cursor))); + out.setActualNotes(parseIntegerValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -70,7 +81,7 @@ void parseTimeModificationContent(TimeModification &out, pugi::xml_node el) } if (cursorIs(cursor, "normal-notes")) { - out.setNormalNotes(parseInt(childText(cursor))); + out.setNormalNotes(parseIntegerValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -79,7 +90,7 @@ void parseTimeModificationContent(TimeModification &out, pugi::xml_node el) } if (cursor && (cursorIs(cursor, "normal-type"))) { - out.setGroup(parseTimeModificationGroup(el, cursor)); + out.setGroup(parseTimeModificationGroup(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/TimeModification.h b/src/private/mx/core/generated/TimeModification.h index 861aa87c9..e8c356ca6 100644 --- a/src/private/mx/core/generated/TimeModification.h +++ b/src/private/mx/core/generated/TimeModification.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Time modification indicates tuplets, double-note tremolos, and other durational changes. A /// time-modification element shows how the cumulative, sounding effect of tuplets and double-note /// tremolos compare to the written note type represented by the type and dot elements. Nested @@ -43,8 +45,12 @@ class TimeModification TimeModification parseTimeModification(pugi::xml_node el); +TimeModification parseTimeModification(pugi::xml_node el, const ParseContext &context); + void parseTimeModificationContent(TimeModification &out, pugi::xml_node el); +void parseTimeModificationContent(TimeModification &out, pugi::xml_node el, const ParseContext &context); + void serializeTimeModification(const TimeModification &v, pugi::xml_node parent, const char *tag); void serializeTimeModificationContent(const TimeModification &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/TimeModificationGroup.cpp b/src/private/mx/core/generated/TimeModificationGroup.cpp index 5be39f2e4..d97c264a7 100644 --- a/src/private/mx/core/generated/TimeModificationGroup.cpp +++ b/src/private/mx/core/generated/TimeModificationGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/TimeModificationGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -36,11 +37,16 @@ void TimeModificationGroup::setNormalDot(std::vector value) } TimeModificationGroup parseTimeModificationGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseTimeModificationGroup(el, cursor, ParseContext{}); +} + +TimeModificationGroup parseTimeModificationGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { TimeModificationGroup out; if (cursorIs(cursor, "normal-type")) { - out.setNormalType(NoteTypeValue::parse(childText(cursor))); + out.setNormalType(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -49,7 +55,7 @@ TimeModificationGroup parseTimeModificationGroup(pugi::xml_node el, pugi::xml_no } while (cursorIs(cursor, "normal-dot")) { - out.addNormalDot(parseEmpty(cursor)); + out.addNormalDot(parseEmpty(cursor, context)); cursor = nextElement(cursor); } return out; diff --git a/src/private/mx/core/generated/TimeModificationGroup.h b/src/private/mx/core/generated/TimeModificationGroup.h index 274d1e3d8..d82f64b25 100644 --- a/src/private/mx/core/generated/TimeModificationGroup.h +++ b/src/private/mx/core/generated/TimeModificationGroup.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A shared content group (synthesized from an anonymous /// particle of the schema): transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -40,6 +42,9 @@ class TimeModificationGroup final /// is the enclosing element, for error paths. TimeModificationGroup parseTimeModificationGroup(pugi::xml_node el, pugi::xml_node &cursor); +TimeModificationGroup parseTimeModificationGroup(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context); + void serializeTimeModificationGroup(const TimeModificationGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/TimeRelation.cpp b/src/private/mx/core/generated/TimeRelation.cpp index 1f24a71bb..9338521f5 100644 --- a/src/private/mx/core/generated/TimeRelation.cpp +++ b/src/private/mx/core/generated/TimeRelation.cpp @@ -61,9 +61,15 @@ bool TimeRelation::tryParse(std::string_view text, TimeRelation &out) noexcept } TimeRelation TimeRelation::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +TimeRelation TimeRelation::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { TimeRelation v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/TimeRelation.h b/src/private/mx/core/generated/TimeRelation.h index 6e139049f..d28453571 100644 --- a/src/private/mx/core/generated/TimeRelation.h +++ b/src/private/mx/core/generated/TimeRelation.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -49,6 +51,9 @@ class TimeRelation final /// (the import leniency policy; never produces an invalid value). static TimeRelation parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static TimeRelation parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const TimeRelation &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/TimeSeparator.cpp b/src/private/mx/core/generated/TimeSeparator.cpp index 686fc0de0..56d070b9e 100644 --- a/src/private/mx/core/generated/TimeSeparator.cpp +++ b/src/private/mx/core/generated/TimeSeparator.cpp @@ -56,9 +56,15 @@ bool TimeSeparator::tryParse(std::string_view text, TimeSeparator &out) noexcept } TimeSeparator TimeSeparator::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +TimeSeparator TimeSeparator::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { TimeSeparator v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/TimeSeparator.h b/src/private/mx/core/generated/TimeSeparator.h index 235259add..0c465f050 100644 --- a/src/private/mx/core/generated/TimeSeparator.h +++ b/src/private/mx/core/generated/TimeSeparator.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -51,6 +53,9 @@ class TimeSeparator final /// (the import leniency policy; never produces an invalid value). static TimeSeparator parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static TimeSeparator parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const TimeSeparator &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/TimeSignatureGroup.cpp b/src/private/mx/core/generated/TimeSignatureGroup.cpp index a7439d74d..8acc6e769 100644 --- a/src/private/mx/core/generated/TimeSignatureGroup.cpp +++ b/src/private/mx/core/generated/TimeSignatureGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/TimeSignatureGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void TimeSignatureGroup::setBeatType(std::string value) } TimeSignatureGroup parseTimeSignatureGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseTimeSignatureGroup(el, cursor, ParseContext{}); +} + +TimeSignatureGroup parseTimeSignatureGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { TimeSignatureGroup out; if (cursorIs(cursor, "beats")) diff --git a/src/private/mx/core/generated/TimeSignatureGroup.h b/src/private/mx/core/generated/TimeSignatureGroup.h index 3c8f8df4b..053ac9b44 100644 --- a/src/private/mx/core/generated/TimeSignatureGroup.h +++ b/src/private/mx/core/generated/TimeSignatureGroup.h @@ -15,6 +15,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Time signatures are represented by the beats element for the numerator and the beat-type element /// for the denominator. /// A shared content group: transparent on the wire, its @@ -37,6 +39,8 @@ class TimeSignatureGroup final /// is the enclosing element, for error paths. TimeSignatureGroup parseTimeSignatureGroup(pugi::xml_node el, pugi::xml_node &cursor); +TimeSignatureGroup parseTimeSignatureGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeTimeSignatureGroup(const TimeSignatureGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/TimeSymbol.cpp b/src/private/mx/core/generated/TimeSymbol.cpp index 186461b64..54c0e23a8 100644 --- a/src/private/mx/core/generated/TimeSymbol.cpp +++ b/src/private/mx/core/generated/TimeSymbol.cpp @@ -61,9 +61,15 @@ bool TimeSymbol::tryParse(std::string_view text, TimeSymbol &out) noexcept } TimeSymbol TimeSymbol::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +TimeSymbol TimeSymbol::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { TimeSymbol v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/TimeSymbol.h b/src/private/mx/core/generated/TimeSymbol.h index 0fa43656f..4b1874d27 100644 --- a/src/private/mx/core/generated/TimeSymbol.h +++ b/src/private/mx/core/generated/TimeSymbol.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -54,6 +56,9 @@ class TimeSymbol final /// (the import leniency policy; never produces an invalid value). static TimeSymbol parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static TimeSymbol parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const TimeSymbol &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/TimewiseMeasure.cpp b/src/private/mx/core/generated/TimewiseMeasure.cpp index ca1cc1977..26acb88e8 100644 --- a/src/private/mx/core/generated/TimewiseMeasure.cpp +++ b/src/private/mx/core/generated/TimewiseMeasure.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/TimewiseMeasure.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -86,6 +87,11 @@ void TimewiseMeasure::setPart(OneOrMore value) } TimewiseMeasure parseTimewiseMeasure(pugi::xml_node el) +{ + return parseTimewiseMeasure(el, ParseContext{}); +} + +TimewiseMeasure parseTimewiseMeasure(pugi::xml_node el, const ParseContext &context) { TimewiseMeasure out; bool seen_number = false; @@ -103,19 +109,19 @@ TimewiseMeasure parseTimewiseMeasure(pugi::xml_node el) } else if (aname == "text") { - out.setText(MeasureText::parse(a.value())); + out.setText(parseValue(a.value(), context, el, "text")); } else if (aname == "implicit") { - out.setImplicit(YesNo::parse(a.value())); + out.setImplicit(parseValue(a.value(), context, el, "implicit")); } else if (aname == "non-controlling") { - out.setNonControlling(YesNo::parse(a.value())); + out.setNonControlling(parseValue(a.value(), context, el, "non-controlling")); } else if (aname == "width") { - out.setWidth(Tenths::parse(a.value())); + out.setWidth(parseValue(a.value(), context, el, "width")); } else if (aname == "id") { @@ -130,22 +136,27 @@ TimewiseMeasure parseTimewiseMeasure(pugi::xml_node el) { throwMissingAttribute(el, "number"); } - parseTimewiseMeasureContent(out, el); + parseTimewiseMeasureContent(out, el, context); return out; } void parseTimewiseMeasureContent(TimewiseMeasure &out, pugi::xml_node el) +{ + parseTimewiseMeasureContent(out, el, ParseContext{}); +} + +void parseTimewiseMeasureContent(TimewiseMeasure &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (!cursorIs(cursor, "part")) { throwMissingOrMisplaced(el, cursor, "part"); } - out.setPart(OneOrMore{parseTimewisePart(cursor)}); + out.setPart(OneOrMore{parseTimewisePart(cursor, context)}); cursor = nextElement(cursor); while (cursorIs(cursor, "part")) { - out.addPart(parseTimewisePart(cursor)); + out.addPart(parseTimewisePart(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/TimewiseMeasure.h b/src/private/mx/core/generated/TimewiseMeasure.h index db51faf3e..c19d2d7eb 100644 --- a/src/private/mx/core/generated/TimewiseMeasure.h +++ b/src/private/mx/core/generated/TimewiseMeasure.h @@ -23,6 +23,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Content fields mirror the schema grammar in declaration order; the /// serializer walks them, so a wrong order is unrepresentable (plan ยง2.3). class TimewiseMeasure final @@ -57,8 +59,12 @@ class TimewiseMeasure final TimewiseMeasure parseTimewiseMeasure(pugi::xml_node el); +TimewiseMeasure parseTimewiseMeasure(pugi::xml_node el, const ParseContext &context); + void parseTimewiseMeasureContent(TimewiseMeasure &out, pugi::xml_node el); +void parseTimewiseMeasureContent(TimewiseMeasure &out, pugi::xml_node el, const ParseContext &context); + void serializeTimewiseMeasure(const TimewiseMeasure &v, pugi::xml_node parent, const char *tag); void serializeTimewiseMeasureContent(const TimewiseMeasure &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/TimewisePart.cpp b/src/private/mx/core/generated/TimewisePart.cpp index eb34c07dd..76c4cb5ff 100644 --- a/src/private/mx/core/generated/TimewisePart.cpp +++ b/src/private/mx/core/generated/TimewisePart.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/TimewisePart.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -36,6 +37,11 @@ void TimewisePart::setMusicData(std::vector value) } TimewisePart parseTimewisePart(pugi::xml_node el) +{ + return parseTimewisePart(el, ParseContext{}); +} + +TimewisePart parseTimewisePart(pugi::xml_node el, const ParseContext &context) { TimewisePart out; bool seen_id = false; @@ -60,11 +66,16 @@ TimewisePart parseTimewisePart(pugi::xml_node el) { throwMissingAttribute(el, "id"); } - parseTimewisePartContent(out, el); + parseTimewisePartContent(out, el, context); return out; } void parseTimewisePartContent(TimewisePart &out, pugi::xml_node el) +{ + parseTimewisePartContent(out, el, ParseContext{}); +} + +void parseTimewisePartContent(TimewisePart &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); while (cursor && (cursorIs(cursor, "note") || cursorIs(cursor, "backup") || cursorIs(cursor, "forward") || @@ -73,7 +84,7 @@ void parseTimewisePartContent(TimewisePart &out, pugi::xml_node el) cursorIs(cursor, "listening") || cursorIs(cursor, "barline") || cursorIs(cursor, "grouping") || cursorIs(cursor, "link") || cursorIs(cursor, "bookmark"))) { - out.addMusicData(parseMusicDataChoice(el, cursor)); + out.addMusicData(parseMusicDataChoice(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/TimewisePart.h b/src/private/mx/core/generated/TimewisePart.h index 711a516d9..c348b7422 100644 --- a/src/private/mx/core/generated/TimewisePart.h +++ b/src/private/mx/core/generated/TimewisePart.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Content fields mirror the schema grammar in declaration order; the /// serializer walks them, so a wrong order is unrepresentable (plan ยง2.3). class TimewisePart final @@ -38,8 +40,12 @@ class TimewisePart final TimewisePart parseTimewisePart(pugi::xml_node el); +TimewisePart parseTimewisePart(pugi::xml_node el, const ParseContext &context); + void parseTimewisePartContent(TimewisePart &out, pugi::xml_node el); +void parseTimewisePartContent(TimewisePart &out, pugi::xml_node el, const ParseContext &context); + void serializeTimewisePart(const TimewisePart &v, pugi::xml_node parent, const char *tag); void serializeTimewisePartContent(const TimewisePart &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Timpani.cpp b/src/private/mx/core/generated/Timpani.cpp index e336159ac..339ddbdf5 100644 --- a/src/private/mx/core/generated/Timpani.cpp +++ b/src/private/mx/core/generated/Timpani.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Timpani.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -21,6 +22,11 @@ void Timpani::setSmufl(std::optional value) } Timpani parseTimpani(pugi::xml_node el) +{ + return parseTimpani(el, ParseContext{}); +} + +Timpani parseTimpani(pugi::xml_node el, const ParseContext &context) { Timpani out; for (pugi::xml_attribute a : el.attributes()) @@ -32,20 +38,26 @@ Timpani parseTimpani(pugi::xml_node el) } if (aname == "smufl") { - out.setSmufl(SmuflPictogramGlyphName::parse(a.value())); + out.setSmufl(parseValue(a.value(), context, el, "smufl")); } else { throwUnknownAttribute(el, a.name()); } } - parseTimpaniContent(out, el); + parseTimpaniContent(out, el, context); return out; } void parseTimpaniContent(Timpani &out, pugi::xml_node el) +{ + parseTimpaniContent(out, el, ParseContext{}); +} + +void parseTimpaniContent(Timpani &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Timpani.h b/src/private/mx/core/generated/Timpani.h index a27634749..e42ecbd66 100644 --- a/src/private/mx/core/generated/Timpani.h +++ b/src/private/mx/core/generated/Timpani.h @@ -15,6 +15,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The timpani type represents the timpani pictogram. The smufl attribute is used to distinguish /// different SMuFL stylistic alternates. class Timpani final @@ -30,8 +32,12 @@ class Timpani final Timpani parseTimpani(pugi::xml_node el); +Timpani parseTimpani(pugi::xml_node el, const ParseContext &context); + void parseTimpaniContent(Timpani &out, pugi::xml_node el); +void parseTimpaniContent(Timpani &out, pugi::xml_node el, const ParseContext &context); + void serializeTimpani(const Timpani &v, pugi::xml_node parent, const char *tag); void serializeTimpaniContent(const Timpani &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/TipDirection.cpp b/src/private/mx/core/generated/TipDirection.cpp index 3fa0859c9..ab07a67e2 100644 --- a/src/private/mx/core/generated/TipDirection.cpp +++ b/src/private/mx/core/generated/TipDirection.cpp @@ -71,9 +71,15 @@ bool TipDirection::tryParse(std::string_view text, TipDirection &out) noexcept } TipDirection TipDirection::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +TipDirection TipDirection::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { TipDirection v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/TipDirection.h b/src/private/mx/core/generated/TipDirection.h index 3dffc4912..41108175c 100644 --- a/src/private/mx/core/generated/TipDirection.h +++ b/src/private/mx/core/generated/TipDirection.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -53,6 +55,9 @@ class TipDirection final /// (the import leniency policy; never produces an invalid value). static TipDirection parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static TipDirection parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const TipDirection &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/TopBottom.cpp b/src/private/mx/core/generated/TopBottom.cpp index 476639779..b26fc94ce 100644 --- a/src/private/mx/core/generated/TopBottom.cpp +++ b/src/private/mx/core/generated/TopBottom.cpp @@ -42,9 +42,15 @@ bool TopBottom::tryParse(std::string_view text, TopBottom &out) noexcept } TopBottom TopBottom::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +TopBottom TopBottom::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { TopBottom v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/TopBottom.h b/src/private/mx/core/generated/TopBottom.h index 2b33c0de7..eaf2eaf06 100644 --- a/src/private/mx/core/generated/TopBottom.h +++ b/src/private/mx/core/generated/TopBottom.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -41,6 +43,9 @@ class TopBottom final /// (the import leniency policy; never produces an invalid value). static TopBottom parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static TopBottom parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const TopBottom &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/TraditionalKeyGroup.cpp b/src/private/mx/core/generated/TraditionalKeyGroup.cpp index baf5a3268..1f98f8dec 100644 --- a/src/private/mx/core/generated/TraditionalKeyGroup.cpp +++ b/src/private/mx/core/generated/TraditionalKeyGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/TraditionalKeyGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,16 +42,21 @@ void TraditionalKeyGroup::setMode(std::optional value) } TraditionalKeyGroup parseTraditionalKeyGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseTraditionalKeyGroup(el, cursor, ParseContext{}); +} + +TraditionalKeyGroup parseTraditionalKeyGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { TraditionalKeyGroup out; if (cursorIs(cursor, "cancel")) { - out.setCancel(parseCancel(cursor)); + out.setCancel(parseCancel(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "fifths")) { - out.setFifths(Fifths::parse(childText(cursor))); + out.setFifths(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -59,7 +65,7 @@ TraditionalKeyGroup parseTraditionalKeyGroup(pugi::xml_node el, pugi::xml_node & } if (cursorIs(cursor, "mode")) { - out.setMode(Mode::parse(childText(cursor))); + out.setMode(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } return out; diff --git a/src/private/mx/core/generated/TraditionalKeyGroup.h b/src/private/mx/core/generated/TraditionalKeyGroup.h index 8f1d1d11a..471bf3b18 100644 --- a/src/private/mx/core/generated/TraditionalKeyGroup.h +++ b/src/private/mx/core/generated/TraditionalKeyGroup.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The traditional-key group represents a traditional key signature using the cycle of fifths. /// A shared content group: transparent on the wire, its /// fields serialize directly into the referencing element (plan ยง2.3). @@ -43,6 +45,8 @@ class TraditionalKeyGroup final /// is the enclosing element, for error paths. TraditionalKeyGroup parseTraditionalKeyGroup(pugi::xml_node el, pugi::xml_node &cursor); +TraditionalKeyGroup parseTraditionalKeyGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeTraditionalKeyGroup(const TraditionalKeyGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/Transpose.cpp b/src/private/mx/core/generated/Transpose.cpp index 5495e3f81..044df0e8e 100644 --- a/src/private/mx/core/generated/Transpose.cpp +++ b/src/private/mx/core/generated/Transpose.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Transpose.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,6 +42,11 @@ void Transpose::setTranspose(TransposeGroup value) } Transpose parseTranspose(pugi::xml_node el) +{ + return parseTranspose(el, ParseContext{}); +} + +Transpose parseTranspose(pugi::xml_node el, const ParseContext &context) { Transpose out; for (pugi::xml_attribute a : el.attributes()) @@ -52,7 +58,7 @@ Transpose parseTranspose(pugi::xml_node el) } if (aname == "number") { - out.setNumber(StaffNumber::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else if (aname == "id") { @@ -63,16 +69,21 @@ Transpose parseTranspose(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseTransposeContent(out, el); + parseTransposeContent(out, el, context); return out; } void parseTransposeContent(Transpose &out, pugi::xml_node el) +{ + parseTransposeContent(out, el, ParseContext{}); +} + +void parseTransposeContent(Transpose &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "diatonic") || cursorIs(cursor, "chromatic"))) { - out.setTranspose(parseTransposeGroup(el, cursor)); + out.setTranspose(parseTransposeGroup(el, cursor, context)); } else { diff --git a/src/private/mx/core/generated/Transpose.h b/src/private/mx/core/generated/Transpose.h index 00c6d8fd4..c2a18eb6b 100644 --- a/src/private/mx/core/generated/Transpose.h +++ b/src/private/mx/core/generated/Transpose.h @@ -20,6 +20,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The transpose type represents what must be added to a written pitch to get a correct sounding /// pitch. The optional number attribute refers to staff numbers, from top to bottom on the system. /// If absent, the transposition applies to all staves in the part. Per-staff transposition is most @@ -45,8 +47,12 @@ class Transpose final Transpose parseTranspose(pugi::xml_node el); +Transpose parseTranspose(pugi::xml_node el, const ParseContext &context); + void parseTransposeContent(Transpose &out, pugi::xml_node el); +void parseTransposeContent(Transpose &out, pugi::xml_node el, const ParseContext &context); + void serializeTranspose(const Transpose &v, pugi::xml_node parent, const char *tag); void serializeTransposeContent(const Transpose &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/TransposeGroup.cpp b/src/private/mx/core/generated/TransposeGroup.cpp index d0cc8ec5c..9d9fb33b2 100644 --- a/src/private/mx/core/generated/TransposeGroup.cpp +++ b/src/private/mx/core/generated/TransposeGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/TransposeGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -51,16 +52,21 @@ void TransposeGroup::setDouble(std::optional value) } TransposeGroup parseTransposeGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseTransposeGroup(el, cursor, ParseContext{}); +} + +TransposeGroup parseTransposeGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { TransposeGroup out; if (cursorIs(cursor, "diatonic")) { - out.setDiatonic(parseInt(childText(cursor))); + out.setDiatonic(parseIntegerValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (cursorIs(cursor, "chromatic")) { - out.setChromatic(Semitones::parse(childText(cursor))); + out.setChromatic(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -69,12 +75,12 @@ TransposeGroup parseTransposeGroup(pugi::xml_node el, pugi::xml_node &cursor) } if (cursorIs(cursor, "octave-change")) { - out.setOctaveChange(parseInt(childText(cursor))); + out.setOctaveChange(parseIntegerValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (cursorIs(cursor, "double")) { - out.setDouble(parseDouble(cursor)); + out.setDouble(parseDouble(cursor, context)); cursor = nextElement(cursor); } return out; diff --git a/src/private/mx/core/generated/TransposeGroup.h b/src/private/mx/core/generated/TransposeGroup.h index e88ed8afa..deb762bd5 100644 --- a/src/private/mx/core/generated/TransposeGroup.h +++ b/src/private/mx/core/generated/TransposeGroup.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The transpose group represents what must be added to a written pitch to get a correct sounding /// pitch. /// A shared content group: transparent on the wire, its @@ -46,6 +48,8 @@ class TransposeGroup final /// is the enclosing element, for error paths. TransposeGroup parseTransposeGroup(pugi::xml_node el, pugi::xml_node &cursor); +TransposeGroup parseTransposeGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeTransposeGroup(const TransposeGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/Tremolo.cpp b/src/private/mx/core/generated/Tremolo.cpp index d467c9b28..ac7350267 100644 --- a/src/private/mx/core/generated/Tremolo.cpp +++ b/src/private/mx/core/generated/Tremolo.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Tremolo.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -141,6 +142,11 @@ void Tremolo::setValue(TremoloMarks value) } Tremolo parseTremolo(pugi::xml_node el) +{ + return parseTremolo(el, ParseContext{}); +} + +Tremolo parseTremolo(pugi::xml_node el, const ParseContext &context) { Tremolo out; for (pugi::xml_attribute a : el.attributes()) @@ -152,64 +158,69 @@ Tremolo parseTremolo(pugi::xml_node el) } if (aname == "type") { - out.setType(TremoloType::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else if (aname == "smufl") { - out.setSmufl(SmuflGlyphName::parse(a.value())); + out.setSmufl(parseValue(a.value(), context, el, "smufl")); } else { throwUnknownAttribute(el, a.name()); } } - parseTremoloContent(out, el); + parseTremoloContent(out, el, context); return out; } void parseTremoloContent(Tremolo &out, pugi::xml_node el) { - out.setValue(TremoloMarks::parse(childText(el))); + parseTremoloContent(out, el, ParseContext{}); +} + +void parseTremoloContent(Tremolo &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Tremolo.h b/src/private/mx/core/generated/Tremolo.h index 6610987e2..3ee8bcdac 100644 --- a/src/private/mx/core/generated/Tremolo.h +++ b/src/private/mx/core/generated/Tremolo.h @@ -24,6 +24,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The tremolo ornament can be used to indicate single-note, double-note, or unmeasured tremolos. /// Single-note tremolos use the single type, double-note tremolos use the start and stop types, and /// unmeasured tremolos use the unmeasured type. The default is "single" for compatibility with @@ -86,8 +88,12 @@ class Tremolo final Tremolo parseTremolo(pugi::xml_node el); +Tremolo parseTremolo(pugi::xml_node el, const ParseContext &context); + void parseTremoloContent(Tremolo &out, pugi::xml_node el); +void parseTremoloContent(Tremolo &out, pugi::xml_node el, const ParseContext &context); + void serializeTremolo(const Tremolo &v, pugi::xml_node parent, const char *tag); void serializeTremoloContent(const Tremolo &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/TremoloMarks.cpp b/src/private/mx/core/generated/TremoloMarks.cpp index c46c301ae..64972e792 100644 --- a/src/private/mx/core/generated/TremoloMarks.cpp +++ b/src/private/mx/core/generated/TremoloMarks.cpp @@ -42,20 +42,33 @@ std::string TremoloMarks::toString() const bool TremoloMarks::tryParse(std::string_view text, TremoloMarks &out) { - int v{}; - if (!tryParseInt(text, v)) + ValueParseOutcome outcome = ValueParseOutcome::valid; + TremoloMarks parsed = parse(text, outcome); + if (outcome == ValueParseOutcome::invalid) { return false; } - out = TremoloMarks{v}; + out = std::move(parsed); return true; } TremoloMarks TremoloMarks::parse(std::string_view text) { - TremoloMarks v; - tryParse(text, v); - return v; + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +TremoloMarks TremoloMarks::parse(std::string_view text, ValueParseOutcome &outcome) +{ + int v{}; + if (!tryParseInt(text, v)) + { + outcome = ValueParseOutcome::invalid; + return TremoloMarks{}; + } + TremoloMarks out{v}; + outcome = out.value() == v ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; } } // namespace mx::core diff --git a/src/private/mx/core/generated/TremoloMarks.h b/src/private/mx/core/generated/TremoloMarks.h index 3972a5b81..1a826c2c2 100644 --- a/src/private/mx/core/generated/TremoloMarks.h +++ b/src/private/mx/core/generated/TremoloMarks.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -36,6 +38,9 @@ class TremoloMarks final /// Lenient: non-numeric text yields the clamped zero. static TremoloMarks parse(std::string_view text); + /// Lenient, and says whether the text was non-numeric or clamped. + static TremoloMarks parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const TremoloMarks &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/TremoloType.cpp b/src/private/mx/core/generated/TremoloType.cpp index d0e969fcc..7b511763e 100644 --- a/src/private/mx/core/generated/TremoloType.cpp +++ b/src/private/mx/core/generated/TremoloType.cpp @@ -54,9 +54,15 @@ bool TremoloType::tryParse(std::string_view text, TremoloType &out) noexcept } TremoloType TremoloType::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +TremoloType TremoloType::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { TremoloType v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/TremoloType.h b/src/private/mx/core/generated/TremoloType.h index 1b0fdf951..c998c39d0 100644 --- a/src/private/mx/core/generated/TremoloType.h +++ b/src/private/mx/core/generated/TremoloType.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -44,6 +46,9 @@ class TremoloType final /// (the import leniency policy; never produces an invalid value). static TremoloType parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static TremoloType parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const TremoloType &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/TrillBeats.cpp b/src/private/mx/core/generated/TrillBeats.cpp index 36b1e76f8..43c47d6d3 100644 --- a/src/private/mx/core/generated/TrillBeats.cpp +++ b/src/private/mx/core/generated/TrillBeats.cpp @@ -38,20 +38,33 @@ std::string TrillBeats::toString() const bool TrillBeats::tryParse(std::string_view text, TrillBeats &out) { - Decimal v; - if (!Decimal::tryParse(text, v)) + ValueParseOutcome outcome = ValueParseOutcome::valid; + TrillBeats parsed = parse(text, outcome); + if (outcome == ValueParseOutcome::invalid) { return false; } - out = TrillBeats{std::move(v)}; + out = std::move(parsed); return true; } TrillBeats TrillBeats::parse(std::string_view text) { - TrillBeats v; - tryParse(text, v); - return v; + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +TrillBeats TrillBeats::parse(std::string_view text, ValueParseOutcome &outcome) +{ + Decimal v; + if (!Decimal::tryParse(text, v)) + { + outcome = ValueParseOutcome::invalid; + return TrillBeats{}; + } + TrillBeats out{v}; + outcome = out.value() == v ? ValueParseOutcome::valid : ValueParseOutcome::adjusted; + return out; } } // namespace mx::core diff --git a/src/private/mx/core/generated/TrillBeats.h b/src/private/mx/core/generated/TrillBeats.h index 38112e0cd..ac4066f54 100644 --- a/src/private/mx/core/generated/TrillBeats.h +++ b/src/private/mx/core/generated/TrillBeats.h @@ -3,6 +3,7 @@ #pragma once #include "mx/core/Decimal.h" +#include "mx/core/Lexical.h" #include #include @@ -38,6 +39,9 @@ class TrillBeats final /// Lenient: non-numeric text yields the clamped zero. static TrillBeats parse(std::string_view text); + /// Lenient, and says whether the text was non-numeric or clamped. + static TrillBeats parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const TrillBeats &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/TrillStep.cpp b/src/private/mx/core/generated/TrillStep.cpp index 02537b28e..8ab8f40ff 100644 --- a/src/private/mx/core/generated/TrillStep.cpp +++ b/src/private/mx/core/generated/TrillStep.cpp @@ -48,9 +48,15 @@ bool TrillStep::tryParse(std::string_view text, TrillStep &out) noexcept } TrillStep TrillStep::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +TrillStep TrillStep::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { TrillStep v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/TrillStep.h b/src/private/mx/core/generated/TrillStep.h index ce9a1381a..b8d5b48df 100644 --- a/src/private/mx/core/generated/TrillStep.h +++ b/src/private/mx/core/generated/TrillStep.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -43,6 +45,9 @@ class TrillStep final /// (the import leniency policy; never produces an invalid value). static TrillStep parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static TrillStep parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const TrillStep &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/TuningGroup.cpp b/src/private/mx/core/generated/TuningGroup.cpp index ce169fa0c..7882ca893 100644 --- a/src/private/mx/core/generated/TuningGroup.cpp +++ b/src/private/mx/core/generated/TuningGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/TuningGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,11 +42,16 @@ void TuningGroup::setTuningOctave(Octave value) } TuningGroup parseTuningGroup(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseTuningGroup(el, cursor, ParseContext{}); +} + +TuningGroup parseTuningGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { TuningGroup out; if (cursorIs(cursor, "tuning-step")) { - out.setTuningStep(Step::parse(childText(cursor))); + out.setTuningStep(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else @@ -54,12 +60,12 @@ TuningGroup parseTuningGroup(pugi::xml_node el, pugi::xml_node &cursor) } if (cursorIs(cursor, "tuning-alter")) { - out.setTuningAlter(Semitones::parse(childText(cursor))); + out.setTuningAlter(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (cursorIs(cursor, "tuning-octave")) { - out.setTuningOctave(Octave::parse(childText(cursor))); + out.setTuningOctave(parseValue(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } else diff --git a/src/private/mx/core/generated/TuningGroup.h b/src/private/mx/core/generated/TuningGroup.h index 0f3aea5ea..4adb6b1ba 100644 --- a/src/private/mx/core/generated/TuningGroup.h +++ b/src/private/mx/core/generated/TuningGroup.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The tuning group contains the sequence of elements common to the staff-tuning and accord /// elements. /// A shared content group: transparent on the wire, its @@ -44,6 +46,8 @@ class TuningGroup final /// is the enclosing element, for error paths. TuningGroup parseTuningGroup(pugi::xml_node el, pugi::xml_node &cursor); +TuningGroup parseTuningGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); + void serializeTuningGroup(const TuningGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/Tuplet.cpp b/src/private/mx/core/generated/Tuplet.cpp index 4eb590319..4bf9b0712 100644 --- a/src/private/mx/core/generated/Tuplet.cpp +++ b/src/private/mx/core/generated/Tuplet.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Tuplet.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -151,6 +152,11 @@ void Tuplet::setTupletNormal(std::optional value) } Tuplet parseTuplet(pugi::xml_node el) +{ + return parseTuplet(el, ParseContext{}); +} + +Tuplet parseTuplet(pugi::xml_node el, const ParseContext &context) { Tuplet out; bool seen_type = false; @@ -164,47 +170,47 @@ Tuplet parseTuplet(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(StartStop::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "number") { - out.setNumber(NumberLevel::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else if (aname == "bracket") { - out.setBracket(YesNo::parse(a.value())); + out.setBracket(parseValue(a.value(), context, el, "bracket")); } else if (aname == "show-number") { - out.setShowNumber(ShowTuplet::parse(a.value())); + out.setShowNumber(parseValue(a.value(), context, el, "show-number")); } else if (aname == "show-type") { - out.setShowType(ShowTuplet::parse(a.value())); + out.setShowType(parseValue(a.value(), context, el, "show-type")); } else if (aname == "line-shape") { - out.setLineShape(LineShape::parse(a.value())); + out.setLineShape(parseValue(a.value(), context, el, "line-shape")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else if (aname == "id") { @@ -219,21 +225,26 @@ Tuplet parseTuplet(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseTupletContent(out, el); + parseTupletContent(out, el, context); return out; } void parseTupletContent(Tuplet &out, pugi::xml_node el) +{ + parseTupletContent(out, el, ParseContext{}); +} + +void parseTupletContent(Tuplet &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "tuplet-actual")) { - out.setTupletActual(parseTupletPortion(cursor)); + out.setTupletActual(parseTupletPortion(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "tuplet-normal")) { - out.setTupletNormal(parseTupletPortion(cursor)); + out.setTupletNormal(parseTupletPortion(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/Tuplet.h b/src/private/mx/core/generated/Tuplet.h index c64d13981..5ca86ac33 100644 --- a/src/private/mx/core/generated/Tuplet.h +++ b/src/private/mx/core/generated/Tuplet.h @@ -26,6 +26,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A tuplet element is present when a tuplet is to be displayed graphically, in addition to the /// sound data provided by the time-modification elements. The number attribute is used to /// distinguish nested tuplets. The bracket attribute is used to indicate the presence of a bracket. @@ -93,8 +95,12 @@ class Tuplet final Tuplet parseTuplet(pugi::xml_node el); +Tuplet parseTuplet(pugi::xml_node el, const ParseContext &context); + void parseTupletContent(Tuplet &out, pugi::xml_node el); +void parseTupletContent(Tuplet &out, pugi::xml_node el, const ParseContext &context); + void serializeTuplet(const Tuplet &v, pugi::xml_node parent, const char *tag); void serializeTupletContent(const Tuplet &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/TupletDot.cpp b/src/private/mx/core/generated/TupletDot.cpp index 95f1314db..49bfc232b 100644 --- a/src/private/mx/core/generated/TupletDot.cpp +++ b/src/private/mx/core/generated/TupletDot.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/TupletDot.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -61,6 +62,11 @@ void TupletDot::setColor(std::optional value) } TupletDot parseTupletDot(pugi::xml_node el) +{ + return parseTupletDot(el, ParseContext{}); +} + +TupletDot parseTupletDot(pugi::xml_node el, const ParseContext &context) { TupletDot out; for (pugi::xml_attribute a : el.attributes()) @@ -72,36 +78,42 @@ TupletDot parseTupletDot(pugi::xml_node el) } if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else { throwUnknownAttribute(el, a.name()); } } - parseTupletDotContent(out, el); + parseTupletDotContent(out, el, context); return out; } void parseTupletDotContent(TupletDot &out, pugi::xml_node el) +{ + parseTupletDotContent(out, el, ParseContext{}); +} + +void parseTupletDotContent(TupletDot &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/TupletDot.h b/src/private/mx/core/generated/TupletDot.h index fe15edbb9..458d96a1f 100644 --- a/src/private/mx/core/generated/TupletDot.h +++ b/src/private/mx/core/generated/TupletDot.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The tuplet-dot type is used to specify dotted tuplet types. class TupletDot final { @@ -45,8 +47,12 @@ class TupletDot final TupletDot parseTupletDot(pugi::xml_node el); +TupletDot parseTupletDot(pugi::xml_node el, const ParseContext &context); + void parseTupletDotContent(TupletDot &out, pugi::xml_node el); +void parseTupletDotContent(TupletDot &out, pugi::xml_node el, const ParseContext &context); + void serializeTupletDot(const TupletDot &v, pugi::xml_node parent, const char *tag); void serializeTupletDotContent(const TupletDot &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/TupletNumber.cpp b/src/private/mx/core/generated/TupletNumber.cpp index 271689b95..866bc0c87 100644 --- a/src/private/mx/core/generated/TupletNumber.cpp +++ b/src/private/mx/core/generated/TupletNumber.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/TupletNumber.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -71,6 +72,11 @@ void TupletNumber::setValue(int value) } TupletNumber parseTupletNumber(pugi::xml_node el) +{ + return parseTupletNumber(el, ParseContext{}); +} + +TupletNumber parseTupletNumber(pugi::xml_node el, const ParseContext &context) { TupletNumber out; for (pugi::xml_attribute a : el.attributes()) @@ -82,36 +88,41 @@ TupletNumber parseTupletNumber(pugi::xml_node el) } if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else { throwUnknownAttribute(el, a.name()); } } - parseTupletNumberContent(out, el); + parseTupletNumberContent(out, el, context); return out; } void parseTupletNumberContent(TupletNumber &out, pugi::xml_node el) { - out.setValue(parseInt(childText(el))); + parseTupletNumberContent(out, el, ParseContext{}); +} + +void parseTupletNumberContent(TupletNumber &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseIntegerValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/TupletNumber.h b/src/private/mx/core/generated/TupletNumber.h index d30ab4335..59293f0a2 100644 --- a/src/private/mx/core/generated/TupletNumber.h +++ b/src/private/mx/core/generated/TupletNumber.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The tuplet-number type indicates the number of notes for this portion of the tuplet. class TupletNumber final { @@ -48,8 +50,12 @@ class TupletNumber final TupletNumber parseTupletNumber(pugi::xml_node el); +TupletNumber parseTupletNumber(pugi::xml_node el, const ParseContext &context); + void parseTupletNumberContent(TupletNumber &out, pugi::xml_node el); +void parseTupletNumberContent(TupletNumber &out, pugi::xml_node el, const ParseContext &context); + void serializeTupletNumber(const TupletNumber &v, pugi::xml_node parent, const char *tag); void serializeTupletNumberContent(const TupletNumber &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/TupletPortion.cpp b/src/private/mx/core/generated/TupletPortion.cpp index c5b363afe..03499ae6a 100644 --- a/src/private/mx/core/generated/TupletPortion.cpp +++ b/src/private/mx/core/generated/TupletPortion.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/TupletPortion.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -46,6 +47,11 @@ void TupletPortion::setTupletDot(std::vector value) } TupletPortion parseTupletPortion(pugi::xml_node el) +{ + return parseTupletPortion(el, ParseContext{}); +} + +TupletPortion parseTupletPortion(pugi::xml_node el, const ParseContext &context) { TupletPortion out; for (pugi::xml_attribute a : el.attributes()) @@ -57,26 +63,31 @@ TupletPortion parseTupletPortion(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseTupletPortionContent(out, el); + parseTupletPortionContent(out, el, context); return out; } void parseTupletPortionContent(TupletPortion &out, pugi::xml_node el) +{ + parseTupletPortionContent(out, el, ParseContext{}); +} + +void parseTupletPortionContent(TupletPortion &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "tuplet-number")) { - out.setTupletNumber(parseTupletNumber(cursor)); + out.setTupletNumber(parseTupletNumber(cursor, context)); cursor = nextElement(cursor); } if (cursorIs(cursor, "tuplet-type")) { - out.setTupletType(parseTupletType(cursor)); + out.setTupletType(parseTupletType(cursor, context)); cursor = nextElement(cursor); } while (cursorIs(cursor, "tuplet-dot")) { - out.addTupletDot(parseTupletDot(cursor)); + out.addTupletDot(parseTupletDot(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/TupletPortion.h b/src/private/mx/core/generated/TupletPortion.h index ea0d3111f..d436f2dc7 100644 --- a/src/private/mx/core/generated/TupletPortion.h +++ b/src/private/mx/core/generated/TupletPortion.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The tuplet-portion type provides optional full control over tuplet specifications. It allows the /// number and note type (including dots) to be set for the actual and normal portions of a single /// tuplet. If any of these elements are absent, their values are based on the time-modification @@ -45,8 +47,12 @@ class TupletPortion final TupletPortion parseTupletPortion(pugi::xml_node el); +TupletPortion parseTupletPortion(pugi::xml_node el, const ParseContext &context); + void parseTupletPortionContent(TupletPortion &out, pugi::xml_node el); +void parseTupletPortionContent(TupletPortion &out, pugi::xml_node el, const ParseContext &context); + void serializeTupletPortion(const TupletPortion &v, pugi::xml_node parent, const char *tag); void serializeTupletPortionContent(const TupletPortion &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/TupletType.cpp b/src/private/mx/core/generated/TupletType.cpp index 9faf2efef..dc3a3799b 100644 --- a/src/private/mx/core/generated/TupletType.cpp +++ b/src/private/mx/core/generated/TupletType.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/TupletType.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -71,6 +72,11 @@ void TupletType::setValue(NoteTypeValue value) } TupletType parseTupletType(pugi::xml_node el) +{ + return parseTupletType(el, ParseContext{}); +} + +TupletType parseTupletType(pugi::xml_node el, const ParseContext &context) { TupletType out; for (pugi::xml_attribute a : el.attributes()) @@ -82,36 +88,41 @@ TupletType parseTupletType(pugi::xml_node el) } if (aname == "font-family") { - out.setFontFamily(FontFamily::parse(a.value())); + out.setFontFamily(parseValue(a.value(), context, el, "font-family")); } else if (aname == "font-style") { - out.setFontStyle(FontStyle::parse(a.value())); + out.setFontStyle(parseValue(a.value(), context, el, "font-style")); } else if (aname == "font-size") { - out.setFontSize(FontSize::parse(a.value())); + out.setFontSize(parseValue(a.value(), context, el, "font-size")); } else if (aname == "font-weight") { - out.setFontWeight(FontWeight::parse(a.value())); + out.setFontWeight(parseValue(a.value(), context, el, "font-weight")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else { throwUnknownAttribute(el, a.name()); } } - parseTupletTypeContent(out, el); + parseTupletTypeContent(out, el, context); return out; } void parseTupletTypeContent(TupletType &out, pugi::xml_node el) { - out.setValue(NoteTypeValue::parse(childText(el))); + parseTupletTypeContent(out, el, ParseContext{}); +} + +void parseTupletTypeContent(TupletType &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/TupletType.h b/src/private/mx/core/generated/TupletType.h index d5c32505d..5fcd2c119 100644 --- a/src/private/mx/core/generated/TupletType.h +++ b/src/private/mx/core/generated/TupletType.h @@ -20,6 +20,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The tuplet-type type indicates the graphical note type of the notes for this portion of the /// tuplet. class TupletType final @@ -50,8 +52,12 @@ class TupletType final TupletType parseTupletType(pugi::xml_node el); +TupletType parseTupletType(pugi::xml_node el, const ParseContext &context); + void parseTupletTypeContent(TupletType &out, pugi::xml_node el); +void parseTupletTypeContent(TupletType &out, pugi::xml_node el, const ParseContext &context); + void serializeTupletType(const TupletType &v, pugi::xml_node parent, const char *tag); void serializeTupletTypeContent(const TupletType &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/TwoNoteTurn.cpp b/src/private/mx/core/generated/TwoNoteTurn.cpp index 4768f8459..7f801fb26 100644 --- a/src/private/mx/core/generated/TwoNoteTurn.cpp +++ b/src/private/mx/core/generated/TwoNoteTurn.cpp @@ -48,9 +48,15 @@ bool TwoNoteTurn::tryParse(std::string_view text, TwoNoteTurn &out) noexcept } TwoNoteTurn TwoNoteTurn::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +TwoNoteTurn TwoNoteTurn::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { TwoNoteTurn v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/TwoNoteTurn.h b/src/private/mx/core/generated/TwoNoteTurn.h index a92e168ca..1919cccfd 100644 --- a/src/private/mx/core/generated/TwoNoteTurn.h +++ b/src/private/mx/core/generated/TwoNoteTurn.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -43,6 +45,9 @@ class TwoNoteTurn final /// (the import leniency policy; never produces an invalid value). static TwoNoteTurn parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static TwoNoteTurn parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const TwoNoteTurn &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/TypedText.cpp b/src/private/mx/core/generated/TypedText.cpp index 9b94475da..0b4dfbbdb 100644 --- a/src/private/mx/core/generated/TypedText.cpp +++ b/src/private/mx/core/generated/TypedText.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/TypedText.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void TypedText::setValue(std::string value) } TypedText parseTypedText(pugi::xml_node el) +{ + return parseTypedText(el, ParseContext{}); +} + +TypedText parseTypedText(pugi::xml_node el, const ParseContext &context) { TypedText out; for (pugi::xml_attribute a : el.attributes()) @@ -49,11 +55,16 @@ TypedText parseTypedText(pugi::xml_node el) throwUnknownAttribute(el, a.name()); } } - parseTypedTextContent(out, el); + parseTypedTextContent(out, el, context); return out; } void parseTypedTextContent(TypedText &out, pugi::xml_node el) +{ + parseTypedTextContent(out, el, ParseContext{}); +} + +void parseTypedTextContent(TypedText &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); if (firstElement(el)) diff --git a/src/private/mx/core/generated/TypedText.h b/src/private/mx/core/generated/TypedText.h index a7fe1f35a..b98d51af4 100644 --- a/src/private/mx/core/generated/TypedText.h +++ b/src/private/mx/core/generated/TypedText.h @@ -13,6 +13,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The typed-text type represents a text element with a type attribute. class TypedText final { @@ -30,8 +32,12 @@ class TypedText final TypedText parseTypedText(pugi::xml_node el); +TypedText parseTypedText(pugi::xml_node el, const ParseContext &context); + void parseTypedTextContent(TypedText &out, pugi::xml_node el); +void parseTypedTextContent(TypedText &out, pugi::xml_node el, const ParseContext &context); + void serializeTypedText(const TypedText &v, pugi::xml_node parent, const char *tag); void serializeTypedTextContent(const TypedText &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Unpitched.cpp b/src/private/mx/core/generated/Unpitched.cpp index 9868ba894..d247cc792 100644 --- a/src/private/mx/core/generated/Unpitched.cpp +++ b/src/private/mx/core/generated/Unpitched.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Unpitched.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -21,6 +22,11 @@ void Unpitched::setDisplayStepOctave(std::optional value } Unpitched parseUnpitched(pugi::xml_node el) +{ + return parseUnpitched(el, ParseContext{}); +} + +Unpitched parseUnpitched(pugi::xml_node el, const ParseContext &context) { Unpitched out; for (pugi::xml_attribute a : el.attributes()) @@ -32,16 +38,21 @@ Unpitched parseUnpitched(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseUnpitchedContent(out, el); + parseUnpitchedContent(out, el, context); return out; } void parseUnpitchedContent(Unpitched &out, pugi::xml_node el) +{ + parseUnpitchedContent(out, el, ParseContext{}); +} + +void parseUnpitchedContent(Unpitched &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursor && (cursorIs(cursor, "display-step"))) { - out.setDisplayStepOctave(parseDisplayStepOctaveGroup(el, cursor)); + out.setDisplayStepOctave(parseDisplayStepOctaveGroup(el, cursor, context)); } if (cursor) { diff --git a/src/private/mx/core/generated/Unpitched.h b/src/private/mx/core/generated/Unpitched.h index fc673eed5..815d535bb 100644 --- a/src/private/mx/core/generated/Unpitched.h +++ b/src/private/mx/core/generated/Unpitched.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The unpitched type represents musical elements that are notated on the staff but lack definite /// pitch, such as unpitched percussion and speaking voice. If the child elements are not present, /// the note is placed on the middle line of the staff. This is generally used with a one-line staff. @@ -36,8 +38,12 @@ class Unpitched final Unpitched parseUnpitched(pugi::xml_node el); +Unpitched parseUnpitched(pugi::xml_node el, const ParseContext &context); + void parseUnpitchedContent(Unpitched &out, pugi::xml_node el); +void parseUnpitchedContent(Unpitched &out, pugi::xml_node el, const ParseContext &context); + void serializeUnpitched(const Unpitched &v, pugi::xml_node parent, const char *tag); void serializeUnpitchedContent(const Unpitched &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/UpDown.cpp b/src/private/mx/core/generated/UpDown.cpp index 411a68e32..6106d179e 100644 --- a/src/private/mx/core/generated/UpDown.cpp +++ b/src/private/mx/core/generated/UpDown.cpp @@ -42,9 +42,15 @@ bool UpDown::tryParse(std::string_view text, UpDown &out) noexcept } UpDown UpDown::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +UpDown UpDown::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { UpDown v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/UpDown.h b/src/private/mx/core/generated/UpDown.h index 4b9e0137c..633191797 100644 --- a/src/private/mx/core/generated/UpDown.h +++ b/src/private/mx/core/generated/UpDown.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -41,6 +43,9 @@ class UpDown final /// (the import leniency policy; never produces an invalid value). static UpDown parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static UpDown parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const UpDown &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/UpDownStopContinue.cpp b/src/private/mx/core/generated/UpDownStopContinue.cpp index eec3a75ad..3b3179ad3 100644 --- a/src/private/mx/core/generated/UpDownStopContinue.cpp +++ b/src/private/mx/core/generated/UpDownStopContinue.cpp @@ -54,9 +54,15 @@ bool UpDownStopContinue::tryParse(std::string_view text, UpDownStopContinue &out } UpDownStopContinue UpDownStopContinue::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +UpDownStopContinue UpDownStopContinue::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { UpDownStopContinue v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/UpDownStopContinue.h b/src/private/mx/core/generated/UpDownStopContinue.h index 02a93473e..8b8dfaf7d 100644 --- a/src/private/mx/core/generated/UpDownStopContinue.h +++ b/src/private/mx/core/generated/UpDownStopContinue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -45,6 +47,9 @@ class UpDownStopContinue final /// (the import leniency policy; never produces an invalid value). static UpDownStopContinue parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static UpDownStopContinue parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const UpDownStopContinue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/UprightInverted.cpp b/src/private/mx/core/generated/UprightInverted.cpp index ba42097de..4780107f5 100644 --- a/src/private/mx/core/generated/UprightInverted.cpp +++ b/src/private/mx/core/generated/UprightInverted.cpp @@ -42,9 +42,15 @@ bool UprightInverted::tryParse(std::string_view text, UprightInverted &out) noex } UprightInverted UprightInverted::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +UprightInverted UprightInverted::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { UprightInverted v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/UprightInverted.h b/src/private/mx/core/generated/UprightInverted.h index dfc9d8b2d..83e06e9c0 100644 --- a/src/private/mx/core/generated/UprightInverted.h +++ b/src/private/mx/core/generated/UprightInverted.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -41,6 +43,9 @@ class UprightInverted final /// (the import leniency policy; never produces an invalid value). static UprightInverted parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static UprightInverted parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const UprightInverted &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Valign.cpp b/src/private/mx/core/generated/Valign.cpp index 66cadc7d0..45c3361ed 100644 --- a/src/private/mx/core/generated/Valign.cpp +++ b/src/private/mx/core/generated/Valign.cpp @@ -54,9 +54,15 @@ bool Valign::tryParse(std::string_view text, Valign &out) noexcept } Valign Valign::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +Valign Valign::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { Valign v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/Valign.h b/src/private/mx/core/generated/Valign.h index 5ef8b9bc9..cf5c13aa5 100644 --- a/src/private/mx/core/generated/Valign.h +++ b/src/private/mx/core/generated/Valign.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -46,6 +48,9 @@ class Valign final /// (the import leniency policy; never produces an invalid value). static Valign parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static Valign parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const Valign &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/ValignImage.cpp b/src/private/mx/core/generated/ValignImage.cpp index 94cc287d0..38226cf4f 100644 --- a/src/private/mx/core/generated/ValignImage.cpp +++ b/src/private/mx/core/generated/ValignImage.cpp @@ -48,9 +48,15 @@ bool ValignImage::tryParse(std::string_view text, ValignImage &out) noexcept } ValignImage ValignImage::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +ValignImage ValignImage::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { ValignImage v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/ValignImage.h b/src/private/mx/core/generated/ValignImage.h index e1f4a595f..c05cc38fd 100644 --- a/src/private/mx/core/generated/ValignImage.h +++ b/src/private/mx/core/generated/ValignImage.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -43,6 +45,9 @@ class ValignImage final /// (the import leniency policy; never produces an invalid value). static ValignImage parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static ValignImage parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const ValignImage &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/VirtualInstrument.cpp b/src/private/mx/core/generated/VirtualInstrument.cpp index 972697a79..14006ff4d 100644 --- a/src/private/mx/core/generated/VirtualInstrument.cpp +++ b/src/private/mx/core/generated/VirtualInstrument.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/VirtualInstrument.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void VirtualInstrument::setVirtualName(std::optional value) } VirtualInstrument parseVirtualInstrument(pugi::xml_node el) +{ + return parseVirtualInstrument(el, ParseContext{}); +} + +VirtualInstrument parseVirtualInstrument(pugi::xml_node el, const ParseContext &context) { VirtualInstrument out; for (pugi::xml_attribute a : el.attributes()) @@ -42,11 +48,16 @@ VirtualInstrument parseVirtualInstrument(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseVirtualInstrumentContent(out, el); + parseVirtualInstrumentContent(out, el, context); return out; } void parseVirtualInstrumentContent(VirtualInstrument &out, pugi::xml_node el) +{ + parseVirtualInstrumentContent(out, el, ParseContext{}); +} + +void parseVirtualInstrumentContent(VirtualInstrument &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "virtual-library")) diff --git a/src/private/mx/core/generated/VirtualInstrument.h b/src/private/mx/core/generated/VirtualInstrument.h index 570a7eccd..973639720 100644 --- a/src/private/mx/core/generated/VirtualInstrument.h +++ b/src/private/mx/core/generated/VirtualInstrument.h @@ -15,6 +15,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The virtual-instrument element defines a specific virtual instrument used for an instrument /// sound. /// Content fields mirror the schema grammar in declaration order; the @@ -35,8 +37,12 @@ class VirtualInstrument final VirtualInstrument parseVirtualInstrument(pugi::xml_node el); +VirtualInstrument parseVirtualInstrument(pugi::xml_node el, const ParseContext &context); + void parseVirtualInstrumentContent(VirtualInstrument &out, pugi::xml_node el); +void parseVirtualInstrumentContent(VirtualInstrument &out, pugi::xml_node el, const ParseContext &context); + void serializeVirtualInstrument(const VirtualInstrument &v, pugi::xml_node parent, const char *tag); void serializeVirtualInstrumentContent(const VirtualInstrument &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/VirtualInstrumentDataGroup.cpp b/src/private/mx/core/generated/VirtualInstrumentDataGroup.cpp index 00713ebad..fa0b7a7e4 100644 --- a/src/private/mx/core/generated/VirtualInstrumentDataGroup.cpp +++ b/src/private/mx/core/generated/VirtualInstrumentDataGroup.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/VirtualInstrumentDataGroup.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,20 +42,26 @@ void VirtualInstrumentDataGroup::setVirtualInstrument(std::optional(childText(cursor), context, cursor, nullptr)); cursor = nextElement(cursor); } if (cursor && (cursorIs(cursor, "solo") || cursorIs(cursor, "ensemble"))) { - out.setChoice(parseVirtualInstrumentDataGroupChoice(el, cursor)); + out.setChoice(parseVirtualInstrumentDataGroupChoice(el, cursor, context)); } if (cursorIs(cursor, "virtual-instrument")) { - out.setVirtualInstrument(parseVirtualInstrument(cursor)); + out.setVirtualInstrument(parseVirtualInstrument(cursor, context)); cursor = nextElement(cursor); } return out; diff --git a/src/private/mx/core/generated/VirtualInstrumentDataGroup.h b/src/private/mx/core/generated/VirtualInstrumentDataGroup.h index dff4fa865..7c52f6fbf 100644 --- a/src/private/mx/core/generated/VirtualInstrumentDataGroup.h +++ b/src/private/mx/core/generated/VirtualInstrumentDataGroup.h @@ -19,6 +19,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Virtual instrument data can be part of either the score-instrument element at the start of a /// part, or an instrument-change element within a part. /// A shared content group: transparent on the wire, its @@ -44,6 +46,9 @@ class VirtualInstrumentDataGroup final /// is the enclosing element, for error paths. VirtualInstrumentDataGroup parseVirtualInstrumentDataGroup(pugi::xml_node el, pugi::xml_node &cursor); +VirtualInstrumentDataGroup parseVirtualInstrumentDataGroup(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context); + void serializeVirtualInstrumentDataGroup(const VirtualInstrumentDataGroup &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/VirtualInstrumentDataGroupChoice.cpp b/src/private/mx/core/generated/VirtualInstrumentDataGroupChoice.cpp index 6d28f63c9..0bd3fa2af 100644 --- a/src/private/mx/core/generated/VirtualInstrumentDataGroupChoice.cpp +++ b/src/private/mx/core/generated/VirtualInstrumentDataGroupChoice.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/VirtualInstrumentDataGroupChoice.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -26,16 +27,22 @@ VirtualInstrumentDataGroupChoice VirtualInstrumentDataGroupChoice::ensemble(Posi } VirtualInstrumentDataGroupChoice parseVirtualInstrumentDataGroupChoice(pugi::xml_node el, pugi::xml_node &cursor) +{ + return parseVirtualInstrumentDataGroupChoice(el, cursor, ParseContext{}); +} + +VirtualInstrumentDataGroupChoice parseVirtualInstrumentDataGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context) { if (cursor && (cursorIs(cursor, "solo"))) { - Empty value = parseEmpty(cursor); + Empty value = parseEmpty(cursor, context); cursor = nextElement(cursor); return VirtualInstrumentDataGroupChoice::solo(std::move(value)); } if (cursor && (cursorIs(cursor, "ensemble"))) { - PositiveIntegerOrEmpty value = PositiveIntegerOrEmpty::parse(childText(cursor)); + PositiveIntegerOrEmpty value = parseValue(childText(cursor), context, cursor, nullptr); cursor = nextElement(cursor); return VirtualInstrumentDataGroupChoice::ensemble(std::move(value)); } diff --git a/src/private/mx/core/generated/VirtualInstrumentDataGroupChoice.h b/src/private/mx/core/generated/VirtualInstrumentDataGroupChoice.h index c8c7bafe1..d850346b5 100644 --- a/src/private/mx/core/generated/VirtualInstrumentDataGroupChoice.h +++ b/src/private/mx/core/generated/VirtualInstrumentDataGroupChoice.h @@ -18,6 +18,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// A schema choice (synthesized from an anonymous particle /// of the schema): exactly one alternative by construction. /// Alternatives are positional; dispatch is by Kind/index, never by type @@ -82,6 +84,9 @@ class VirtualInstrumentDataGroupChoice final /// the enclosing element, for error paths. VirtualInstrumentDataGroupChoice parseVirtualInstrumentDataGroupChoice(pugi::xml_node el, pugi::xml_node &cursor); +VirtualInstrumentDataGroupChoice parseVirtualInstrumentDataGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, + const ParseContext &context); + void serializeVirtualInstrumentDataGroupChoice(const VirtualInstrumentDataGroupChoice &v, pugi::xml_node el); } // namespace mx::core diff --git a/src/private/mx/core/generated/Wait.cpp b/src/private/mx/core/generated/Wait.cpp index 57ceac38d..019ef7f80 100644 --- a/src/private/mx/core/generated/Wait.cpp +++ b/src/private/mx/core/generated/Wait.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Wait.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void Wait::setTimeOnly(std::optional value) } Wait parseWait(pugi::xml_node el) +{ + return parseWait(el, ParseContext{}); +} + +Wait parseWait(pugi::xml_node el, const ParseContext &context) { Wait out; for (pugi::xml_attribute a : el.attributes()) @@ -46,20 +52,26 @@ Wait parseWait(pugi::xml_node el) } else if (aname == "time-only") { - out.setTimeOnly(TimeOnly::parse(a.value())); + out.setTimeOnly(parseValue(a.value(), context, el, "time-only")); } else { throwUnknownAttribute(el, a.name()); } } - parseWaitContent(out, el); + parseWaitContent(out, el, context); return out; } void parseWaitContent(Wait &out, pugi::xml_node el) +{ + parseWaitContent(out, el, ParseContext{}); +} + +void parseWaitContent(Wait &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Wait.h b/src/private/mx/core/generated/Wait.h index af2473fcc..fbe6ca33a 100644 --- a/src/private/mx/core/generated/Wait.h +++ b/src/private/mx/core/generated/Wait.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The wait type specifies a point where the accompaniment should wait for a performer event before /// continuing. This typically happens at the start of new sections or after a held note or /// indeterminate music. These waiting points cannot always be inferred reliably from the contents of @@ -38,8 +40,12 @@ class Wait final Wait parseWait(pugi::xml_node el); +Wait parseWait(pugi::xml_node el, const ParseContext &context); + void parseWaitContent(Wait &out, pugi::xml_node el); +void parseWaitContent(Wait &out, pugi::xml_node el, const ParseContext &context); + void serializeWait(const Wait &v, pugi::xml_node parent, const char *tag); void serializeWaitContent(const Wait &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/WavyLine.cpp b/src/private/mx/core/generated/WavyLine.cpp index 1eaec5487..ecc9fcdb9 100644 --- a/src/private/mx/core/generated/WavyLine.cpp +++ b/src/private/mx/core/generated/WavyLine.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/WavyLine.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -171,6 +172,11 @@ void WavyLine::setLastBeat(std::optional value) } WavyLine parseWavyLine(pugi::xml_node el) +{ + return parseWavyLine(el, ParseContext{}); +} + +WavyLine parseWavyLine(pugi::xml_node el, const ParseContext &context) { WavyLine out; bool seen_type = false; @@ -184,67 +190,67 @@ WavyLine parseWavyLine(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(StartStopContinue::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "number") { - out.setNumber(NumberLevel::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else if (aname == "smufl") { - out.setSmufl(SmuflWavyLineGlyphName::parse(a.value())); + out.setSmufl(parseValue(a.value(), context, el, "smufl")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "placement") { - out.setPlacement(AboveBelow::parse(a.value())); + out.setPlacement(parseValue(a.value(), context, el, "placement")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "start-note") { - out.setStartNote(StartNote::parse(a.value())); + out.setStartNote(parseValue(a.value(), context, el, "start-note")); } else if (aname == "trill-step") { - out.setTrillStep(TrillStep::parse(a.value())); + out.setTrillStep(parseValue(a.value(), context, el, "trill-step")); } else if (aname == "two-note-turn") { - out.setTwoNoteTurn(TwoNoteTurn::parse(a.value())); + out.setTwoNoteTurn(parseValue(a.value(), context, el, "two-note-turn")); } else if (aname == "accelerate") { - out.setAccelerate(YesNo::parse(a.value())); + out.setAccelerate(parseValue(a.value(), context, el, "accelerate")); } else if (aname == "beats") { - out.setBeats(TrillBeats::parse(a.value())); + out.setBeats(parseValue(a.value(), context, el, "beats")); } else if (aname == "second-beat") { - out.setSecondBeat(Percent::parse(a.value())); + out.setSecondBeat(parseValue(a.value(), context, el, "second-beat")); } else if (aname == "last-beat") { - out.setLastBeat(Percent::parse(a.value())); + out.setLastBeat(parseValue(a.value(), context, el, "last-beat")); } else { @@ -255,13 +261,19 @@ WavyLine parseWavyLine(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseWavyLineContent(out, el); + parseWavyLineContent(out, el, context); return out; } void parseWavyLineContent(WavyLine &out, pugi::xml_node el) +{ + parseWavyLineContent(out, el, ParseContext{}); +} + +void parseWavyLineContent(WavyLine &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/WavyLine.h b/src/private/mx/core/generated/WavyLine.h index 155f677cd..55161bc55 100644 --- a/src/private/mx/core/generated/WavyLine.h +++ b/src/private/mx/core/generated/WavyLine.h @@ -26,6 +26,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Wavy lines are one way to indicate trills and vibrato. When used with a barline element, they /// should always have type="continue" set. The smufl attribute specifies a particular wavy line /// glyph from the SMuFL Multi-segment lines range. @@ -87,8 +89,12 @@ class WavyLine final WavyLine parseWavyLine(pugi::xml_node el); +WavyLine parseWavyLine(pugi::xml_node el, const ParseContext &context); + void parseWavyLineContent(WavyLine &out, pugi::xml_node el); +void parseWavyLineContent(WavyLine &out, pugi::xml_node el, const ParseContext &context); + void serializeWavyLine(const WavyLine &v, pugi::xml_node parent, const char *tag); void serializeWavyLineContent(const WavyLine &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Wedge.cpp b/src/private/mx/core/generated/Wedge.cpp index 4def125e5..01915f407 100644 --- a/src/private/mx/core/generated/Wedge.cpp +++ b/src/private/mx/core/generated/Wedge.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Wedge.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -141,6 +142,11 @@ void Wedge::setID(std::optional value) } Wedge parseWedge(pugi::xml_node el) +{ + return parseWedge(el, ParseContext{}); +} + +Wedge parseWedge(pugi::xml_node el, const ParseContext &context) { Wedge out; bool seen_type = false; @@ -154,51 +160,51 @@ Wedge parseWedge(pugi::xml_node el) if (aname == "type") { seen_type = true; - out.setType(WedgeType::parse(a.value())); + out.setType(parseValue(a.value(), context, el, "type")); } else if (aname == "number") { - out.setNumber(NumberLevel::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else if (aname == "spread") { - out.setSpread(Tenths::parse(a.value())); + out.setSpread(parseValue(a.value(), context, el, "spread")); } else if (aname == "niente") { - out.setNiente(YesNo::parse(a.value())); + out.setNiente(parseValue(a.value(), context, el, "niente")); } else if (aname == "line-type") { - out.setLineType(LineType::parse(a.value())); + out.setLineType(parseValue(a.value(), context, el, "line-type")); } else if (aname == "dash-length") { - out.setDashLength(Tenths::parse(a.value())); + out.setDashLength(parseValue(a.value(), context, el, "dash-length")); } else if (aname == "space-length") { - out.setSpaceLength(Tenths::parse(a.value())); + out.setSpaceLength(parseValue(a.value(), context, el, "space-length")); } else if (aname == "default-x") { - out.setDefaultX(Tenths::parse(a.value())); + out.setDefaultX(parseValue(a.value(), context, el, "default-x")); } else if (aname == "default-y") { - out.setDefaultY(Tenths::parse(a.value())); + out.setDefaultY(parseValue(a.value(), context, el, "default-y")); } else if (aname == "relative-x") { - out.setRelativeX(Tenths::parse(a.value())); + out.setRelativeX(parseValue(a.value(), context, el, "relative-x")); } else if (aname == "relative-y") { - out.setRelativeY(Tenths::parse(a.value())); + out.setRelativeY(parseValue(a.value(), context, el, "relative-y")); } else if (aname == "color") { - out.setColor(Color::parse(a.value())); + out.setColor(parseValue(a.value(), context, el, "color")); } else if (aname == "id") { @@ -213,13 +219,19 @@ Wedge parseWedge(pugi::xml_node el) { throwMissingAttribute(el, "type"); } - parseWedgeContent(out, el); + parseWedgeContent(out, el, context); return out; } void parseWedgeContent(Wedge &out, pugi::xml_node el) +{ + parseWedgeContent(out, el, ParseContext{}); +} + +void parseWedgeContent(Wedge &out, pugi::xml_node el, const ParseContext &context) { (void)out; + (void)context; if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Wedge.h b/src/private/mx/core/generated/Wedge.h index 01d8c223d..666939f3a 100644 --- a/src/private/mx/core/generated/Wedge.h +++ b/src/private/mx/core/generated/Wedge.h @@ -22,6 +22,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The wedge type represents crescendo and diminuendo wedge symbols. The type attribute is crescendo /// for the start of a wedge that is closed at the left side, and diminuendo for the start of a wedge /// that is closed on the right side. Spread values are measured in tenths; those at the start of a @@ -78,8 +80,12 @@ class Wedge final Wedge parseWedge(pugi::xml_node el); +Wedge parseWedge(pugi::xml_node el, const ParseContext &context); + void parseWedgeContent(Wedge &out, pugi::xml_node el); +void parseWedgeContent(Wedge &out, pugi::xml_node el, const ParseContext &context); + void serializeWedge(const Wedge &v, pugi::xml_node parent, const char *tag); void serializeWedgeContent(const Wedge &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/WedgeType.cpp b/src/private/mx/core/generated/WedgeType.cpp index 16d431dc7..2b7903ec6 100644 --- a/src/private/mx/core/generated/WedgeType.cpp +++ b/src/private/mx/core/generated/WedgeType.cpp @@ -54,9 +54,15 @@ bool WedgeType::tryParse(std::string_view text, WedgeType &out) noexcept } WedgeType WedgeType::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +WedgeType WedgeType::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { WedgeType v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/WedgeType.h b/src/private/mx/core/generated/WedgeType.h index 42a91ffa1..b640fe406 100644 --- a/src/private/mx/core/generated/WedgeType.h +++ b/src/private/mx/core/generated/WedgeType.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -47,6 +49,9 @@ class WedgeType final /// (the import leniency policy; never produces an invalid value). static WedgeType parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static WedgeType parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const WedgeType &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Winged.cpp b/src/private/mx/core/generated/Winged.cpp index 7db6bdc18..f532f2ca4 100644 --- a/src/private/mx/core/generated/Winged.cpp +++ b/src/private/mx/core/generated/Winged.cpp @@ -56,9 +56,15 @@ bool Winged::tryParse(std::string_view text, Winged &out) noexcept } Winged Winged::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +Winged Winged::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { Winged v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/Winged.h b/src/private/mx/core/generated/Winged.h index fc151a2cd..600b21e12 100644 --- a/src/private/mx/core/generated/Winged.h +++ b/src/private/mx/core/generated/Winged.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -49,6 +51,9 @@ class Winged final /// (the import leniency policy; never produces an invalid value). static Winged parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static Winged parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const Winged &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Wood.cpp b/src/private/mx/core/generated/Wood.cpp index cd8b2c6cd..0b5e761d5 100644 --- a/src/private/mx/core/generated/Wood.cpp +++ b/src/private/mx/core/generated/Wood.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Wood.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -31,6 +32,11 @@ void Wood::setValue(WoodValue value) } Wood parseWood(pugi::xml_node el) +{ + return parseWood(el, ParseContext{}); +} + +Wood parseWood(pugi::xml_node el, const ParseContext &context) { Wood out; for (pugi::xml_attribute a : el.attributes()) @@ -42,20 +48,25 @@ Wood parseWood(pugi::xml_node el) } if (aname == "smufl") { - out.setSmufl(SmuflPictogramGlyphName::parse(a.value())); + out.setSmufl(parseValue(a.value(), context, el, "smufl")); } else { throwUnknownAttribute(el, a.name()); } } - parseWoodContent(out, el); + parseWoodContent(out, el, context); return out; } void parseWoodContent(Wood &out, pugi::xml_node el) { - out.setValue(WoodValue::parse(childText(el))); + parseWoodContent(out, el, ParseContext{}); +} + +void parseWoodContent(Wood &out, pugi::xml_node el, const ParseContext &context) +{ + out.setValue(parseValue(childText(el), context, el, nullptr)); if (firstElement(el)) { throwUnknownElement(firstElement(el)); diff --git a/src/private/mx/core/generated/Wood.h b/src/private/mx/core/generated/Wood.h index a300eb2f1..eea30a88c 100644 --- a/src/private/mx/core/generated/Wood.h +++ b/src/private/mx/core/generated/Wood.h @@ -16,6 +16,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// The wood type represents pictograms for wood percussion instruments. The smufl attribute is used /// to distinguish different SMuFL stylistic alternates. class Wood final @@ -34,8 +36,12 @@ class Wood final Wood parseWood(pugi::xml_node el); +Wood parseWood(pugi::xml_node el, const ParseContext &context); + void parseWoodContent(Wood &out, pugi::xml_node el); +void parseWoodContent(Wood &out, pugi::xml_node el, const ParseContext &context); + void serializeWood(const Wood &v, pugi::xml_node parent, const char *tag); void serializeWoodContent(const Wood &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/WoodValue.cpp b/src/private/mx/core/generated/WoodValue.cpp index 957a0f370..db1b1004e 100644 --- a/src/private/mx/core/generated/WoodValue.cpp +++ b/src/private/mx/core/generated/WoodValue.cpp @@ -140,9 +140,15 @@ bool WoodValue::tryParse(std::string_view text, WoodValue &out) noexcept } WoodValue WoodValue::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +WoodValue WoodValue::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { WoodValue v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/WoodValue.h b/src/private/mx/core/generated/WoodValue.h index 8edbe6616..3896ee371 100644 --- a/src/private/mx/core/generated/WoodValue.h +++ b/src/private/mx/core/generated/WoodValue.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -79,6 +81,9 @@ class WoodValue final /// (the import leniency policy; never produces an invalid value). static WoodValue parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static WoodValue parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const WoodValue &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/Work.cpp b/src/private/mx/core/generated/Work.cpp index 5372ede37..4a2db105c 100644 --- a/src/private/mx/core/generated/Work.cpp +++ b/src/private/mx/core/generated/Work.cpp @@ -3,6 +3,7 @@ #include "mx/core/generated/Work.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include @@ -41,6 +42,11 @@ void Work::setOpus(std::optional value) } Work parseWork(pugi::xml_node el) +{ + return parseWork(el, ParseContext{}); +} + +Work parseWork(pugi::xml_node el, const ParseContext &context) { Work out; for (pugi::xml_attribute a : el.attributes()) @@ -52,11 +58,16 @@ Work parseWork(pugi::xml_node el) } throwUnknownAttribute(el, a.name()); } - parseWorkContent(out, el); + parseWorkContent(out, el, context); return out; } void parseWorkContent(Work &out, pugi::xml_node el) +{ + parseWorkContent(out, el, ParseContext{}); +} + +void parseWorkContent(Work &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); if (cursorIs(cursor, "work-number")) @@ -71,7 +82,7 @@ void parseWorkContent(Work &out, pugi::xml_node el) } if (cursorIs(cursor, "opus")) { - out.setOpus(parseOpus(cursor)); + out.setOpus(parseOpus(cursor, context)); cursor = nextElement(cursor); } if (cursor) diff --git a/src/private/mx/core/generated/Work.h b/src/private/mx/core/generated/Work.h index 57bffda99..6d6100e2a 100644 --- a/src/private/mx/core/generated/Work.h +++ b/src/private/mx/core/generated/Work.h @@ -17,6 +17,8 @@ class xml_node; namespace mx::core { +class ParseContext; + /// Works are optionally identified by number and title. The work type also may indicate a link to /// the opus document that composes multiple scores into a collection. /// Content fields mirror the schema grammar in declaration order; the @@ -40,8 +42,12 @@ class Work final Work parseWork(pugi::xml_node el); +Work parseWork(pugi::xml_node el, const ParseContext &context); + void parseWorkContent(Work &out, pugi::xml_node el); +void parseWorkContent(Work &out, pugi::xml_node el, const ParseContext &context); + void serializeWork(const Work &v, pugi::xml_node parent, const char *tag); void serializeWorkContent(const Work &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/YesNo.cpp b/src/private/mx/core/generated/YesNo.cpp index 2b3bceb94..11796f5fc 100644 --- a/src/private/mx/core/generated/YesNo.cpp +++ b/src/private/mx/core/generated/YesNo.cpp @@ -42,9 +42,15 @@ bool YesNo::tryParse(std::string_view text, YesNo &out) noexcept } YesNo YesNo::parse(std::string_view text) noexcept +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +YesNo YesNo::parse(std::string_view text, ValueParseOutcome &outcome) noexcept { YesNo v; - tryParse(text, v); + outcome = tryParse(text, v) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; return v; } diff --git a/src/private/mx/core/generated/YesNo.h b/src/private/mx/core/generated/YesNo.h index 7b179a7de..50cd2ef61 100644 --- a/src/private/mx/core/generated/YesNo.h +++ b/src/private/mx/core/generated/YesNo.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include namespace mx::core @@ -41,6 +43,9 @@ class YesNo final /// (the import leniency policy; never produces an invalid value). static YesNo parse(std::string_view text) noexcept; + /// Lenient, and says whether the literal was recognized. + static YesNo parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const YesNo &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/YesNoNumber.cpp b/src/private/mx/core/generated/YesNoNumber.cpp index 22b7da4f4..ad9af77ec 100644 --- a/src/private/mx/core/generated/YesNoNumber.cpp +++ b/src/private/mx/core/generated/YesNoNumber.cpp @@ -59,12 +59,20 @@ bool YesNoNumber::tryParse(std::string_view text, YesNoNumber &out) } YesNoNumber YesNoNumber::parse(std::string_view text) +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + return parse(text, outcome); +} + +YesNoNumber YesNoNumber::parse(std::string_view text, ValueParseOutcome &outcome) { YesNoNumber out; if (tryParse(text, out)) { + outcome = ValueParseOutcome::valid; return out; } + outcome = ValueParseOutcome::invalid; return YesNoNumber::yesNo(YesNo::parse(text)); } diff --git a/src/private/mx/core/generated/YesNoNumber.h b/src/private/mx/core/generated/YesNoNumber.h index dece695ca..e13602bbf 100644 --- a/src/private/mx/core/generated/YesNoNumber.h +++ b/src/private/mx/core/generated/YesNoNumber.h @@ -3,6 +3,7 @@ #pragma once #include "mx/core/Decimal.h" +#include "mx/core/Lexical.h" #include "mx/core/generated/YesNo.h" #include @@ -69,6 +70,10 @@ class YesNoNumber final /// parse (never produces an invalid value). static YesNoNumber parse(std::string_view text); + /// Lenient, and says whether no member matched or a matched number was + /// clamped. + static YesNoNumber parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const YesNoNumber &other) const = default; private: diff --git a/src/private/mx/examples/Read.cpp b/src/private/mx/examples/Read.cpp index 6ccc76e3b..1ba18dda6 100644 --- a/src/private/mx/examples/Read.cpp +++ b/src/private/mx/examples/Read.cpp @@ -56,17 +56,17 @@ int main(int argc, const char *argv[]) // place the xml from above into a stream object std::istringstream istr{xml}; + // collect any non-fatal adjustments made while reading. A handler may + // also display each one as it is found. + Diagnostics diagnostics{[](const Diagnostic &diagnostic) { std::cerr << formatDiagnostic(diagnostic) << '\n'; }}; + // parse the xml into a MusicXml document that we own - auto docResult = MusicXml::fromStream(istr); + auto docResult = MusicXml::fromStream(istr, diagnostics); if (!docResult.ok()) { return MX_IS_A_FAILURE; } - // collect any non-fatal adjustments made while reading. A handler may - // also display each one as it is found. - Diagnostics diagnostics{[](const Diagnostic &diagnostic) { std::cerr << formatDiagnostic(diagnostic) << '\n'; }}; - // take the score out of the document. intoScore also consumes the // document, so its memory is freed as the function returns const auto scoreResult = intoScore(std::move(docResult).value(), diagnostics); diff --git a/src/private/mxtest/api/DiagnosticsTest.cpp b/src/private/mxtest/api/DiagnosticsTest.cpp index fa7ff8ed6..98d371b25 100644 --- a/src/private/mxtest/api/DiagnosticsTest.cpp +++ b/src/private/mxtest/api/DiagnosticsTest.cpp @@ -11,7 +11,9 @@ #include "mx/api/MusicXml.h" #include "mx/api/OttavaData.h" #include "mx/api/ScoreData.h" +#include "mxtest/file/StupidFileFunctions.h" +#include #include #include #include @@ -65,6 +67,41 @@ inline std::string diagnosticsTimeSignatureXml() )"; } +inline std::string diagnosticsImportRepairXml() +{ + return R"( + + Music + + + + 1 + + 1 + + 11banana + + +)"; +} + +inline void diagnosticsCheckRethrowsHandlerFailure(const ApiError &error) +{ + CHECK(ResultCode::internalError == error.code); + REQUIRE(error.cause); + bool caughtExpected = false; + try + { + std::rethrow_exception(error.cause); + } + catch (const std::runtime_error &cause) + { + caughtExpected = true; + CHECK_EQUAL(std::string{"handler failed"}, std::string{cause.what()}); + } + CHECK(caughtExpected); +} + TEST(diagnosticsCollectAndInvokeHandlerInOrder, Diagnostics) { auto score = diagnosticsScore(2); @@ -187,19 +224,92 @@ TEST(throwingDiagnosticHandlerBecomesInternalError, Diagnostics) const auto result = fromScore(score, diagnostics); REQUIRE(!result.ok()); - CHECK(ResultCode::internalError == result.error().code); - REQUIRE(result.error().cause); - bool caughtExpected = false; - try - { - std::rethrow_exception(result.error().cause); - } - catch (const std::runtime_error &error) + diagnosticsCheckRethrowsHandlerFailure(result.error()); +} + +T_END + +TEST(fromStreamReportsImportRepairs, Diagnostics) +{ + std::istringstream stream{diagnosticsImportRepairXml()}; + Diagnostics diagnostics; + const auto document = MusicXml::fromStream(stream, diagnostics); + REQUIRE(document.ok()); + REQUIRE(diagnostics.all().size() == 1); + + const auto &diagnostic = diagnostics.all().front(); + CHECK(Severity::warning == diagnostic.severity); + CHECK(DiagnosticCode::invalidValue == diagnostic.code); + CHECK_EQUAL(std::string{"mx: warning at /score-partwise/part/measure/note/type: " + "invalid value \"banana\"; using \"1024th\""}, + formatDiagnostic(diagnostic)); +} + +T_END + +TEST(fromFileReportsImportRepairs, Diagnostics) +{ + const std::string path = mxtest::filePath(mxtest::TEST_OUTPUT_DIRECTORY_NAME, "DiagnosticsImportRepair.musicxml"); { - caughtExpected = true; - CHECK_EQUAL(std::string{"handler failed"}, std::string{error.what()}); + std::ofstream file{path}; + file << diagnosticsImportRepairXml(); } - CHECK(caughtExpected); + Diagnostics diagnostics; + const auto document = MusicXml::fromFile(path, diagnostics); + mxtest::deleteFileNoThrow(path); + REQUIRE(document.ok()); + REQUIRE(diagnostics.all().size() == 1); + CHECK(DiagnosticCode::invalidValue == diagnostics.all().front().code); + CHECK_EQUAL(std::string{"/score-partwise/part/measure/note/type"}, diagnostics.all().front().location.xmlPath); +} + +T_END + +TEST(oneCollectionSpansImportAndTranslation, Diagnostics) +{ + std::istringstream stream{diagnosticsImportRepairXml()}; + Diagnostics diagnostics; + const auto document = MusicXml::fromStream(stream, diagnostics); + REQUIRE(document.ok()); + REQUIRE(diagnostics.all().size() == 1); + + const auto score = getScore(document.value(), diagnostics); + REQUIRE(score.ok()); + REQUIRE(diagnostics.all().size() == 2); + CHECK(DiagnosticCode::invalidValue == diagnostics.all()[0].code); + CHECK(DiagnosticCode::valueAdjusted == diagnostics.all()[1].code); + CHECK_EQUAL(0, diagnostics.all()[1].location.measureIndex); +} + +T_END + +TEST(importWithoutDiagnosticsReadsTheSameDocument, Diagnostics) +{ + std::istringstream silentStream{diagnosticsImportRepairXml()}; + const auto silent = MusicXml::fromStream(silentStream); + std::istringstream observedStream{diagnosticsImportRepairXml()}; + Diagnostics diagnostics; + const auto observed = MusicXml::fromStream(observedStream, diagnostics); + REQUIRE(silent.ok()); + REQUIRE(observed.ok()); + CHECK(!diagnostics.all().empty()); + + std::ostringstream silentXml; + std::ostringstream observedXml; + REQUIRE(silent.value().writeToStream(silentXml).ok()); + REQUIRE(observed.value().writeToStream(observedXml).ok()); + CHECK_EQUAL(silentXml.str(), observedXml.str()); +} + +T_END + +TEST(throwingDiagnosticHandlerDuringImportBecomesInternalError, Diagnostics) +{ + std::istringstream stream{diagnosticsImportRepairXml()}; + Diagnostics diagnostics{[](const Diagnostic &) { throw std::runtime_error{"handler failed"}; }}; + const auto result = MusicXml::fromStream(stream, diagnostics); + REQUIRE(!result.ok()); + diagnosticsCheckRethrowsHandlerFailure(result.error()); } T_END diff --git a/src/private/mxtest/core/ImportDiagnosticsTest.cpp b/src/private/mxtest/core/ImportDiagnosticsTest.cpp new file mode 100644 index 000000000..fc777b022 --- /dev/null +++ b/src/private/mxtest/core/ImportDiagnosticsTest.cpp @@ -0,0 +1,153 @@ +// MusicXML Class Library +// Copyright (c) by Matthew James Briggs +// Distributed under the MIT License + +// Import repairs reported through a ParseContext. The lenient parsers still +// produce the same document; the diagnostics say what was changed and where. + +#include "cpul/cpulTestHarness.h" + +#include "mx/core/ParseContext.h" +#include "mx/core/generated/Document.h" + +#include "pugixml.hpp" + +#include +#include +#include + +using namespace mx::core; + +struct ImportDiagnosticsParse +{ + bool ok = false; + Document document; + std::vector diagnostics; +}; + +inline std::string importDiagnosticsScore(const std::string &defaults, const std::string &measureContent) +{ + return "" + defaults + + "Music" + "" + + measureContent + ""; +} + +inline std::string importDiagnosticsNote(const std::string &octave, const std::string &type = "") +{ + std::string note = "C" + octave + "1"; + if (!type.empty()) + { + note += "" + type + ""; + } + return note + ""; +} + +inline ImportDiagnosticsParse importDiagnosticsParse(const std::string &xml) +{ + ImportDiagnosticsParse out; + pugi::xml_document doc; + CHECK(doc.load_string(xml.c_str())); + const ParseContext context{[&out](const Diagnostic &diagnostic) { out.diagnostics.push_back(diagnostic); }}; + auto result = parse(doc, context); + out.ok = result.ok(); + if (result.ok()) + { + out.document = std::move(result).value(); + } + return out; +} + +TEST(UnknownEnumLiteralFallsBackToFirstVariant, ImportDiagnostics) +{ + const auto parsed = importDiagnosticsParse(importDiagnosticsScore("", importDiagnosticsNote("4", "banana"))); + REQUIRE(parsed.ok); + REQUIRE(parsed.diagnostics.size() == 1); + const Diagnostic &diagnostic = parsed.diagnostics.front(); + CHECK(DiagnosticCode::invalidValue == diagnostic.code); + CHECK_EQUAL(std::string{"/score-partwise/part/measure/note/type"}, diagnostic.path); + CHECK_EQUAL(std::string{"invalid value \"banana\"; using \"1024th\""}, diagnostic.message); +} + +TEST(MalformedAndOutOfRangeNumbersReportDifferentCodes, ImportDiagnostics) +{ + const auto parsed = + importDiagnosticsParse(importDiagnosticsScore("", importDiagnosticsNote("high") + importDiagnosticsNote("12"))); + REQUIRE(parsed.ok); + REQUIRE(parsed.diagnostics.size() == 2); + + CHECK(DiagnosticCode::invalidValue == parsed.diagnostics[0].code); + CHECK_EQUAL(std::string{"/score-partwise/part/measure/note[1]/pitch/octave"}, parsed.diagnostics[0].path); + CHECK_EQUAL(std::string{"invalid value \"high\"; using \"0\""}, parsed.diagnostics[0].message); + + CHECK(DiagnosticCode::valueAdjusted == parsed.diagnostics[1].code); + CHECK_EQUAL(std::string{"/score-partwise/part/measure/note[2]/pitch/octave"}, parsed.diagnostics[1].path); + CHECK_EQUAL(std::string{"value \"12\" adjusted to \"9\""}, parsed.diagnostics[1].message); +} + +TEST(InvalidAttributeValueNamesTheAttribute, ImportDiagnostics) +{ + const auto parsed = importDiagnosticsParse( + importDiagnosticsScore("", "1")); + REQUIRE(parsed.ok); + REQUIRE(parsed.diagnostics.size() == 1); + const Diagnostic &diagnostic = parsed.diagnostics.front(); + CHECK(DiagnosticCode::invalidValue == diagnostic.code); + CHECK_EQUAL(std::string{"/score-partwise/part/measure/note"}, diagnostic.path); + CHECK_EQUAL(std::string{"invalid value \"left\" in attribute \"default-x\"; using \"0\""}, diagnostic.message); +} + +TEST(MissingLyricLanguageIsDefaultedAndReported, ImportDiagnostics) +{ + const auto parsed = importDiagnosticsParse(importDiagnosticsScore("", "")); + REQUIRE(parsed.ok); + const auto &defaults = parsed.document.asScorePartwise().scoreHeader().defaults(); + REQUIRE(defaults.has_value()); + REQUIRE(defaults->lyricLanguage().size() == 1); + CHECK_EQUAL(std::string{"und"}, defaults->lyricLanguage().front().xmlLang()); + + REQUIRE(parsed.diagnostics.size() == 1); + const Diagnostic &diagnostic = parsed.diagnostics.front(); + CHECK(DiagnosticCode::missingValueDefaulted == diagnostic.code); + CHECK_EQUAL(std::string{"/score-partwise/defaults/lyric-language"}, diagnostic.path); + CHECK_EQUAL(std::string{"missing attribute \"xml:lang\"; using \"und\""}, diagnostic.message); +} + +TEST(RepairsAccumulateInDocumentOrder, ImportDiagnostics) +{ + const auto parsed = importDiagnosticsParse(importDiagnosticsScore( + "", + importDiagnosticsNote("12", "banana") + "1")); + REQUIRE(parsed.ok); + REQUIRE(parsed.diagnostics.size() == 4); + CHECK(DiagnosticCode::missingValueDefaulted == parsed.diagnostics[0].code); + CHECK(DiagnosticCode::valueAdjusted == parsed.diagnostics[1].code); + CHECK(DiagnosticCode::invalidValue == parsed.diagnostics[2].code); + CHECK_EQUAL(std::string{"/score-partwise/part/measure/note[1]/type"}, parsed.diagnostics[2].path); + CHECK(DiagnosticCode::invalidValue == parsed.diagnostics[3].code); + CHECK_EQUAL(std::string{"/score-partwise/part/measure/note[2]"}, parsed.diagnostics[3].path); +} + +TEST(ValidAlternateSpellingsReportNothing, ImportDiagnostics) +{ + const auto parsed = importDiagnosticsParse( + importDiagnosticsScore("", "C+04" + " 1 quarter")); + REQUIRE(parsed.ok); + CHECK(parsed.diagnostics.empty()); +} + +TEST(SilentParseProducesTheSameDocument, ImportDiagnostics) +{ + const std::string xml = importDiagnosticsScore("", + importDiagnosticsNote("12", "banana") + + "1"); + const auto reported = importDiagnosticsParse(xml); + REQUIRE(reported.ok); + + pugi::xml_document doc; + REQUIRE(doc.load_string(xml.c_str())); + const auto silent = parse(doc); + REQUIRE(silent.ok()); + CHECK(silent.value() == reported.document); +} From 98af7dcd91c5f9ed1709d3de4820cc6eba5ab3f4 Mon Sep 17 00:00:00 2001 From: Matthew James Briggs Date: Thu, 17 Sep 2026 09:01:28 +0200 Subject: [PATCH 2/8] refactor: require a ParseContext in core parsers core::parse and every generated parser now take the context, with no overload that constructs a silent one. Callers that want no reports pass ParseContext{} explicitly: the defaults probe, the core tests and the corert runner. SilentParseProducesTheSameDocument now also checks that the reporting parse saw repairs, so its comparison with ParseContext{} is meaningful. --- README.md | 3 +- gen/cpp/templates/attrs.cpp.tmpl | 10 - gen/cpp/templates/attrs.h.tmpl | 4 - gen/cpp/templates/choice.cpp.tmpl | 5 - gen/cpp/templates/choice.h.tmpl | 2 - gen/cpp/templates/choice_boxed.cpp.tmpl | 5 - gen/cpp/templates/choice_boxed.h.tmpl | 2 - gen/cpp/templates/composite.cpp.tmpl | 10 - gen/cpp/templates/composite.h.tmpl | 4 - gen/cpp/templates/defaults.cpp.tmpl | 5 +- gen/cpp/templates/derived.cpp.tmpl | 5 - gen/cpp/templates/derived.h.tmpl | 2 - gen/cpp/templates/document.cpp.tmpl | 5 - gen/cpp/templates/document.h.tmpl | 2 - gen/cpp/templates/empty.cpp.tmpl | 10 - gen/cpp/templates/empty.h.tmpl | 4 - gen/cpp/templates/group.cpp.tmpl | 5 - gen/cpp/templates/group.h.tmpl | 2 - gen/cpp/templates/value_class.cpp.tmpl | 10 - gen/cpp/templates/value_class.h.tmpl | 4 - src/private/mx/core/generated/Accidental.cpp | 10 - src/private/mx/core/generated/Accidental.h | 4 - .../mx/core/generated/AccidentalMark.cpp | 10 - .../mx/core/generated/AccidentalMark.h | 4 - .../mx/core/generated/AccidentalText.cpp | 10 - .../mx/core/generated/AccidentalText.h | 4 - src/private/mx/core/generated/Accord.cpp | 10 - src/private/mx/core/generated/Accord.h | 4 - .../core/generated/AccordionRegistration.cpp | 10 - .../mx/core/generated/AccordionRegistration.h | 4 - .../mx/core/generated/AllMarginsGroup.cpp | 5 - .../mx/core/generated/AllMarginsGroup.h | 2 - src/private/mx/core/generated/Appearance.cpp | 10 - src/private/mx/core/generated/Appearance.h | 4 - src/private/mx/core/generated/Arpeggiate.cpp | 10 - src/private/mx/core/generated/Arpeggiate.h | 4 - src/private/mx/core/generated/Arrow.cpp | 10 - src/private/mx/core/generated/Arrow.h | 4 - src/private/mx/core/generated/ArrowChoice.cpp | 5 - src/private/mx/core/generated/ArrowChoice.h | 2 - .../mx/core/generated/ArrowChoiceGroup.cpp | 5 - .../mx/core/generated/ArrowChoiceGroup.h | 2 - .../mx/core/generated/Articulations.cpp | 10 - src/private/mx/core/generated/Articulations.h | 4 - .../mx/core/generated/ArticulationsChoice.cpp | 5 - .../mx/core/generated/ArticulationsChoice.h | 2 - src/private/mx/core/generated/Assess.cpp | 10 - src/private/mx/core/generated/Assess.h | 4 - src/private/mx/core/generated/Attributes.cpp | 10 - src/private/mx/core/generated/Attributes.h | 4 - .../mx/core/generated/AttributesChoice.cpp | 5 - .../mx/core/generated/AttributesChoice.h | 2 - src/private/mx/core/generated/Backup.cpp | 10 - src/private/mx/core/generated/Backup.h | 4 - .../mx/core/generated/BarStyleColor.cpp | 10 - src/private/mx/core/generated/BarStyleColor.h | 4 - src/private/mx/core/generated/Barline.cpp | 10 - src/private/mx/core/generated/Barline.h | 4 - src/private/mx/core/generated/Barre.cpp | 10 - src/private/mx/core/generated/Barre.h | 4 - src/private/mx/core/generated/Bass.cpp | 10 - src/private/mx/core/generated/Bass.h | 4 - src/private/mx/core/generated/BassStep.cpp | 10 - src/private/mx/core/generated/BassStep.h | 4 - src/private/mx/core/generated/Beam.cpp | 10 - src/private/mx/core/generated/Beam.h | 4 - src/private/mx/core/generated/BeatRepeat.cpp | 10 - src/private/mx/core/generated/BeatRepeat.h | 4 - .../mx/core/generated/BeatUnitGroup.cpp | 5 - src/private/mx/core/generated/BeatUnitGroup.h | 2 - .../mx/core/generated/BeatUnitTied.cpp | 10 - src/private/mx/core/generated/BeatUnitTied.h | 4 - src/private/mx/core/generated/Beater.cpp | 10 - src/private/mx/core/generated/Beater.h | 4 - src/private/mx/core/generated/Bend.cpp | 10 - src/private/mx/core/generated/Bend.h | 4 - src/private/mx/core/generated/BendChoice.cpp | 5 - src/private/mx/core/generated/BendChoice.h | 2 - src/private/mx/core/generated/Bookmark.cpp | 10 - src/private/mx/core/generated/Bookmark.h | 4 - src/private/mx/core/generated/Bracket.cpp | 10 - src/private/mx/core/generated/Bracket.h | 4 - src/private/mx/core/generated/BreathMark.cpp | 10 - src/private/mx/core/generated/BreathMark.h | 4 - src/private/mx/core/generated/Caesura.cpp | 10 - src/private/mx/core/generated/Caesura.h | 4 - src/private/mx/core/generated/Cancel.cpp | 10 - src/private/mx/core/generated/Cancel.h | 4 - src/private/mx/core/generated/Clef.cpp | 10 - src/private/mx/core/generated/Clef.h | 4 - src/private/mx/core/generated/ClefGroup.cpp | 5 - src/private/mx/core/generated/ClefGroup.h | 2 - src/private/mx/core/generated/Coda.cpp | 10 - src/private/mx/core/generated/Coda.h | 4 - src/private/mx/core/generated/Credit.cpp | 10 - src/private/mx/core/generated/Credit.h | 4 - .../mx/core/generated/CreditChoice.cpp | 5 - src/private/mx/core/generated/CreditChoice.h | 2 - .../mx/core/generated/CreditChoiceGroup.cpp | 5 - .../mx/core/generated/CreditChoiceGroup.h | 2 - .../generated/CreditChoiceGroupChoice.cpp | 5 - .../core/generated/CreditChoiceGroupChoice.h | 2 - .../core/generated/CreditChoiceGroupGroup.cpp | 5 - .../core/generated/CreditChoiceGroupGroup.h | 2 - .../CreditChoiceGroupGroupChoice.cpp | 5 - .../generated/CreditChoiceGroupGroupChoice.h | 2 - .../mx/core/generated/CueNoteGroup.cpp | 5 - src/private/mx/core/generated/CueNoteGroup.h | 2 - src/private/mx/core/generated/Dashes.cpp | 10 - src/private/mx/core/generated/Dashes.h | 4 - src/private/mx/core/generated/Defaults.cpp | 10 - src/private/mx/core/generated/Defaults.h | 4 - .../mx/core/generated/DefaultsProbe.cpp | 615 +++++++++--------- src/private/mx/core/generated/Degree.cpp | 10 - src/private/mx/core/generated/Degree.h | 4 - src/private/mx/core/generated/DegreeAlter.cpp | 10 - src/private/mx/core/generated/DegreeAlter.h | 4 - src/private/mx/core/generated/DegreeType.cpp | 10 - src/private/mx/core/generated/DegreeType.h | 4 - src/private/mx/core/generated/DegreeValue.cpp | 10 - src/private/mx/core/generated/DegreeValue.h | 4 - src/private/mx/core/generated/Direction.cpp | 10 - src/private/mx/core/generated/Direction.h | 4 - .../mx/core/generated/DirectionType.cpp | 10 - src/private/mx/core/generated/DirectionType.h | 4 - .../mx/core/generated/DirectionTypeChoice.cpp | 5 - .../mx/core/generated/DirectionTypeChoice.h | 2 - .../generated/DirectionTypeChoiceChoice.cpp | 5 - .../generated/DirectionTypeChoiceChoice.h | 2 - src/private/mx/core/generated/Directive.cpp | 10 - src/private/mx/core/generated/Directive.h | 4 - .../core/generated/DisplayStepOctaveGroup.cpp | 5 - .../core/generated/DisplayStepOctaveGroup.h | 2 - src/private/mx/core/generated/Distance.cpp | 10 - src/private/mx/core/generated/Distance.h | 4 - src/private/mx/core/generated/Document.cpp | 5 - src/private/mx/core/generated/Document.h | 2 - src/private/mx/core/generated/Double.cpp | 10 - src/private/mx/core/generated/Double.h | 4 - src/private/mx/core/generated/Dynamics.cpp | 10 - src/private/mx/core/generated/Dynamics.h | 4 - .../mx/core/generated/DynamicsChoice.cpp | 5 - .../mx/core/generated/DynamicsChoice.h | 2 - .../mx/core/generated/EditorialGroup.cpp | 5 - .../mx/core/generated/EditorialGroup.h | 2 - .../EditorialVoiceDirectionGroup.cpp | 5 - .../generated/EditorialVoiceDirectionGroup.h | 2 - .../mx/core/generated/EditorialVoiceGroup.cpp | 5 - .../mx/core/generated/EditorialVoiceGroup.h | 2 - src/private/mx/core/generated/Effect.cpp | 10 - src/private/mx/core/generated/Effect.h | 4 - src/private/mx/core/generated/Elision.cpp | 10 - src/private/mx/core/generated/Elision.h | 4 - .../core/generated/ElisionSyllabicGroup.cpp | 5 - .../mx/core/generated/ElisionSyllabicGroup.h | 2 - src/private/mx/core/generated/Empty.cpp | 10 - src/private/mx/core/generated/Empty.h | 4 - src/private/mx/core/generated/EmptyFont.cpp | 10 - src/private/mx/core/generated/EmptyFont.h | 4 - src/private/mx/core/generated/EmptyLine.cpp | 10 - src/private/mx/core/generated/EmptyLine.h | 4 - .../mx/core/generated/EmptyPlacement.cpp | 10 - .../mx/core/generated/EmptyPlacement.h | 4 - .../mx/core/generated/EmptyPlacementSmufl.cpp | 10 - .../mx/core/generated/EmptyPlacementSmufl.h | 4 - .../generated/EmptyPrintObjectStyleAlign.cpp | 10 - .../generated/EmptyPrintObjectStyleAlign.h | 4 - .../core/generated/EmptyPrintStyleAlignID.cpp | 10 - .../core/generated/EmptyPrintStyleAlignID.h | 4 - .../mx/core/generated/EmptyTrillSound.cpp | 10 - .../mx/core/generated/EmptyTrillSound.h | 4 - src/private/mx/core/generated/Encoding.cpp | 10 - src/private/mx/core/generated/Encoding.h | 4 - .../mx/core/generated/EncodingChoice.cpp | 5 - .../mx/core/generated/EncodingChoice.h | 2 - src/private/mx/core/generated/Ending.cpp | 10 - src/private/mx/core/generated/Ending.h | 4 - src/private/mx/core/generated/Extend.cpp | 10 - src/private/mx/core/generated/Extend.h | 4 - src/private/mx/core/generated/Feature.cpp | 10 - src/private/mx/core/generated/Feature.h | 4 - src/private/mx/core/generated/Fermata.cpp | 10 - src/private/mx/core/generated/Fermata.h | 4 - src/private/mx/core/generated/Figure.cpp | 10 - src/private/mx/core/generated/Figure.h | 4 - src/private/mx/core/generated/FiguredBass.cpp | 10 - src/private/mx/core/generated/FiguredBass.h | 4 - src/private/mx/core/generated/Fingering.cpp | 10 - src/private/mx/core/generated/Fingering.h | 4 - src/private/mx/core/generated/FirstFret.cpp | 10 - src/private/mx/core/generated/FirstFret.h | 4 - src/private/mx/core/generated/ForPart.cpp | 10 - src/private/mx/core/generated/ForPart.h | 4 - .../mx/core/generated/FormattedSymbolID.cpp | 10 - .../mx/core/generated/FormattedSymbolID.h | 4 - .../mx/core/generated/FormattedText.cpp | 10 - src/private/mx/core/generated/FormattedText.h | 4 - .../mx/core/generated/FormattedTextID.cpp | 10 - .../mx/core/generated/FormattedTextID.h | 4 - src/private/mx/core/generated/Forward.cpp | 10 - src/private/mx/core/generated/Forward.h | 4 - src/private/mx/core/generated/Frame.cpp | 10 - src/private/mx/core/generated/Frame.h | 4 - src/private/mx/core/generated/FrameNote.cpp | 10 - src/private/mx/core/generated/FrameNote.h | 4 - src/private/mx/core/generated/Fret.cpp | 10 - src/private/mx/core/generated/Fret.h | 4 - .../mx/core/generated/FullNoteGroup.cpp | 5 - src/private/mx/core/generated/FullNoteGroup.h | 2 - .../mx/core/generated/FullNoteGroupChoice.cpp | 5 - .../mx/core/generated/FullNoteGroupChoice.h | 2 - src/private/mx/core/generated/Glass.cpp | 10 - src/private/mx/core/generated/Glass.h | 4 - src/private/mx/core/generated/Glissando.cpp | 10 - src/private/mx/core/generated/Glissando.h | 4 - src/private/mx/core/generated/Glyph.cpp | 10 - src/private/mx/core/generated/Glyph.h | 4 - src/private/mx/core/generated/Grace.cpp | 10 - src/private/mx/core/generated/Grace.h | 4 - .../mx/core/generated/GraceCueNoteGroup.cpp | 5 - .../mx/core/generated/GraceCueNoteGroup.h | 2 - .../core/generated/GraceNormalNoteGroup.cpp | 5 - .../mx/core/generated/GraceNormalNoteGroup.h | 2 - .../mx/core/generated/GraceNoteChoice.cpp | 5 - .../mx/core/generated/GraceNoteChoice.h | 2 - .../mx/core/generated/GraceNoteGroup.cpp | 5 - .../mx/core/generated/GraceNoteGroup.h | 2 - .../mx/core/generated/GroupBarline.cpp | 10 - src/private/mx/core/generated/GroupBarline.h | 4 - src/private/mx/core/generated/GroupName.cpp | 10 - src/private/mx/core/generated/GroupName.h | 4 - src/private/mx/core/generated/GroupSymbol.cpp | 10 - src/private/mx/core/generated/GroupSymbol.h | 4 - src/private/mx/core/generated/Grouping.cpp | 10 - src/private/mx/core/generated/Grouping.h | 4 - .../mx/core/generated/HammerOnPullOff.cpp | 10 - .../mx/core/generated/HammerOnPullOff.h | 4 - src/private/mx/core/generated/Handbell.cpp | 10 - src/private/mx/core/generated/Handbell.h | 4 - .../mx/core/generated/HarmonClosed.cpp | 10 - src/private/mx/core/generated/HarmonClosed.h | 4 - src/private/mx/core/generated/HarmonMute.cpp | 10 - src/private/mx/core/generated/HarmonMute.h | 4 - src/private/mx/core/generated/Harmonic.cpp | 10 - src/private/mx/core/generated/Harmonic.h | 4 - .../mx/core/generated/HarmonicChoice.cpp | 5 - .../mx/core/generated/HarmonicChoice.h | 2 - .../mx/core/generated/HarmonicChoice2.cpp | 5 - .../mx/core/generated/HarmonicChoice2.h | 2 - src/private/mx/core/generated/Harmony.cpp | 10 - src/private/mx/core/generated/Harmony.h | 4 - .../mx/core/generated/HarmonyAlter.cpp | 10 - src/private/mx/core/generated/HarmonyAlter.h | 4 - .../mx/core/generated/HarmonyChordGroup.cpp | 5 - .../mx/core/generated/HarmonyChordGroup.h | 2 - .../generated/HarmonyChordGroupChoice.cpp | 5 - .../core/generated/HarmonyChordGroupChoice.h | 2 - src/private/mx/core/generated/HarpPedals.cpp | 10 - src/private/mx/core/generated/HarpPedals.h | 4 - src/private/mx/core/generated/HeelToe.cpp | 5 - src/private/mx/core/generated/HeelToe.h | 2 - src/private/mx/core/generated/Hole.cpp | 10 - src/private/mx/core/generated/Hole.h | 4 - src/private/mx/core/generated/HoleClosed.cpp | 10 - src/private/mx/core/generated/HoleClosed.h | 4 - .../mx/core/generated/HorizontalTurn.cpp | 10 - .../mx/core/generated/HorizontalTurn.h | 4 - .../mx/core/generated/Identification.cpp | 10 - .../mx/core/generated/Identification.h | 4 - src/private/mx/core/generated/Image.cpp | 10 - src/private/mx/core/generated/Image.h | 4 - src/private/mx/core/generated/Instrument.cpp | 10 - src/private/mx/core/generated/Instrument.h | 4 - .../mx/core/generated/InstrumentChange.cpp | 10 - .../mx/core/generated/InstrumentChange.h | 4 - .../mx/core/generated/InstrumentLink.cpp | 10 - .../mx/core/generated/InstrumentLink.h | 4 - .../mx/core/generated/Interchangeable.cpp | 10 - .../mx/core/generated/Interchangeable.h | 4 - src/private/mx/core/generated/Inversion.cpp | 10 - src/private/mx/core/generated/Inversion.h | 4 - src/private/mx/core/generated/Key.cpp | 10 - src/private/mx/core/generated/Key.h | 4 - .../mx/core/generated/KeyAccidental.cpp | 10 - src/private/mx/core/generated/KeyAccidental.h | 4 - src/private/mx/core/generated/KeyChoice.cpp | 5 - src/private/mx/core/generated/KeyChoice.h | 2 - src/private/mx/core/generated/KeyOctave.cpp | 10 - src/private/mx/core/generated/KeyOctave.h | 4 - src/private/mx/core/generated/Kind.cpp | 10 - src/private/mx/core/generated/Kind.h | 4 - src/private/mx/core/generated/LayoutGroup.cpp | 5 - src/private/mx/core/generated/LayoutGroup.h | 2 - .../core/generated/LeftRightMarginsGroup.cpp | 5 - .../mx/core/generated/LeftRightMarginsGroup.h | 2 - src/private/mx/core/generated/Level.cpp | 10 - src/private/mx/core/generated/Level.h | 4 - src/private/mx/core/generated/LineDetail.cpp | 10 - src/private/mx/core/generated/LineDetail.h | 4 - src/private/mx/core/generated/LineWidth.cpp | 10 - src/private/mx/core/generated/LineWidth.h | 4 - src/private/mx/core/generated/Link.cpp | 10 - src/private/mx/core/generated/Link.h | 4 - src/private/mx/core/generated/Listen.cpp | 10 - src/private/mx/core/generated/Listen.h | 4 - .../mx/core/generated/ListenChoice.cpp | 5 - src/private/mx/core/generated/ListenChoice.h | 2 - src/private/mx/core/generated/Listening.cpp | 10 - src/private/mx/core/generated/Listening.h | 4 - .../mx/core/generated/ListeningChoice.cpp | 5 - .../mx/core/generated/ListeningChoice.h | 2 - src/private/mx/core/generated/Lyric.cpp | 10 - src/private/mx/core/generated/Lyric.h | 4 - src/private/mx/core/generated/LyricChoice.cpp | 5 - src/private/mx/core/generated/LyricChoice.h | 2 - src/private/mx/core/generated/LyricFont.cpp | 10 - src/private/mx/core/generated/LyricFont.h | 4 - .../mx/core/generated/LyricLanguage.cpp | 10 - src/private/mx/core/generated/LyricLanguage.h | 4 - .../mx/core/generated/LyricSyllableGroup.cpp | 5 - .../mx/core/generated/LyricSyllableGroup.h | 2 - .../mx/core/generated/LyricTextGroup.cpp | 5 - .../mx/core/generated/LyricTextGroup.h | 2 - src/private/mx/core/generated/MIDIDevice.cpp | 10 - src/private/mx/core/generated/MIDIDevice.h | 4 - .../mx/core/generated/MIDIInstrument.cpp | 10 - .../mx/core/generated/MIDIInstrument.h | 4 - .../mx/core/generated/MeasureLayout.cpp | 10 - src/private/mx/core/generated/MeasureLayout.h | 4 - .../mx/core/generated/MeasureNumbering.cpp | 10 - .../mx/core/generated/MeasureNumbering.h | 4 - .../mx/core/generated/MeasureRepeat.cpp | 10 - src/private/mx/core/generated/MeasureRepeat.h | 4 - .../mx/core/generated/MeasureStyle.cpp | 10 - src/private/mx/core/generated/MeasureStyle.h | 4 - .../mx/core/generated/MeasureStyleChoice.cpp | 5 - .../mx/core/generated/MeasureStyleChoice.h | 2 - src/private/mx/core/generated/Membrane.cpp | 10 - src/private/mx/core/generated/Membrane.h | 4 - src/private/mx/core/generated/Metal.cpp | 10 - src/private/mx/core/generated/Metal.h | 4 - src/private/mx/core/generated/Metronome.cpp | 10 - src/private/mx/core/generated/Metronome.h | 4 - .../mx/core/generated/MetronomeBeam.cpp | 10 - src/private/mx/core/generated/MetronomeBeam.h | 4 - .../mx/core/generated/MetronomeChoice.cpp | 5 - .../mx/core/generated/MetronomeChoice.h | 2 - .../core/generated/MetronomeChoiceGroup.cpp | 5 - .../mx/core/generated/MetronomeChoiceGroup.h | 2 - .../core/generated/MetronomeChoiceGroup2.cpp | 5 - .../mx/core/generated/MetronomeChoiceGroup2.h | 2 - .../generated/MetronomeChoiceGroup2Group.cpp | 5 - .../generated/MetronomeChoiceGroup2Group.h | 2 - .../generated/MetronomeChoiceGroupChoice.cpp | 5 - .../generated/MetronomeChoiceGroupChoice.h | 2 - .../MetronomeChoiceGroupChoiceGroup.cpp | 5 - .../MetronomeChoiceGroupChoiceGroup.h | 2 - .../mx/core/generated/MetronomeNote.cpp | 10 - src/private/mx/core/generated/MetronomeNote.h | 4 - .../mx/core/generated/MetronomeTied.cpp | 10 - src/private/mx/core/generated/MetronomeTied.h | 4 - .../mx/core/generated/MetronomeTuplet.cpp | 5 - .../mx/core/generated/MetronomeTuplet.h | 2 - .../mx/core/generated/Miscellaneous.cpp | 10 - src/private/mx/core/generated/Miscellaneous.h | 4 - .../mx/core/generated/MiscellaneousField.cpp | 10 - .../mx/core/generated/MiscellaneousField.h | 4 - src/private/mx/core/generated/Mordent.cpp | 5 - src/private/mx/core/generated/Mordent.h | 2 - .../mx/core/generated/MultipleRest.cpp | 10 - src/private/mx/core/generated/MultipleRest.h | 4 - .../mx/core/generated/MusicDataChoice.cpp | 5 - .../mx/core/generated/MusicDataChoice.h | 2 - src/private/mx/core/generated/NameDisplay.cpp | 10 - src/private/mx/core/generated/NameDisplay.h | 4 - .../mx/core/generated/NameDisplayChoice.cpp | 5 - .../mx/core/generated/NameDisplayChoice.h | 2 - .../mx/core/generated/NonArpeggiate.cpp | 10 - src/private/mx/core/generated/NonArpeggiate.h | 4 - .../core/generated/NonTraditionalKeyGroup.cpp | 5 - .../core/generated/NonTraditionalKeyGroup.h | 2 - .../mx/core/generated/NormalNoteGroup.cpp | 5 - .../mx/core/generated/NormalNoteGroup.h | 2 - src/private/mx/core/generated/Notations.cpp | 10 - src/private/mx/core/generated/Notations.h | 4 - .../mx/core/generated/NotationsChoice.cpp | 5 - .../mx/core/generated/NotationsChoice.h | 2 - src/private/mx/core/generated/Note.cpp | 10 - src/private/mx/core/generated/Note.h | 4 - src/private/mx/core/generated/NoteChoice.cpp | 5 - src/private/mx/core/generated/NoteChoice.h | 2 - src/private/mx/core/generated/NoteSize.cpp | 10 - src/private/mx/core/generated/NoteSize.h | 4 - src/private/mx/core/generated/NoteType.cpp | 10 - src/private/mx/core/generated/NoteType.h | 4 - src/private/mx/core/generated/Notehead.cpp | 10 - src/private/mx/core/generated/Notehead.h | 4 - .../mx/core/generated/NoteheadText.cpp | 10 - src/private/mx/core/generated/NoteheadText.h | 4 - .../mx/core/generated/NoteheadTextChoice.cpp | 5 - .../mx/core/generated/NoteheadTextChoice.h | 2 - src/private/mx/core/generated/Numeral.cpp | 10 - src/private/mx/core/generated/Numeral.h | 4 - src/private/mx/core/generated/NumeralKey.cpp | 10 - src/private/mx/core/generated/NumeralKey.h | 4 - src/private/mx/core/generated/NumeralRoot.cpp | 10 - src/private/mx/core/generated/NumeralRoot.h | 4 - src/private/mx/core/generated/OctaveShift.cpp | 10 - src/private/mx/core/generated/OctaveShift.h | 4 - src/private/mx/core/generated/Offset.cpp | 10 - src/private/mx/core/generated/Offset.h | 4 - src/private/mx/core/generated/Opus.cpp | 10 - src/private/mx/core/generated/Opus.h | 4 - src/private/mx/core/generated/Ornaments.cpp | 10 - src/private/mx/core/generated/Ornaments.h | 4 - .../mx/core/generated/OrnamentsGroup.cpp | 5 - .../mx/core/generated/OrnamentsGroup.h | 2 - .../core/generated/OrnamentsGroupChoice.cpp | 5 - .../mx/core/generated/OrnamentsGroupChoice.h | 2 - .../mx/core/generated/OtherAppearance.cpp | 10 - .../mx/core/generated/OtherAppearance.h | 4 - .../mx/core/generated/OtherDirection.cpp | 10 - .../mx/core/generated/OtherDirection.h | 4 - .../mx/core/generated/OtherListening.cpp | 10 - .../mx/core/generated/OtherListening.h | 4 - .../mx/core/generated/OtherNotation.cpp | 10 - src/private/mx/core/generated/OtherNotation.h | 4 - .../mx/core/generated/OtherPlacementText.cpp | 10 - .../mx/core/generated/OtherPlacementText.h | 4 - src/private/mx/core/generated/OtherPlay.cpp | 10 - src/private/mx/core/generated/OtherPlay.h | 4 - src/private/mx/core/generated/OtherText.cpp | 10 - src/private/mx/core/generated/OtherText.h | 4 - src/private/mx/core/generated/PageLayout.cpp | 10 - src/private/mx/core/generated/PageLayout.h | 4 - .../mx/core/generated/PageLayoutGroup.cpp | 5 - .../mx/core/generated/PageLayoutGroup.h | 2 - src/private/mx/core/generated/PageMargins.cpp | 10 - src/private/mx/core/generated/PageMargins.h | 4 - src/private/mx/core/generated/PartClef.cpp | 10 - src/private/mx/core/generated/PartClef.h | 4 - src/private/mx/core/generated/PartGroup.cpp | 10 - src/private/mx/core/generated/PartGroup.h | 4 - src/private/mx/core/generated/PartLink.cpp | 10 - src/private/mx/core/generated/PartLink.h | 4 - src/private/mx/core/generated/PartList.cpp | 10 - src/private/mx/core/generated/PartList.h | 4 - .../mx/core/generated/PartListChoice.cpp | 5 - .../mx/core/generated/PartListChoice.h | 2 - src/private/mx/core/generated/PartName.cpp | 10 - src/private/mx/core/generated/PartName.h | 4 - src/private/mx/core/generated/PartSymbol.cpp | 10 - src/private/mx/core/generated/PartSymbol.h | 4 - .../mx/core/generated/PartTranspose.cpp | 10 - src/private/mx/core/generated/PartTranspose.h | 4 - .../mx/core/generated/PartwiseMeasure.cpp | 10 - .../mx/core/generated/PartwiseMeasure.h | 4 - .../mx/core/generated/PartwisePart.cpp | 10 - src/private/mx/core/generated/PartwisePart.h | 4 - src/private/mx/core/generated/Pedal.cpp | 10 - src/private/mx/core/generated/Pedal.h | 4 - src/private/mx/core/generated/PedalTuning.cpp | 10 - src/private/mx/core/generated/PedalTuning.h | 4 - src/private/mx/core/generated/PerMinute.cpp | 10 - src/private/mx/core/generated/PerMinute.h | 4 - src/private/mx/core/generated/Percussion.cpp | 10 - src/private/mx/core/generated/Percussion.h | 4 - .../mx/core/generated/PercussionChoice.cpp | 5 - .../mx/core/generated/PercussionChoice.h | 2 - src/private/mx/core/generated/Pitch.cpp | 10 - src/private/mx/core/generated/Pitch.h | 4 - src/private/mx/core/generated/Pitched.cpp | 10 - src/private/mx/core/generated/Pitched.h | 4 - .../mx/core/generated/PlacementText.cpp | 10 - src/private/mx/core/generated/PlacementText.h | 4 - src/private/mx/core/generated/Play.cpp | 10 - src/private/mx/core/generated/Play.h | 4 - src/private/mx/core/generated/PlayChoice.cpp | 5 - src/private/mx/core/generated/PlayChoice.h | 2 - src/private/mx/core/generated/Player.cpp | 10 - src/private/mx/core/generated/Player.h | 4 - .../mx/core/generated/PrincipalVoice.cpp | 10 - .../mx/core/generated/PrincipalVoice.h | 4 - src/private/mx/core/generated/Print.cpp | 10 - src/private/mx/core/generated/Print.h | 4 - src/private/mx/core/generated/Release.cpp | 5 - src/private/mx/core/generated/Release.h | 2 - src/private/mx/core/generated/Repeat.cpp | 10 - src/private/mx/core/generated/Repeat.h | 4 - src/private/mx/core/generated/Rest.cpp | 10 - src/private/mx/core/generated/Rest.h | 4 - src/private/mx/core/generated/Root.cpp | 10 - src/private/mx/core/generated/Root.h | 4 - src/private/mx/core/generated/RootStep.cpp | 10 - src/private/mx/core/generated/RootStep.h | 4 - src/private/mx/core/generated/Scaling.cpp | 10 - src/private/mx/core/generated/Scaling.h | 4 - src/private/mx/core/generated/Scordatura.cpp | 10 - src/private/mx/core/generated/Scordatura.h | 4 - .../mx/core/generated/ScoreHeaderGroup.cpp | 5 - .../mx/core/generated/ScoreHeaderGroup.h | 2 - .../mx/core/generated/ScoreInstrument.cpp | 10 - .../mx/core/generated/ScoreInstrument.h | 4 - src/private/mx/core/generated/ScorePart.cpp | 10 - src/private/mx/core/generated/ScorePart.h | 4 - .../mx/core/generated/ScorePartMIDIGroup.cpp | 5 - .../mx/core/generated/ScorePartMIDIGroup.h | 2 - .../mx/core/generated/ScorePartwise.cpp | 10 - src/private/mx/core/generated/ScorePartwise.h | 4 - .../mx/core/generated/ScoreTimewise.cpp | 10 - src/private/mx/core/generated/ScoreTimewise.h | 4 - src/private/mx/core/generated/Segno.cpp | 10 - src/private/mx/core/generated/Segno.h | 4 - src/private/mx/core/generated/Slash.cpp | 10 - src/private/mx/core/generated/Slash.h | 4 - src/private/mx/core/generated/SlashGroup.cpp | 5 - src/private/mx/core/generated/SlashGroup.h | 2 - .../mx/core/generated/SlashGroupGroup.cpp | 5 - .../mx/core/generated/SlashGroupGroup.h | 2 - src/private/mx/core/generated/Slide.cpp | 10 - src/private/mx/core/generated/Slide.h | 4 - src/private/mx/core/generated/Slur.cpp | 10 - src/private/mx/core/generated/Slur.h | 4 - src/private/mx/core/generated/Sound.cpp | 10 - src/private/mx/core/generated/Sound.h | 4 - src/private/mx/core/generated/SoundGroup.cpp | 5 - src/private/mx/core/generated/SoundGroup.h | 2 - .../mx/core/generated/StaffDetails.cpp | 10 - src/private/mx/core/generated/StaffDetails.h | 4 - .../mx/core/generated/StaffDetailsGroup.cpp | 5 - .../mx/core/generated/StaffDetailsGroup.h | 2 - src/private/mx/core/generated/StaffDivide.cpp | 10 - src/private/mx/core/generated/StaffDivide.h | 4 - src/private/mx/core/generated/StaffLayout.cpp | 10 - src/private/mx/core/generated/StaffLayout.h | 4 - src/private/mx/core/generated/StaffSize.cpp | 10 - src/private/mx/core/generated/StaffSize.h | 4 - src/private/mx/core/generated/StaffTuning.cpp | 10 - src/private/mx/core/generated/StaffTuning.h | 4 - src/private/mx/core/generated/Stem.cpp | 10 - src/private/mx/core/generated/Stem.h | 4 - src/private/mx/core/generated/Stick.cpp | 10 - src/private/mx/core/generated/Stick.h | 4 - src/private/mx/core/generated/String.cpp | 10 - src/private/mx/core/generated/String.h | 4 - src/private/mx/core/generated/StringMute.cpp | 10 - src/private/mx/core/generated/StringMute.h | 4 - .../mx/core/generated/StrongAccent.cpp | 5 - src/private/mx/core/generated/StrongAccent.h | 2 - src/private/mx/core/generated/StyleText.cpp | 10 - src/private/mx/core/generated/StyleText.h | 4 - src/private/mx/core/generated/Supports.cpp | 10 - src/private/mx/core/generated/Supports.h | 4 - src/private/mx/core/generated/Swing.cpp | 10 - src/private/mx/core/generated/Swing.h | 4 - src/private/mx/core/generated/SwingChoice.cpp | 5 - src/private/mx/core/generated/SwingChoice.h | 2 - .../mx/core/generated/SwingChoiceGroup.cpp | 5 - .../mx/core/generated/SwingChoiceGroup.h | 2 - src/private/mx/core/generated/Sync.cpp | 10 - src/private/mx/core/generated/Sync.h | 4 - .../mx/core/generated/SystemDividers.cpp | 10 - .../mx/core/generated/SystemDividers.h | 4 - .../mx/core/generated/SystemLayout.cpp | 10 - src/private/mx/core/generated/SystemLayout.h | 4 - .../mx/core/generated/SystemMargins.cpp | 10 - src/private/mx/core/generated/SystemMargins.h | 4 - src/private/mx/core/generated/Tap.cpp | 10 - src/private/mx/core/generated/Tap.h | 4 - src/private/mx/core/generated/Technical.cpp | 10 - src/private/mx/core/generated/Technical.h | 4 - .../mx/core/generated/TechnicalChoice.cpp | 5 - .../mx/core/generated/TechnicalChoice.h | 2 - .../mx/core/generated/TextElementData.cpp | 10 - .../mx/core/generated/TextElementData.h | 4 - src/private/mx/core/generated/Tie.cpp | 10 - src/private/mx/core/generated/Tie.h | 4 - src/private/mx/core/generated/Tied.cpp | 10 - src/private/mx/core/generated/Tied.h | 4 - src/private/mx/core/generated/Time.cpp | 10 - src/private/mx/core/generated/Time.h | 4 - src/private/mx/core/generated/TimeChoice.cpp | 5 - src/private/mx/core/generated/TimeChoice.h | 2 - .../mx/core/generated/TimeChoiceGroup.cpp | 5 - .../mx/core/generated/TimeChoiceGroup.h | 2 - .../mx/core/generated/TimeModification.cpp | 10 - .../mx/core/generated/TimeModification.h | 4 - .../core/generated/TimeModificationGroup.cpp | 5 - .../mx/core/generated/TimeModificationGroup.h | 2 - .../mx/core/generated/TimeSignatureGroup.cpp | 5 - .../mx/core/generated/TimeSignatureGroup.h | 2 - .../mx/core/generated/TimewiseMeasure.cpp | 10 - .../mx/core/generated/TimewiseMeasure.h | 4 - .../mx/core/generated/TimewisePart.cpp | 10 - src/private/mx/core/generated/TimewisePart.h | 4 - src/private/mx/core/generated/Timpani.cpp | 10 - src/private/mx/core/generated/Timpani.h | 4 - .../mx/core/generated/TraditionalKeyGroup.cpp | 5 - .../mx/core/generated/TraditionalKeyGroup.h | 2 - src/private/mx/core/generated/Transpose.cpp | 10 - src/private/mx/core/generated/Transpose.h | 4 - .../mx/core/generated/TransposeGroup.cpp | 5 - .../mx/core/generated/TransposeGroup.h | 2 - src/private/mx/core/generated/Tremolo.cpp | 10 - src/private/mx/core/generated/Tremolo.h | 4 - src/private/mx/core/generated/TuningGroup.cpp | 5 - src/private/mx/core/generated/TuningGroup.h | 2 - src/private/mx/core/generated/Tuplet.cpp | 10 - src/private/mx/core/generated/Tuplet.h | 4 - src/private/mx/core/generated/TupletDot.cpp | 10 - src/private/mx/core/generated/TupletDot.h | 4 - .../mx/core/generated/TupletNumber.cpp | 10 - src/private/mx/core/generated/TupletNumber.h | 4 - .../mx/core/generated/TupletPortion.cpp | 10 - src/private/mx/core/generated/TupletPortion.h | 4 - src/private/mx/core/generated/TupletType.cpp | 10 - src/private/mx/core/generated/TupletType.h | 4 - src/private/mx/core/generated/TypedText.cpp | 10 - src/private/mx/core/generated/TypedText.h | 4 - src/private/mx/core/generated/Unpitched.cpp | 10 - src/private/mx/core/generated/Unpitched.h | 4 - .../mx/core/generated/VirtualInstrument.cpp | 10 - .../mx/core/generated/VirtualInstrument.h | 4 - .../generated/VirtualInstrumentDataGroup.cpp | 5 - .../generated/VirtualInstrumentDataGroup.h | 2 - .../VirtualInstrumentDataGroupChoice.cpp | 5 - .../VirtualInstrumentDataGroupChoice.h | 2 - src/private/mx/core/generated/Wait.cpp | 10 - src/private/mx/core/generated/Wait.h | 4 - src/private/mx/core/generated/WavyLine.cpp | 10 - src/private/mx/core/generated/WavyLine.h | 4 - src/private/mx/core/generated/Wedge.cpp | 10 - src/private/mx/core/generated/Wedge.h | 4 - src/private/mx/core/generated/Wood.cpp | 10 - src/private/mx/core/generated/Wood.h | 4 - src/private/mx/core/generated/Work.cpp | 10 - src/private/mx/core/generated/Work.h | 4 - src/private/mxtest/core/AttributionTest.cpp | 3 +- src/private/mxtest/core/DocumentTest.cpp | 11 +- .../mxtest/core/ImportDiagnosticsTest.cpp | 3 +- src/private/mxtest/core/ShapeTest.cpp | 5 +- .../mxtest/corert/CoreRoundtripImpl.cpp | 3 +- 642 files changed, 328 insertions(+), 4128 deletions(-) diff --git a/README.md b/README.md index cc128e0dc..73eaea4aa 100644 --- a/README.md +++ b/README.md @@ -494,7 +494,8 @@ constructors, clamp-on-construct number wrappers, composites with named fields i (the serializer walks declaration order, so wrong element order is unrepresentable), `std::variant`-based choice classes, `OneOrMore` for required repeats, and `Result`-returning bounded appends (e.g. beam <= 8). Value semantics throughout -- no shared pointers. Errors exist -in exactly two places: `mx::core::parse(const pugi::xml_document&) -> Result` (strict on +in exactly two places: +`mx::core::parse(const pugi::xml_document&, const ParseContext&) -> Result` (strict on names and structure, lenient on values) and the bounded `add...` methods. Serialization is `mx::core::serialize(const Document&, pugi::xml_document&)`. The design and its rationale are recorded in `docs/ai/design/mx-core-plan.md`. diff --git a/gen/cpp/templates/attrs.cpp.tmpl b/gen/cpp/templates/attrs.cpp.tmpl index 437568e77..047b628ce 100644 --- a/gen/cpp/templates/attrs.cpp.tmpl +++ b/gen/cpp/templates/attrs.cpp.tmpl @@ -12,11 +12,6 @@ namespace {{vars.namespace}} { {{>attributes_impl}} -{{ident}} parse{{ident}}(pugi::xml_node el) -{ - return parse{{ident}}(el, ParseContext{}); -} - {{ident}} parse{{ident}}(pugi::xml_node el, const ParseContext &context) { {{ident}} out; @@ -25,11 +20,6 @@ namespace {{vars.namespace}} return out; } -void parse{{ident}}Content({{ident}} &out, pugi::xml_node el) -{ - parse{{ident}}Content(out, el, ParseContext{}); -} - void parse{{ident}}Content({{ident}} &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/gen/cpp/templates/attrs.h.tmpl b/gen/cpp/templates/attrs.h.tmpl index 7cfeb7e96..3c9bef23c 100644 --- a/gen/cpp/templates/attrs.h.tmpl +++ b/gen/cpp/templates/attrs.h.tmpl @@ -39,12 +39,8 @@ private: {{>attributes_members}} }; -{{ident}} parse{{ident}}(pugi::xml_node el); - {{ident}} parse{{ident}}(pugi::xml_node el, const ParseContext &context); -void parse{{ident}}Content({{ident}} &out, pugi::xml_node el); - void parse{{ident}}Content({{ident}} &out, pugi::xml_node el, const ParseContext &context); void serialize{{ident}}(const {{ident}} &v, pugi::xml_node parent, const char *tag); diff --git a/gen/cpp/templates/choice.cpp.tmpl b/gen/cpp/templates/choice.cpp.tmpl index 7801762e9..325aae54c 100644 --- a/gen/cpp/templates/choice.cpp.tmpl +++ b/gen/cpp/templates/choice.cpp.tmpl @@ -27,11 +27,6 @@ namespace {{vars.namespace}} } {{/alternatives}} -{{ident}} parse{{ident}}(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parse{{ident}}(el, cursor, ParseContext{}); -} - {{ident}} parse{{ident}}(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { {{#alternatives}} diff --git a/gen/cpp/templates/choice.h.tmpl b/gen/cpp/templates/choice.h.tmpl index 124846b13..f82459128 100644 --- a/gen/cpp/templates/choice.h.tmpl +++ b/gen/cpp/templates/choice.h.tmpl @@ -89,8 +89,6 @@ private: /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -{{ident}} parse{{ident}}(pugi::xml_node el, pugi::xml_node &cursor); - {{ident}} parse{{ident}}(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serialize{{ident}}(const {{ident}} &v, pugi::xml_node el); diff --git a/gen/cpp/templates/choice_boxed.cpp.tmpl b/gen/cpp/templates/choice_boxed.cpp.tmpl index 78eba435b..a152297ae 100644 --- a/gen/cpp/templates/choice_boxed.cpp.tmpl +++ b/gen/cpp/templates/choice_boxed.cpp.tmpl @@ -55,11 +55,6 @@ bool {{ident}}::operator==(const {{ident}} &other) const } {{/alternatives}} -{{ident}} parse{{ident}}(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parse{{ident}}(el, cursor, ParseContext{}); -} - {{ident}} parse{{ident}}(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { {{#alternatives}} diff --git a/gen/cpp/templates/choice_boxed.h.tmpl b/gen/cpp/templates/choice_boxed.h.tmpl index a639d64d4..9bb122f9e 100644 --- a/gen/cpp/templates/choice_boxed.h.tmpl +++ b/gen/cpp/templates/choice_boxed.h.tmpl @@ -91,8 +91,6 @@ private: /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -{{ident}} parse{{ident}}(pugi::xml_node el, pugi::xml_node &cursor); - {{ident}} parse{{ident}}(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serialize{{ident}}(const {{ident}} &v, pugi::xml_node el); diff --git a/gen/cpp/templates/composite.cpp.tmpl b/gen/cpp/templates/composite.cpp.tmpl index a98eaa364..124f7c95b 100644 --- a/gen/cpp/templates/composite.cpp.tmpl +++ b/gen/cpp/templates/composite.cpp.tmpl @@ -13,11 +13,6 @@ namespace {{vars.namespace}} {{>attributes_impl}} {{>fields_impl}} -{{ident}} parse{{ident}}(pugi::xml_node el) -{ - return parse{{ident}}(el, ParseContext{}); -} - {{ident}} parse{{ident}}(pugi::xml_node el, const ParseContext &context) { {{ident}} out; @@ -26,11 +21,6 @@ namespace {{vars.namespace}} return out; } -void parse{{ident}}Content({{ident}} &out, pugi::xml_node el) -{ - parse{{ident}}Content(out, el, ParseContext{}); -} - void parse{{ident}}Content({{ident}} &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/gen/cpp/templates/composite.h.tmpl b/gen/cpp/templates/composite.h.tmpl index 4e1dee3f6..d3235bd91 100644 --- a/gen/cpp/templates/composite.h.tmpl +++ b/gen/cpp/templates/composite.h.tmpl @@ -51,12 +51,8 @@ private: {{>fields_members}} }; -{{ident}} parse{{ident}}(pugi::xml_node el); - {{ident}} parse{{ident}}(pugi::xml_node el, const ParseContext &context); -void parse{{ident}}Content({{ident}} &out, pugi::xml_node el); - void parse{{ident}}Content({{ident}} &out, pugi::xml_node el, const ParseContext &context); void serialize{{ident}}(const {{ident}} &v, pugi::xml_node parent, const char *tag); diff --git a/gen/cpp/templates/defaults.cpp.tmpl b/gen/cpp/templates/defaults.cpp.tmpl index 330281965..61197a18d 100644 --- a/gen/cpp/templates/defaults.cpp.tmpl +++ b/gen/cpp/templates/defaults.cpp.tmpl @@ -8,6 +8,7 @@ {{#groups}} #include "mx/core/generated/{{ident}}.h" {{/groups}} +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" namespace {{vars.namespace}} @@ -19,7 +20,7 @@ void roundTripDefaults() { pugi::xml_document doc; serialize{{ident}}({{ident}}{}, doc, "probe"); - parse{{ident}}(doc.document_element()); + parse{{ident}}(doc.document_element(), ParseContext{}); } {{/complex_types}} {{#groups}} @@ -29,7 +30,7 @@ void roundTripDefaults() serialize{{ident}}({{ident}}{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parse{{ident}}(el, cursor); + parse{{ident}}(el, cursor, ParseContext{}); } } {{/groups}} diff --git a/gen/cpp/templates/derived.cpp.tmpl b/gen/cpp/templates/derived.cpp.tmpl index 5833a06bf..aa49a7dff 100644 --- a/gen/cpp/templates/derived.cpp.tmpl +++ b/gen/cpp/templates/derived.cpp.tmpl @@ -12,11 +12,6 @@ namespace {{vars.namespace}} { {{>attributes_impl}} -{{ident}} parse{{ident}}(pugi::xml_node el) -{ - return parse{{ident}}(el, ParseContext{}); -} - {{ident}} parse{{ident}}(pugi::xml_node el, const ParseContext &context) { {{ident}} out; diff --git a/gen/cpp/templates/derived.h.tmpl b/gen/cpp/templates/derived.h.tmpl index 41e2098b1..98e479f4e 100644 --- a/gen/cpp/templates/derived.h.tmpl +++ b/gen/cpp/templates/derived.h.tmpl @@ -41,8 +41,6 @@ private: {{>attributes_members}} }; -{{ident}} parse{{ident}}(pugi::xml_node el); - {{ident}} parse{{ident}}(pugi::xml_node el, const ParseContext &context); void serialize{{ident}}(const {{ident}} &v, pugi::xml_node parent, const char *tag); diff --git a/gen/cpp/templates/document.cpp.tmpl b/gen/cpp/templates/document.cpp.tmpl index fef513779..bb88cce56 100644 --- a/gen/cpp/templates/document.cpp.tmpl +++ b/gen/cpp/templates/document.cpp.tmpl @@ -14,11 +14,6 @@ namespace {{vars.namespace}} { -Result parse(const pugi::xml_document &doc) -{ - return parse(doc, ParseContext{}); -} - Result parse(const pugi::xml_document &doc, const ParseContext &context) { try diff --git a/gen/cpp/templates/document.h.tmpl b/gen/cpp/templates/document.h.tmpl index 9ff4024cb..fccdb48bf 100644 --- a/gen/cpp/templates/document.h.tmpl +++ b/gen/cpp/templates/document.h.tmpl @@ -92,8 +92,6 @@ private: /// The parse error boundary (plan ยง2.5): strict on names and structure, /// lenient on values; a root declaring a version newer than /// SupportedMusicXMLVersion is rejected with unsupportedVersion. -Result parse(const pugi::xml_document &doc); - Result parse(const pugi::xml_document &doc, const ParseContext &context); /// Total for every Document (ยง1.1 guarantees validity): writes the XML diff --git a/gen/cpp/templates/empty.cpp.tmpl b/gen/cpp/templates/empty.cpp.tmpl index 562ee3380..e70fe4af9 100644 --- a/gen/cpp/templates/empty.cpp.tmpl +++ b/gen/cpp/templates/empty.cpp.tmpl @@ -8,11 +8,6 @@ namespace {{vars.namespace}} { -{{ident}} parse{{ident}}(pugi::xml_node el) -{ - return parse{{ident}}(el, ParseContext{}); -} - {{ident}} parse{{ident}}(pugi::xml_node el, const ParseContext &context) { {{ident}} out; @@ -29,11 +24,6 @@ namespace {{vars.namespace}} return out; } -void parse{{ident}}Content({{ident}} &out, pugi::xml_node el) -{ - parse{{ident}}Content(out, el, ParseContext{}); -} - void parse{{ident}}Content({{ident}} &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/gen/cpp/templates/empty.h.tmpl b/gen/cpp/templates/empty.h.tmpl index e67ac3bff..776f0cf28 100644 --- a/gen/cpp/templates/empty.h.tmpl +++ b/gen/cpp/templates/empty.h.tmpl @@ -24,12 +24,8 @@ public: bool operator==(const {{ident}} &) const noexcept = default; }; -{{ident}} parse{{ident}}(pugi::xml_node el); - {{ident}} parse{{ident}}(pugi::xml_node el, const ParseContext &context); -void parse{{ident}}Content({{ident}} &out, pugi::xml_node el); - void parse{{ident}}Content({{ident}} &out, pugi::xml_node el, const ParseContext &context); void serialize{{ident}}(const {{ident}} &v, pugi::xml_node parent, const char *tag); diff --git a/gen/cpp/templates/group.cpp.tmpl b/gen/cpp/templates/group.cpp.tmpl index 3e99197f9..2fd86dda2 100644 --- a/gen/cpp/templates/group.cpp.tmpl +++ b/gen/cpp/templates/group.cpp.tmpl @@ -12,11 +12,6 @@ namespace {{vars.namespace}} { {{>fields_impl}} -{{ident}} parse{{ident}}(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parse{{ident}}(el, cursor, ParseContext{}); -} - {{ident}} parse{{ident}}(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { {{ident}} out; diff --git a/gen/cpp/templates/group.h.tmpl b/gen/cpp/templates/group.h.tmpl index 1dbae5925..7eeacfb09 100644 --- a/gen/cpp/templates/group.h.tmpl +++ b/gen/cpp/templates/group.h.tmpl @@ -48,8 +48,6 @@ private: /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -{{ident}} parse{{ident}}(pugi::xml_node el, pugi::xml_node &cursor); - {{ident}} parse{{ident}}(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serialize{{ident}}(const {{ident}} &v, pugi::xml_node el); diff --git a/gen/cpp/templates/value_class.cpp.tmpl b/gen/cpp/templates/value_class.cpp.tmpl index 64a7a76ad..894c8cb03 100644 --- a/gen/cpp/templates/value_class.cpp.tmpl +++ b/gen/cpp/templates/value_class.cpp.tmpl @@ -24,11 +24,6 @@ void {{type.ident}}::set{{name.pascal}}({{type_ref.ident}} value) } {{/value}} -{{ident}} parse{{ident}}(pugi::xml_node el) -{ - return parse{{ident}}(el, ParseContext{}); -} - {{ident}} parse{{ident}}(pugi::xml_node el, const ParseContext &context) { {{ident}} out; @@ -37,11 +32,6 @@ void {{type.ident}}::set{{name.pascal}}({{type_ref.ident}} value) return out; } -void parse{{ident}}Content({{ident}} &out, pugi::xml_node el) -{ - parse{{ident}}Content(out, el, ParseContext{}); -} - void parse{{ident}}Content({{ident}} &out, pugi::xml_node el, const ParseContext &context) { {{#value}} diff --git a/gen/cpp/templates/value_class.h.tmpl b/gen/cpp/templates/value_class.h.tmpl index 7360d959e..c3a17ca9c 100644 --- a/gen/cpp/templates/value_class.h.tmpl +++ b/gen/cpp/templates/value_class.h.tmpl @@ -46,12 +46,8 @@ private: {{/value}} }; -{{ident}} parse{{ident}}(pugi::xml_node el); - {{ident}} parse{{ident}}(pugi::xml_node el, const ParseContext &context); -void parse{{ident}}Content({{ident}} &out, pugi::xml_node el); - void parse{{ident}}Content({{ident}} &out, pugi::xml_node el, const ParseContext &context); void serialize{{ident}}(const {{ident}} &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Accidental.cpp b/src/private/mx/core/generated/Accidental.cpp index 627d9eb50..b53b1d416 100644 --- a/src/private/mx/core/generated/Accidental.cpp +++ b/src/private/mx/core/generated/Accidental.cpp @@ -171,11 +171,6 @@ void Accidental::setValue(AccidentalValue value) m_value = std::move(value); } -Accidental parseAccidental(pugi::xml_node el) -{ - return parseAccidental(el, ParseContext{}); -} - Accidental parseAccidental(pugi::xml_node el, const ParseContext &context) { Accidental out; @@ -255,11 +250,6 @@ Accidental parseAccidental(pugi::xml_node el, const ParseContext &context) return out; } -void parseAccidentalContent(Accidental &out, pugi::xml_node el) -{ - parseAccidentalContent(out, el, ParseContext{}); -} - void parseAccidentalContent(Accidental &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/Accidental.h b/src/private/mx/core/generated/Accidental.h index 7e3d48486..593a4c993 100644 --- a/src/private/mx/core/generated/Accidental.h +++ b/src/private/mx/core/generated/Accidental.h @@ -86,12 +86,8 @@ class Accidental final AccidentalValue m_value{}; }; -Accidental parseAccidental(pugi::xml_node el); - Accidental parseAccidental(pugi::xml_node el, const ParseContext &context); -void parseAccidentalContent(Accidental &out, pugi::xml_node el); - void parseAccidentalContent(Accidental &out, pugi::xml_node el, const ParseContext &context); void serializeAccidental(const Accidental &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/AccidentalMark.cpp b/src/private/mx/core/generated/AccidentalMark.cpp index d4169f862..8fdc2bde4 100644 --- a/src/private/mx/core/generated/AccidentalMark.cpp +++ b/src/private/mx/core/generated/AccidentalMark.cpp @@ -171,11 +171,6 @@ void AccidentalMark::setValue(AccidentalValue value) m_value = std::move(value); } -AccidentalMark parseAccidentalMark(pugi::xml_node el) -{ - return parseAccidentalMark(el, ParseContext{}); -} - AccidentalMark parseAccidentalMark(pugi::xml_node el, const ParseContext &context) { AccidentalMark out; @@ -255,11 +250,6 @@ AccidentalMark parseAccidentalMark(pugi::xml_node el, const ParseContext &contex return out; } -void parseAccidentalMarkContent(AccidentalMark &out, pugi::xml_node el) -{ - parseAccidentalMarkContent(out, el, ParseContext{}); -} - void parseAccidentalMarkContent(AccidentalMark &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/AccidentalMark.h b/src/private/mx/core/generated/AccidentalMark.h index c8f2dd66f..992d90bf3 100644 --- a/src/private/mx/core/generated/AccidentalMark.h +++ b/src/private/mx/core/generated/AccidentalMark.h @@ -87,12 +87,8 @@ class AccidentalMark final AccidentalValue m_value{}; }; -AccidentalMark parseAccidentalMark(pugi::xml_node el); - AccidentalMark parseAccidentalMark(pugi::xml_node el, const ParseContext &context); -void parseAccidentalMarkContent(AccidentalMark &out, pugi::xml_node el); - void parseAccidentalMarkContent(AccidentalMark &out, pugi::xml_node el, const ParseContext &context); void serializeAccidentalMark(const AccidentalMark &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/AccidentalText.cpp b/src/private/mx/core/generated/AccidentalText.cpp index 545f510f8..3cd3ef165 100644 --- a/src/private/mx/core/generated/AccidentalText.cpp +++ b/src/private/mx/core/generated/AccidentalText.cpp @@ -251,11 +251,6 @@ void AccidentalText::setValue(AccidentalValue value) m_value = std::move(value); } -AccidentalText parseAccidentalText(pugi::xml_node el) -{ - return parseAccidentalText(el, ParseContext{}); -} - AccidentalText parseAccidentalText(pugi::xml_node el, const ParseContext &context) { AccidentalText out; @@ -367,11 +362,6 @@ AccidentalText parseAccidentalText(pugi::xml_node el, const ParseContext &contex return out; } -void parseAccidentalTextContent(AccidentalText &out, pugi::xml_node el) -{ - parseAccidentalTextContent(out, el, ParseContext{}); -} - void parseAccidentalTextContent(AccidentalText &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/AccidentalText.h b/src/private/mx/core/generated/AccidentalText.h index f1329b181..041e1301d 100644 --- a/src/private/mx/core/generated/AccidentalText.h +++ b/src/private/mx/core/generated/AccidentalText.h @@ -113,12 +113,8 @@ class AccidentalText final AccidentalValue m_value{}; }; -AccidentalText parseAccidentalText(pugi::xml_node el); - AccidentalText parseAccidentalText(pugi::xml_node el, const ParseContext &context); -void parseAccidentalTextContent(AccidentalText &out, pugi::xml_node el); - void parseAccidentalTextContent(AccidentalText &out, pugi::xml_node el, const ParseContext &context); void serializeAccidentalText(const AccidentalText &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Accord.cpp b/src/private/mx/core/generated/Accord.cpp index 0ac13bb18..8d7aff016 100644 --- a/src/private/mx/core/generated/Accord.cpp +++ b/src/private/mx/core/generated/Accord.cpp @@ -31,11 +31,6 @@ void Accord::setTuning(TuningGroup value) m_tuning = std::move(value); } -Accord parseAccord(pugi::xml_node el) -{ - return parseAccord(el, ParseContext{}); -} - Accord parseAccord(pugi::xml_node el, const ParseContext &context) { Accord out; @@ -59,11 +54,6 @@ Accord parseAccord(pugi::xml_node el, const ParseContext &context) return out; } -void parseAccordContent(Accord &out, pugi::xml_node el) -{ - parseAccordContent(out, el, ParseContext{}); -} - void parseAccordContent(Accord &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Accord.h b/src/private/mx/core/generated/Accord.h index dc868aa65..b6a6696c5 100644 --- a/src/private/mx/core/generated/Accord.h +++ b/src/private/mx/core/generated/Accord.h @@ -38,12 +38,8 @@ class Accord final TuningGroup m_tuning{}; }; -Accord parseAccord(pugi::xml_node el); - Accord parseAccord(pugi::xml_node el, const ParseContext &context); -void parseAccordContent(Accord &out, pugi::xml_node el); - void parseAccordContent(Accord &out, pugi::xml_node el, const ParseContext &context); void serializeAccord(const Accord &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/AccordionRegistration.cpp b/src/private/mx/core/generated/AccordionRegistration.cpp index 86f99b6f2..a7af034be 100644 --- a/src/private/mx/core/generated/AccordionRegistration.cpp +++ b/src/private/mx/core/generated/AccordionRegistration.cpp @@ -161,11 +161,6 @@ void AccordionRegistration::setAccordionLow(bool value) noexcept m_accordionLow = value; } -AccordionRegistration parseAccordionRegistration(pugi::xml_node el) -{ - return parseAccordionRegistration(el, ParseContext{}); -} - AccordionRegistration parseAccordionRegistration(pugi::xml_node el, const ParseContext &context) { AccordionRegistration out; @@ -233,11 +228,6 @@ AccordionRegistration parseAccordionRegistration(pugi::xml_node el, const ParseC return out; } -void parseAccordionRegistrationContent(AccordionRegistration &out, pugi::xml_node el) -{ - parseAccordionRegistrationContent(out, el, ParseContext{}); -} - void parseAccordionRegistrationContent(AccordionRegistration &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/AccordionRegistration.h b/src/private/mx/core/generated/AccordionRegistration.h index 486542a39..be151fd46 100644 --- a/src/private/mx/core/generated/AccordionRegistration.h +++ b/src/private/mx/core/generated/AccordionRegistration.h @@ -90,12 +90,8 @@ class AccordionRegistration final bool m_accordionLow{false}; }; -AccordionRegistration parseAccordionRegistration(pugi::xml_node el); - AccordionRegistration parseAccordionRegistration(pugi::xml_node el, const ParseContext &context); -void parseAccordionRegistrationContent(AccordionRegistration &out, pugi::xml_node el); - void parseAccordionRegistrationContent(AccordionRegistration &out, pugi::xml_node el, const ParseContext &context); void serializeAccordionRegistration(const AccordionRegistration &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/AllMarginsGroup.cpp b/src/private/mx/core/generated/AllMarginsGroup.cpp index 7616f8fb4..82919bddf 100644 --- a/src/private/mx/core/generated/AllMarginsGroup.cpp +++ b/src/private/mx/core/generated/AllMarginsGroup.cpp @@ -41,11 +41,6 @@ void AllMarginsGroup::setBottomMargin(Tenths value) m_bottomMargin = std::move(value); } -AllMarginsGroup parseAllMarginsGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseAllMarginsGroup(el, cursor, ParseContext{}); -} - AllMarginsGroup parseAllMarginsGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { AllMarginsGroup out; diff --git a/src/private/mx/core/generated/AllMarginsGroup.h b/src/private/mx/core/generated/AllMarginsGroup.h index 33f8d934c..7fb4ad86b 100644 --- a/src/private/mx/core/generated/AllMarginsGroup.h +++ b/src/private/mx/core/generated/AllMarginsGroup.h @@ -42,8 +42,6 @@ class AllMarginsGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -AllMarginsGroup parseAllMarginsGroup(pugi::xml_node el, pugi::xml_node &cursor); - AllMarginsGroup parseAllMarginsGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeAllMarginsGroup(const AllMarginsGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Appearance.cpp b/src/private/mx/core/generated/Appearance.cpp index 6d773f948..f4eaf43cd 100644 --- a/src/private/mx/core/generated/Appearance.cpp +++ b/src/private/mx/core/generated/Appearance.cpp @@ -86,11 +86,6 @@ void Appearance::setOtherAppearance(std::vector value) m_otherAppearance = std::move(value); } -Appearance parseAppearance(pugi::xml_node el) -{ - return parseAppearance(el, ParseContext{}); -} - Appearance parseAppearance(pugi::xml_node el, const ParseContext &context) { Appearance out; @@ -107,11 +102,6 @@ Appearance parseAppearance(pugi::xml_node el, const ParseContext &context) return out; } -void parseAppearanceContent(Appearance &out, pugi::xml_node el) -{ - parseAppearanceContent(out, el, ParseContext{}); -} - void parseAppearanceContent(Appearance &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Appearance.h b/src/private/mx/core/generated/Appearance.h index fcb261551..bee9bb31a 100644 --- a/src/private/mx/core/generated/Appearance.h +++ b/src/private/mx/core/generated/Appearance.h @@ -57,12 +57,8 @@ class Appearance final std::vector m_otherAppearance; }; -Appearance parseAppearance(pugi::xml_node el); - Appearance parseAppearance(pugi::xml_node el, const ParseContext &context); -void parseAppearanceContent(Appearance &out, pugi::xml_node el); - void parseAppearanceContent(Appearance &out, pugi::xml_node el, const ParseContext &context); void serializeAppearance(const Appearance &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Arpeggiate.cpp b/src/private/mx/core/generated/Arpeggiate.cpp index 75e961670..b4c7c8bfe 100644 --- a/src/private/mx/core/generated/Arpeggiate.cpp +++ b/src/private/mx/core/generated/Arpeggiate.cpp @@ -111,11 +111,6 @@ void Arpeggiate::setID(std::optional value) m_id = std::move(value); } -Arpeggiate parseArpeggiate(pugi::xml_node el) -{ - return parseArpeggiate(el, ParseContext{}); -} - Arpeggiate parseArpeggiate(pugi::xml_node el, const ParseContext &context) { Arpeggiate out; @@ -175,11 +170,6 @@ Arpeggiate parseArpeggiate(pugi::xml_node el, const ParseContext &context) return out; } -void parseArpeggiateContent(Arpeggiate &out, pugi::xml_node el) -{ - parseArpeggiateContent(out, el, ParseContext{}); -} - void parseArpeggiateContent(Arpeggiate &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/Arpeggiate.h b/src/private/mx/core/generated/Arpeggiate.h index 92aa90156..c698a4f36 100644 --- a/src/private/mx/core/generated/Arpeggiate.h +++ b/src/private/mx/core/generated/Arpeggiate.h @@ -70,12 +70,8 @@ class Arpeggiate final std::optional m_id; }; -Arpeggiate parseArpeggiate(pugi::xml_node el); - Arpeggiate parseArpeggiate(pugi::xml_node el, const ParseContext &context); -void parseArpeggiateContent(Arpeggiate &out, pugi::xml_node el); - void parseArpeggiateContent(Arpeggiate &out, pugi::xml_node el, const ParseContext &context); void serializeArpeggiate(const Arpeggiate &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Arrow.cpp b/src/private/mx/core/generated/Arrow.cpp index ff4b3711c..19f6b44da 100644 --- a/src/private/mx/core/generated/Arrow.cpp +++ b/src/private/mx/core/generated/Arrow.cpp @@ -131,11 +131,6 @@ void Arrow::setChoice(ArrowChoice value) m_choice = std::move(value); } -Arrow parseArrow(pugi::xml_node el) -{ - return parseArrow(el, ParseContext{}); -} - Arrow parseArrow(pugi::xml_node el, const ParseContext &context) { Arrow out; @@ -199,11 +194,6 @@ Arrow parseArrow(pugi::xml_node el, const ParseContext &context) return out; } -void parseArrowContent(Arrow &out, pugi::xml_node el) -{ - parseArrowContent(out, el, ParseContext{}); -} - void parseArrowContent(Arrow &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Arrow.h b/src/private/mx/core/generated/Arrow.h index b88955240..23afb1c71 100644 --- a/src/private/mx/core/generated/Arrow.h +++ b/src/private/mx/core/generated/Arrow.h @@ -78,12 +78,8 @@ class Arrow final ArrowChoice m_choice{}; }; -Arrow parseArrow(pugi::xml_node el); - Arrow parseArrow(pugi::xml_node el, const ParseContext &context); -void parseArrowContent(Arrow &out, pugi::xml_node el); - void parseArrowContent(Arrow &out, pugi::xml_node el, const ParseContext &context); void serializeArrow(const Arrow &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/ArrowChoice.cpp b/src/private/mx/core/generated/ArrowChoice.cpp index db4e9c9f7..061724740 100644 --- a/src/private/mx/core/generated/ArrowChoice.cpp +++ b/src/private/mx/core/generated/ArrowChoice.cpp @@ -26,11 +26,6 @@ ArrowChoice ArrowChoice::circularArrow(CircularArrow value) return ArrowChoice{Storage{std::in_place_index<1>, std::move(value)}}; } -ArrowChoice parseArrowChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseArrowChoice(el, cursor, ParseContext{}); -} - ArrowChoice parseArrowChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "arrow-direction"))) diff --git a/src/private/mx/core/generated/ArrowChoice.h b/src/private/mx/core/generated/ArrowChoice.h index 7c91a7303..7e0b17d39 100644 --- a/src/private/mx/core/generated/ArrowChoice.h +++ b/src/private/mx/core/generated/ArrowChoice.h @@ -82,8 +82,6 @@ class ArrowChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -ArrowChoice parseArrowChoice(pugi::xml_node el, pugi::xml_node &cursor); - ArrowChoice parseArrowChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeArrowChoice(const ArrowChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/ArrowChoiceGroup.cpp b/src/private/mx/core/generated/ArrowChoiceGroup.cpp index e31edce6b..2fd6322ed 100644 --- a/src/private/mx/core/generated/ArrowChoiceGroup.cpp +++ b/src/private/mx/core/generated/ArrowChoiceGroup.cpp @@ -41,11 +41,6 @@ void ArrowChoiceGroup::setArrowhead(bool value) noexcept m_arrowhead = value; } -ArrowChoiceGroup parseArrowChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseArrowChoiceGroup(el, cursor, ParseContext{}); -} - ArrowChoiceGroup parseArrowChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { ArrowChoiceGroup out; diff --git a/src/private/mx/core/generated/ArrowChoiceGroup.h b/src/private/mx/core/generated/ArrowChoiceGroup.h index 8ed0be9f6..4718780b9 100644 --- a/src/private/mx/core/generated/ArrowChoiceGroup.h +++ b/src/private/mx/core/generated/ArrowChoiceGroup.h @@ -43,8 +43,6 @@ class ArrowChoiceGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -ArrowChoiceGroup parseArrowChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor); - ArrowChoiceGroup parseArrowChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeArrowChoiceGroup(const ArrowChoiceGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Articulations.cpp b/src/private/mx/core/generated/Articulations.cpp index ff56284a5..7ad7b72f2 100644 --- a/src/private/mx/core/generated/Articulations.cpp +++ b/src/private/mx/core/generated/Articulations.cpp @@ -36,11 +36,6 @@ void Articulations::setChoice(std::vector value) m_choice = std::move(value); } -Articulations parseArticulations(pugi::xml_node el) -{ - return parseArticulations(el, ParseContext{}); -} - Articulations parseArticulations(pugi::xml_node el, const ParseContext &context) { Articulations out; @@ -64,11 +59,6 @@ Articulations parseArticulations(pugi::xml_node el, const ParseContext &context) return out; } -void parseArticulationsContent(Articulations &out, pugi::xml_node el) -{ - parseArticulationsContent(out, el, ParseContext{}); -} - void parseArticulationsContent(Articulations &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Articulations.h b/src/private/mx/core/generated/Articulations.h index 94b562070..d05eae7f5 100644 --- a/src/private/mx/core/generated/Articulations.h +++ b/src/private/mx/core/generated/Articulations.h @@ -39,12 +39,8 @@ class Articulations final std::vector m_choice; }; -Articulations parseArticulations(pugi::xml_node el); - Articulations parseArticulations(pugi::xml_node el, const ParseContext &context); -void parseArticulationsContent(Articulations &out, pugi::xml_node el); - void parseArticulationsContent(Articulations &out, pugi::xml_node el, const ParseContext &context); void serializeArticulations(const Articulations &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/ArticulationsChoice.cpp b/src/private/mx/core/generated/ArticulationsChoice.cpp index 62d5556a7..130f9f20f 100644 --- a/src/private/mx/core/generated/ArticulationsChoice.cpp +++ b/src/private/mx/core/generated/ArticulationsChoice.cpp @@ -101,11 +101,6 @@ ArticulationsChoice ArticulationsChoice::otherArticulation(OtherPlacementText va return ArticulationsChoice{Storage{std::in_place_index<16>, std::move(value)}}; } -ArticulationsChoice parseArticulationsChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseArticulationsChoice(el, cursor, ParseContext{}); -} - ArticulationsChoice parseArticulationsChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "accent"))) diff --git a/src/private/mx/core/generated/ArticulationsChoice.h b/src/private/mx/core/generated/ArticulationsChoice.h index aa0e20356..4337fc225 100644 --- a/src/private/mx/core/generated/ArticulationsChoice.h +++ b/src/private/mx/core/generated/ArticulationsChoice.h @@ -298,8 +298,6 @@ class ArticulationsChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -ArticulationsChoice parseArticulationsChoice(pugi::xml_node el, pugi::xml_node &cursor); - ArticulationsChoice parseArticulationsChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeArticulationsChoice(const ArticulationsChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Assess.cpp b/src/private/mx/core/generated/Assess.cpp index 7e9adb81f..c88eef864 100644 --- a/src/private/mx/core/generated/Assess.cpp +++ b/src/private/mx/core/generated/Assess.cpp @@ -41,11 +41,6 @@ void Assess::setTimeOnly(std::optional value) m_timeOnly = std::move(value); } -Assess parseAssess(pugi::xml_node el) -{ - return parseAssess(el, ParseContext{}); -} - Assess parseAssess(pugi::xml_node el, const ParseContext &context) { Assess out; @@ -83,11 +78,6 @@ Assess parseAssess(pugi::xml_node el, const ParseContext &context) return out; } -void parseAssessContent(Assess &out, pugi::xml_node el) -{ - parseAssessContent(out, el, ParseContext{}); -} - void parseAssessContent(Assess &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/Assess.h b/src/private/mx/core/generated/Assess.h index 562bd0702..74d0b9448 100644 --- a/src/private/mx/core/generated/Assess.h +++ b/src/private/mx/core/generated/Assess.h @@ -44,12 +44,8 @@ class Assess final std::optional m_timeOnly; }; -Assess parseAssess(pugi::xml_node el); - Assess parseAssess(pugi::xml_node el, const ParseContext &context); -void parseAssessContent(Assess &out, pugi::xml_node el); - void parseAssessContent(Assess &out, pugi::xml_node el, const ParseContext &context); void serializeAssess(const Assess &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Attributes.cpp b/src/private/mx/core/generated/Attributes.cpp index d7acf7b56..0a1619c6a 100644 --- a/src/private/mx/core/generated/Attributes.cpp +++ b/src/private/mx/core/generated/Attributes.cpp @@ -161,11 +161,6 @@ void Attributes::setMeasureStyle(std::vector value) m_measureStyle = std::move(value); } -Attributes parseAttributes(pugi::xml_node el) -{ - return parseAttributes(el, ParseContext{}); -} - Attributes parseAttributes(pugi::xml_node el, const ParseContext &context) { Attributes out; @@ -182,11 +177,6 @@ Attributes parseAttributes(pugi::xml_node el, const ParseContext &context) return out; } -void parseAttributesContent(Attributes &out, pugi::xml_node el) -{ - parseAttributesContent(out, el, ParseContext{}); -} - void parseAttributesContent(Attributes &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Attributes.h b/src/private/mx/core/generated/Attributes.h index 9023f6e4b..f6ce152ae 100644 --- a/src/private/mx/core/generated/Attributes.h +++ b/src/private/mx/core/generated/Attributes.h @@ -83,12 +83,8 @@ class Attributes final std::vector m_measureStyle; }; -Attributes parseAttributes(pugi::xml_node el); - Attributes parseAttributes(pugi::xml_node el, const ParseContext &context); -void parseAttributesContent(Attributes &out, pugi::xml_node el); - void parseAttributesContent(Attributes &out, pugi::xml_node el, const ParseContext &context); void serializeAttributes(const Attributes &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/AttributesChoice.cpp b/src/private/mx/core/generated/AttributesChoice.cpp index 1ccc20d23..e43dbd8d1 100644 --- a/src/private/mx/core/generated/AttributesChoice.cpp +++ b/src/private/mx/core/generated/AttributesChoice.cpp @@ -26,11 +26,6 @@ AttributesChoice AttributesChoice::forPart(std::vector value) return AttributesChoice{Storage{std::in_place_index<1>, std::move(value)}}; } -AttributesChoice parseAttributesChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseAttributesChoice(el, cursor, ParseContext{}); -} - AttributesChoice parseAttributesChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "transpose"))) diff --git a/src/private/mx/core/generated/AttributesChoice.h b/src/private/mx/core/generated/AttributesChoice.h index 628289b53..115545f8f 100644 --- a/src/private/mx/core/generated/AttributesChoice.h +++ b/src/private/mx/core/generated/AttributesChoice.h @@ -83,8 +83,6 @@ class AttributesChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -AttributesChoice parseAttributesChoice(pugi::xml_node el, pugi::xml_node &cursor); - AttributesChoice parseAttributesChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeAttributesChoice(const AttributesChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Backup.cpp b/src/private/mx/core/generated/Backup.cpp index 7946b027d..f03df9153 100644 --- a/src/private/mx/core/generated/Backup.cpp +++ b/src/private/mx/core/generated/Backup.cpp @@ -31,11 +31,6 @@ void Backup::setEditorial(EditorialGroup value) m_editorial = std::move(value); } -Backup parseBackup(pugi::xml_node el) -{ - return parseBackup(el, ParseContext{}); -} - Backup parseBackup(pugi::xml_node el, const ParseContext &context) { Backup out; @@ -52,11 +47,6 @@ Backup parseBackup(pugi::xml_node el, const ParseContext &context) return out; } -void parseBackupContent(Backup &out, pugi::xml_node el) -{ - parseBackupContent(out, el, ParseContext{}); -} - void parseBackupContent(Backup &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Backup.h b/src/private/mx/core/generated/Backup.h index 5bb803526..320a0362f 100644 --- a/src/private/mx/core/generated/Backup.h +++ b/src/private/mx/core/generated/Backup.h @@ -41,12 +41,8 @@ class Backup final EditorialGroup m_editorial{}; }; -Backup parseBackup(pugi::xml_node el); - Backup parseBackup(pugi::xml_node el, const ParseContext &context); -void parseBackupContent(Backup &out, pugi::xml_node el); - void parseBackupContent(Backup &out, pugi::xml_node el, const ParseContext &context); void serializeBackup(const Backup &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/BarStyleColor.cpp b/src/private/mx/core/generated/BarStyleColor.cpp index e9fd86692..f0e63fa2d 100644 --- a/src/private/mx/core/generated/BarStyleColor.cpp +++ b/src/private/mx/core/generated/BarStyleColor.cpp @@ -31,11 +31,6 @@ void BarStyleColor::setValue(BarStyle value) m_value = std::move(value); } -BarStyleColor parseBarStyleColor(pugi::xml_node el) -{ - return parseBarStyleColor(el, ParseContext{}); -} - BarStyleColor parseBarStyleColor(pugi::xml_node el, const ParseContext &context) { BarStyleColor out; @@ -59,11 +54,6 @@ BarStyleColor parseBarStyleColor(pugi::xml_node el, const ParseContext &context) return out; } -void parseBarStyleColorContent(BarStyleColor &out, pugi::xml_node el) -{ - parseBarStyleColorContent(out, el, ParseContext{}); -} - void parseBarStyleColorContent(BarStyleColor &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/BarStyleColor.h b/src/private/mx/core/generated/BarStyleColor.h index b71cf0f1d..9743f706e 100644 --- a/src/private/mx/core/generated/BarStyleColor.h +++ b/src/private/mx/core/generated/BarStyleColor.h @@ -33,12 +33,8 @@ class BarStyleColor final BarStyle m_value{}; }; -BarStyleColor parseBarStyleColor(pugi::xml_node el); - BarStyleColor parseBarStyleColor(pugi::xml_node el, const ParseContext &context); -void parseBarStyleColorContent(BarStyleColor &out, pugi::xml_node el); - void parseBarStyleColorContent(BarStyleColor &out, pugi::xml_node el, const ParseContext &context); void serializeBarStyleColor(const BarStyleColor &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Barline.cpp b/src/private/mx/core/generated/Barline.cpp index ca23c9eee..077373d8f 100644 --- a/src/private/mx/core/generated/Barline.cpp +++ b/src/private/mx/core/generated/Barline.cpp @@ -151,11 +151,6 @@ void Barline::setRepeat(std::optional value) m_repeat = std::move(value); } -Barline parseBarline(pugi::xml_node el) -{ - return parseBarline(el, ParseContext{}); -} - Barline parseBarline(pugi::xml_node el, const ParseContext &context) { Barline out; @@ -195,11 +190,6 @@ Barline parseBarline(pugi::xml_node el, const ParseContext &context) return out; } -void parseBarlineContent(Barline &out, pugi::xml_node el) -{ - parseBarlineContent(out, el, ParseContext{}); -} - void parseBarlineContent(Barline &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Barline.h b/src/private/mx/core/generated/Barline.h index 617be1451..ec2865294 100644 --- a/src/private/mx/core/generated/Barline.h +++ b/src/private/mx/core/generated/Barline.h @@ -98,12 +98,8 @@ class Barline final std::optional m_repeat; }; -Barline parseBarline(pugi::xml_node el); - Barline parseBarline(pugi::xml_node el, const ParseContext &context); -void parseBarlineContent(Barline &out, pugi::xml_node el); - void parseBarlineContent(Barline &out, pugi::xml_node el, const ParseContext &context); void serializeBarline(const Barline &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Barre.cpp b/src/private/mx/core/generated/Barre.cpp index 7b8ea8795..4d0781d2a 100644 --- a/src/private/mx/core/generated/Barre.cpp +++ b/src/private/mx/core/generated/Barre.cpp @@ -31,11 +31,6 @@ void Barre::setColor(std::optional value) m_color = std::move(value); } -Barre parseBarre(pugi::xml_node el) -{ - return parseBarre(el, ParseContext{}); -} - Barre parseBarre(pugi::xml_node el, const ParseContext &context) { Barre out; @@ -69,11 +64,6 @@ Barre parseBarre(pugi::xml_node el, const ParseContext &context) return out; } -void parseBarreContent(Barre &out, pugi::xml_node el) -{ - parseBarreContent(out, el, ParseContext{}); -} - void parseBarreContent(Barre &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/Barre.h b/src/private/mx/core/generated/Barre.h index 85f5509a3..175e781c2 100644 --- a/src/private/mx/core/generated/Barre.h +++ b/src/private/mx/core/generated/Barre.h @@ -35,12 +35,8 @@ class Barre final std::optional m_color; }; -Barre parseBarre(pugi::xml_node el); - Barre parseBarre(pugi::xml_node el, const ParseContext &context); -void parseBarreContent(Barre &out, pugi::xml_node el); - void parseBarreContent(Barre &out, pugi::xml_node el, const ParseContext &context); void serializeBarre(const Barre &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Bass.cpp b/src/private/mx/core/generated/Bass.cpp index fb0aab6ea..800dd1cac 100644 --- a/src/private/mx/core/generated/Bass.cpp +++ b/src/private/mx/core/generated/Bass.cpp @@ -51,11 +51,6 @@ void Bass::setBassAlter(std::optional value) m_bassAlter = std::move(value); } -Bass parseBass(pugi::xml_node el) -{ - return parseBass(el, ParseContext{}); -} - Bass parseBass(pugi::xml_node el, const ParseContext &context) { Bass out; @@ -79,11 +74,6 @@ Bass parseBass(pugi::xml_node el, const ParseContext &context) return out; } -void parseBassContent(Bass &out, pugi::xml_node el) -{ - parseBassContent(out, el, ParseContext{}); -} - void parseBassContent(Bass &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Bass.h b/src/private/mx/core/generated/Bass.h index a175e5e55..294315ff3 100644 --- a/src/private/mx/core/generated/Bass.h +++ b/src/private/mx/core/generated/Bass.h @@ -48,12 +48,8 @@ class Bass final std::optional m_bassAlter; }; -Bass parseBass(pugi::xml_node el); - Bass parseBass(pugi::xml_node el, const ParseContext &context); -void parseBassContent(Bass &out, pugi::xml_node el); - void parseBassContent(Bass &out, pugi::xml_node el, const ParseContext &context); void serializeBass(const Bass &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/BassStep.cpp b/src/private/mx/core/generated/BassStep.cpp index 39a20e381..2a3f2493a 100644 --- a/src/private/mx/core/generated/BassStep.cpp +++ b/src/private/mx/core/generated/BassStep.cpp @@ -121,11 +121,6 @@ void BassStep::setValue(Step value) m_value = std::move(value); } -BassStep parseBassStep(pugi::xml_node el) -{ - return parseBassStep(el, ParseContext{}); -} - BassStep parseBassStep(pugi::xml_node el, const ParseContext &context) { BassStep out; @@ -185,11 +180,6 @@ BassStep parseBassStep(pugi::xml_node el, const ParseContext &context) return out; } -void parseBassStepContent(BassStep &out, pugi::xml_node el) -{ - parseBassStepContent(out, el, ParseContext{}); -} - void parseBassStepContent(BassStep &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/BassStep.h b/src/private/mx/core/generated/BassStep.h index 6be73b59d..05952b559 100644 --- a/src/private/mx/core/generated/BassStep.h +++ b/src/private/mx/core/generated/BassStep.h @@ -67,12 +67,8 @@ class BassStep final Step m_value{}; }; -BassStep parseBassStep(pugi::xml_node el); - BassStep parseBassStep(pugi::xml_node el, const ParseContext &context); -void parseBassStepContent(BassStep &out, pugi::xml_node el); - void parseBassStepContent(BassStep &out, pugi::xml_node el, const ParseContext &context); void serializeBassStep(const BassStep &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Beam.cpp b/src/private/mx/core/generated/Beam.cpp index 90f2a58fe..d7c23c2b2 100644 --- a/src/private/mx/core/generated/Beam.cpp +++ b/src/private/mx/core/generated/Beam.cpp @@ -71,11 +71,6 @@ void Beam::setValue(BeamValue value) m_value = std::move(value); } -Beam parseBeam(pugi::xml_node el) -{ - return parseBeam(el, ParseContext{}); -} - Beam parseBeam(pugi::xml_node el, const ParseContext &context) { Beam out; @@ -115,11 +110,6 @@ Beam parseBeam(pugi::xml_node el, const ParseContext &context) return out; } -void parseBeamContent(Beam &out, pugi::xml_node el) -{ - parseBeamContent(out, el, ParseContext{}); -} - void parseBeamContent(Beam &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/Beam.h b/src/private/mx/core/generated/Beam.h index d857ef9a2..032c14949 100644 --- a/src/private/mx/core/generated/Beam.h +++ b/src/private/mx/core/generated/Beam.h @@ -59,12 +59,8 @@ class Beam final BeamValue m_value{}; }; -Beam parseBeam(pugi::xml_node el); - Beam parseBeam(pugi::xml_node el, const ParseContext &context); -void parseBeamContent(Beam &out, pugi::xml_node el); - void parseBeamContent(Beam &out, pugi::xml_node el, const ParseContext &context); void serializeBeam(const Beam &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/BeatRepeat.cpp b/src/private/mx/core/generated/BeatRepeat.cpp index 2c9612dd2..9ac576e7e 100644 --- a/src/private/mx/core/generated/BeatRepeat.cpp +++ b/src/private/mx/core/generated/BeatRepeat.cpp @@ -51,11 +51,6 @@ void BeatRepeat::setSlash(std::optional value) m_slash = std::move(value); } -BeatRepeat parseBeatRepeat(pugi::xml_node el) -{ - return parseBeatRepeat(el, ParseContext{}); -} - BeatRepeat parseBeatRepeat(pugi::xml_node el, const ParseContext &context) { BeatRepeat out; @@ -93,11 +88,6 @@ BeatRepeat parseBeatRepeat(pugi::xml_node el, const ParseContext &context) return out; } -void parseBeatRepeatContent(BeatRepeat &out, pugi::xml_node el) -{ - parseBeatRepeatContent(out, el, ParseContext{}); -} - void parseBeatRepeatContent(BeatRepeat &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/BeatRepeat.h b/src/private/mx/core/generated/BeatRepeat.h index 8ca873153..e65d7f303 100644 --- a/src/private/mx/core/generated/BeatRepeat.h +++ b/src/private/mx/core/generated/BeatRepeat.h @@ -52,12 +52,8 @@ class BeatRepeat final std::optional m_slash; }; -BeatRepeat parseBeatRepeat(pugi::xml_node el); - BeatRepeat parseBeatRepeat(pugi::xml_node el, const ParseContext &context); -void parseBeatRepeatContent(BeatRepeat &out, pugi::xml_node el); - void parseBeatRepeatContent(BeatRepeat &out, pugi::xml_node el, const ParseContext &context); void serializeBeatRepeat(const BeatRepeat &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/BeatUnitGroup.cpp b/src/private/mx/core/generated/BeatUnitGroup.cpp index 15d231b89..314d07a22 100644 --- a/src/private/mx/core/generated/BeatUnitGroup.cpp +++ b/src/private/mx/core/generated/BeatUnitGroup.cpp @@ -36,11 +36,6 @@ void BeatUnitGroup::setBeatUnitDot(std::vector value) m_beatUnitDot = std::move(value); } -BeatUnitGroup parseBeatUnitGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseBeatUnitGroup(el, cursor, ParseContext{}); -} - BeatUnitGroup parseBeatUnitGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { BeatUnitGroup out; diff --git a/src/private/mx/core/generated/BeatUnitGroup.h b/src/private/mx/core/generated/BeatUnitGroup.h index 1210d5b27..58b582db9 100644 --- a/src/private/mx/core/generated/BeatUnitGroup.h +++ b/src/private/mx/core/generated/BeatUnitGroup.h @@ -41,8 +41,6 @@ class BeatUnitGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -BeatUnitGroup parseBeatUnitGroup(pugi::xml_node el, pugi::xml_node &cursor); - BeatUnitGroup parseBeatUnitGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeBeatUnitGroup(const BeatUnitGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/BeatUnitTied.cpp b/src/private/mx/core/generated/BeatUnitTied.cpp index 4a6679b83..01b3d189c 100644 --- a/src/private/mx/core/generated/BeatUnitTied.cpp +++ b/src/private/mx/core/generated/BeatUnitTied.cpp @@ -21,11 +21,6 @@ void BeatUnitTied::setBeatUnit(BeatUnitGroup value) m_beatUnit = std::move(value); } -BeatUnitTied parseBeatUnitTied(pugi::xml_node el) -{ - return parseBeatUnitTied(el, ParseContext{}); -} - BeatUnitTied parseBeatUnitTied(pugi::xml_node el, const ParseContext &context) { BeatUnitTied out; @@ -42,11 +37,6 @@ BeatUnitTied parseBeatUnitTied(pugi::xml_node el, const ParseContext &context) return out; } -void parseBeatUnitTiedContent(BeatUnitTied &out, pugi::xml_node el) -{ - parseBeatUnitTiedContent(out, el, ParseContext{}); -} - void parseBeatUnitTiedContent(BeatUnitTied &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/BeatUnitTied.h b/src/private/mx/core/generated/BeatUnitTied.h index 204e084a3..002cab66f 100644 --- a/src/private/mx/core/generated/BeatUnitTied.h +++ b/src/private/mx/core/generated/BeatUnitTied.h @@ -36,12 +36,8 @@ class BeatUnitTied final BeatUnitGroup m_beatUnit{}; }; -BeatUnitTied parseBeatUnitTied(pugi::xml_node el); - BeatUnitTied parseBeatUnitTied(pugi::xml_node el, const ParseContext &context); -void parseBeatUnitTiedContent(BeatUnitTied &out, pugi::xml_node el); - void parseBeatUnitTiedContent(BeatUnitTied &out, pugi::xml_node el, const ParseContext &context); void serializeBeatUnitTied(const BeatUnitTied &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Beater.cpp b/src/private/mx/core/generated/Beater.cpp index 9107c5857..d7ef400fc 100644 --- a/src/private/mx/core/generated/Beater.cpp +++ b/src/private/mx/core/generated/Beater.cpp @@ -31,11 +31,6 @@ void Beater::setValue(BeaterValue value) m_value = std::move(value); } -Beater parseBeater(pugi::xml_node el) -{ - return parseBeater(el, ParseContext{}); -} - Beater parseBeater(pugi::xml_node el, const ParseContext &context) { Beater out; @@ -59,11 +54,6 @@ Beater parseBeater(pugi::xml_node el, const ParseContext &context) return out; } -void parseBeaterContent(Beater &out, pugi::xml_node el) -{ - parseBeaterContent(out, el, ParseContext{}); -} - void parseBeaterContent(Beater &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/Beater.h b/src/private/mx/core/generated/Beater.h index 9d3a2561c..1c113e739 100644 --- a/src/private/mx/core/generated/Beater.h +++ b/src/private/mx/core/generated/Beater.h @@ -34,12 +34,8 @@ class Beater final BeaterValue m_value{}; }; -Beater parseBeater(pugi::xml_node el); - Beater parseBeater(pugi::xml_node el, const ParseContext &context); -void parseBeaterContent(Beater &out, pugi::xml_node el); - void parseBeaterContent(Beater &out, pugi::xml_node el, const ParseContext &context); void serializeBeater(const Beater &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Bend.cpp b/src/private/mx/core/generated/Bend.cpp index 681ecb823..04bf07b95 100644 --- a/src/private/mx/core/generated/Bend.cpp +++ b/src/private/mx/core/generated/Bend.cpp @@ -181,11 +181,6 @@ void Bend::setWithBar(std::optional value) m_withBar = std::move(value); } -Bend parseBend(pugi::xml_node el) -{ - return parseBend(el, ParseContext{}); -} - Bend parseBend(pugi::xml_node el, const ParseContext &context) { Bend out; @@ -261,11 +256,6 @@ Bend parseBend(pugi::xml_node el, const ParseContext &context) return out; } -void parseBendContent(Bend &out, pugi::xml_node el) -{ - parseBendContent(out, el, ParseContext{}); -} - void parseBendContent(Bend &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Bend.h b/src/private/mx/core/generated/Bend.h index c7c7bcdf0..48c52eb08 100644 --- a/src/private/mx/core/generated/Bend.h +++ b/src/private/mx/core/generated/Bend.h @@ -97,12 +97,8 @@ class Bend final std::optional m_withBar; }; -Bend parseBend(pugi::xml_node el); - Bend parseBend(pugi::xml_node el, const ParseContext &context); -void parseBendContent(Bend &out, pugi::xml_node el); - void parseBendContent(Bend &out, pugi::xml_node el, const ParseContext &context); void serializeBend(const Bend &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/BendChoice.cpp b/src/private/mx/core/generated/BendChoice.cpp index 8866d0549..54d7f5488 100644 --- a/src/private/mx/core/generated/BendChoice.cpp +++ b/src/private/mx/core/generated/BendChoice.cpp @@ -26,11 +26,6 @@ BendChoice BendChoice::release(Release value) return BendChoice{Storage{std::in_place_index<1>, std::move(value)}}; } -BendChoice parseBendChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseBendChoice(el, cursor, ParseContext{}); -} - BendChoice parseBendChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "pre-bend"))) diff --git a/src/private/mx/core/generated/BendChoice.h b/src/private/mx/core/generated/BendChoice.h index 669ac8116..4a8deebf1 100644 --- a/src/private/mx/core/generated/BendChoice.h +++ b/src/private/mx/core/generated/BendChoice.h @@ -82,8 +82,6 @@ class BendChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -BendChoice parseBendChoice(pugi::xml_node el, pugi::xml_node &cursor); - BendChoice parseBendChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeBendChoice(const BendChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Bookmark.cpp b/src/private/mx/core/generated/Bookmark.cpp index 061ba76a6..25c00a834 100644 --- a/src/private/mx/core/generated/Bookmark.cpp +++ b/src/private/mx/core/generated/Bookmark.cpp @@ -51,11 +51,6 @@ void Bookmark::setPosition(std::optional value) m_position = std::move(value); } -Bookmark parseBookmark(pugi::xml_node el) -{ - return parseBookmark(el, ParseContext{}); -} - Bookmark parseBookmark(pugi::xml_node el, const ParseContext &context) { Bookmark out; @@ -97,11 +92,6 @@ Bookmark parseBookmark(pugi::xml_node el, const ParseContext &context) return out; } -void parseBookmarkContent(Bookmark &out, pugi::xml_node el) -{ - parseBookmarkContent(out, el, ParseContext{}); -} - void parseBookmarkContent(Bookmark &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/Bookmark.h b/src/private/mx/core/generated/Bookmark.h index 4dbbd44cd..1743fa627 100644 --- a/src/private/mx/core/generated/Bookmark.h +++ b/src/private/mx/core/generated/Bookmark.h @@ -39,12 +39,8 @@ class Bookmark final std::optional m_position; }; -Bookmark parseBookmark(pugi::xml_node el); - Bookmark parseBookmark(pugi::xml_node el, const ParseContext &context); -void parseBookmarkContent(Bookmark &out, pugi::xml_node el); - void parseBookmarkContent(Bookmark &out, pugi::xml_node el, const ParseContext &context); void serializeBookmark(const Bookmark &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Bracket.cpp b/src/private/mx/core/generated/Bracket.cpp index 821af4a24..72500550d 100644 --- a/src/private/mx/core/generated/Bracket.cpp +++ b/src/private/mx/core/generated/Bracket.cpp @@ -141,11 +141,6 @@ void Bracket::setID(std::optional value) m_id = std::move(value); } -Bracket parseBracket(pugi::xml_node el) -{ - return parseBracket(el, ParseContext{}); -} - Bracket parseBracket(pugi::xml_node el, const ParseContext &context) { Bracket out; @@ -229,11 +224,6 @@ Bracket parseBracket(pugi::xml_node el, const ParseContext &context) return out; } -void parseBracketContent(Bracket &out, pugi::xml_node el) -{ - parseBracketContent(out, el, ParseContext{}); -} - void parseBracketContent(Bracket &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/Bracket.h b/src/private/mx/core/generated/Bracket.h index a83a9e5b8..f0babd13e 100644 --- a/src/private/mx/core/generated/Bracket.h +++ b/src/private/mx/core/generated/Bracket.h @@ -75,12 +75,8 @@ class Bracket final std::optional m_id; }; -Bracket parseBracket(pugi::xml_node el); - Bracket parseBracket(pugi::xml_node el, const ParseContext &context); -void parseBracketContent(Bracket &out, pugi::xml_node el); - void parseBracketContent(Bracket &out, pugi::xml_node el, const ParseContext &context); void serializeBracket(const Bracket &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/BreathMark.cpp b/src/private/mx/core/generated/BreathMark.cpp index b73c4f69e..f26fc425b 100644 --- a/src/private/mx/core/generated/BreathMark.cpp +++ b/src/private/mx/core/generated/BreathMark.cpp @@ -121,11 +121,6 @@ void BreathMark::setValue(BreathMarkValue value) m_value = std::move(value); } -BreathMark parseBreathMark(pugi::xml_node el) -{ - return parseBreathMark(el, ParseContext{}); -} - BreathMark parseBreathMark(pugi::xml_node el, const ParseContext &context) { BreathMark out; @@ -185,11 +180,6 @@ BreathMark parseBreathMark(pugi::xml_node el, const ParseContext &context) return out; } -void parseBreathMarkContent(BreathMark &out, pugi::xml_node el) -{ - parseBreathMarkContent(out, el, ParseContext{}); -} - void parseBreathMarkContent(BreathMark &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/BreathMark.h b/src/private/mx/core/generated/BreathMark.h index 9962a7044..bb008a0b4 100644 --- a/src/private/mx/core/generated/BreathMark.h +++ b/src/private/mx/core/generated/BreathMark.h @@ -66,12 +66,8 @@ class BreathMark final BreathMarkValue m_value{}; }; -BreathMark parseBreathMark(pugi::xml_node el); - BreathMark parseBreathMark(pugi::xml_node el, const ParseContext &context); -void parseBreathMarkContent(BreathMark &out, pugi::xml_node el); - void parseBreathMarkContent(BreathMark &out, pugi::xml_node el, const ParseContext &context); void serializeBreathMark(const BreathMark &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Caesura.cpp b/src/private/mx/core/generated/Caesura.cpp index 3fafe625e..2b6363c1d 100644 --- a/src/private/mx/core/generated/Caesura.cpp +++ b/src/private/mx/core/generated/Caesura.cpp @@ -121,11 +121,6 @@ void Caesura::setValue(CaesuraValue value) m_value = std::move(value); } -Caesura parseCaesura(pugi::xml_node el) -{ - return parseCaesura(el, ParseContext{}); -} - Caesura parseCaesura(pugi::xml_node el, const ParseContext &context) { Caesura out; @@ -185,11 +180,6 @@ Caesura parseCaesura(pugi::xml_node el, const ParseContext &context) return out; } -void parseCaesuraContent(Caesura &out, pugi::xml_node el) -{ - parseCaesuraContent(out, el, ParseContext{}); -} - void parseCaesuraContent(Caesura &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/Caesura.h b/src/private/mx/core/generated/Caesura.h index e2282cd57..f5f9e2013 100644 --- a/src/private/mx/core/generated/Caesura.h +++ b/src/private/mx/core/generated/Caesura.h @@ -67,12 +67,8 @@ class Caesura final CaesuraValue m_value{}; }; -Caesura parseCaesura(pugi::xml_node el); - Caesura parseCaesura(pugi::xml_node el, const ParseContext &context); -void parseCaesuraContent(Caesura &out, pugi::xml_node el); - void parseCaesuraContent(Caesura &out, pugi::xml_node el, const ParseContext &context); void serializeCaesura(const Caesura &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Cancel.cpp b/src/private/mx/core/generated/Cancel.cpp index 57efcf59c..78f805959 100644 --- a/src/private/mx/core/generated/Cancel.cpp +++ b/src/private/mx/core/generated/Cancel.cpp @@ -31,11 +31,6 @@ void Cancel::setValue(Fifths value) m_value = std::move(value); } -Cancel parseCancel(pugi::xml_node el) -{ - return parseCancel(el, ParseContext{}); -} - Cancel parseCancel(pugi::xml_node el, const ParseContext &context) { Cancel out; @@ -59,11 +54,6 @@ Cancel parseCancel(pugi::xml_node el, const ParseContext &context) return out; } -void parseCancelContent(Cancel &out, pugi::xml_node el) -{ - parseCancelContent(out, el, ParseContext{}); -} - void parseCancelContent(Cancel &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/Cancel.h b/src/private/mx/core/generated/Cancel.h index 695d50aab..adc673c58 100644 --- a/src/private/mx/core/generated/Cancel.h +++ b/src/private/mx/core/generated/Cancel.h @@ -37,12 +37,8 @@ class Cancel final Fifths m_value{}; }; -Cancel parseCancel(pugi::xml_node el); - Cancel parseCancel(pugi::xml_node el, const ParseContext &context); -void parseCancelContent(Cancel &out, pugi::xml_node el); - void parseCancelContent(Cancel &out, pugi::xml_node el, const ParseContext &context); void serializeCancel(const Cancel &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Clef.cpp b/src/private/mx/core/generated/Clef.cpp index 419510369..96ba91716 100644 --- a/src/private/mx/core/generated/Clef.cpp +++ b/src/private/mx/core/generated/Clef.cpp @@ -171,11 +171,6 @@ void Clef::setClef(ClefGroup value) m_clef = std::move(value); } -Clef parseClef(pugi::xml_node el) -{ - return parseClef(el, ParseContext{}); -} - Clef parseClef(pugi::xml_node el, const ParseContext &context) { Clef out; @@ -255,11 +250,6 @@ Clef parseClef(pugi::xml_node el, const ParseContext &context) return out; } -void parseClefContent(Clef &out, pugi::xml_node el) -{ - parseClefContent(out, el, ParseContext{}); -} - void parseClefContent(Clef &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Clef.h b/src/private/mx/core/generated/Clef.h index 9e268bbad..f3b34bfc5 100644 --- a/src/private/mx/core/generated/Clef.h +++ b/src/private/mx/core/generated/Clef.h @@ -99,12 +99,8 @@ class Clef final ClefGroup m_clef{}; }; -Clef parseClef(pugi::xml_node el); - Clef parseClef(pugi::xml_node el, const ParseContext &context); -void parseClefContent(Clef &out, pugi::xml_node el); - void parseClefContent(Clef &out, pugi::xml_node el, const ParseContext &context); void serializeClef(const Clef &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/ClefGroup.cpp b/src/private/mx/core/generated/ClefGroup.cpp index 053208694..b427bbc03 100644 --- a/src/private/mx/core/generated/ClefGroup.cpp +++ b/src/private/mx/core/generated/ClefGroup.cpp @@ -41,11 +41,6 @@ void ClefGroup::setClefOctaveChange(std::optional value) m_clefOctaveChange = std::move(value); } -ClefGroup parseClefGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseClefGroup(el, cursor, ParseContext{}); -} - ClefGroup parseClefGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { ClefGroup out; diff --git a/src/private/mx/core/generated/ClefGroup.h b/src/private/mx/core/generated/ClefGroup.h index 137e40f98..1670fae1b 100644 --- a/src/private/mx/core/generated/ClefGroup.h +++ b/src/private/mx/core/generated/ClefGroup.h @@ -42,8 +42,6 @@ class ClefGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -ClefGroup parseClefGroup(pugi::xml_node el, pugi::xml_node &cursor); - ClefGroup parseClefGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeClefGroup(const ClefGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Coda.cpp b/src/private/mx/core/generated/Coda.cpp index acc4b4720..428ede00c 100644 --- a/src/private/mx/core/generated/Coda.cpp +++ b/src/private/mx/core/generated/Coda.cpp @@ -141,11 +141,6 @@ void Coda::setID(std::optional value) m_id = std::move(value); } -Coda parseCoda(pugi::xml_node el) -{ - return parseCoda(el, ParseContext{}); -} - Coda parseCoda(pugi::xml_node el, const ParseContext &context) { Coda out; @@ -217,11 +212,6 @@ Coda parseCoda(pugi::xml_node el, const ParseContext &context) return out; } -void parseCodaContent(Coda &out, pugi::xml_node el) -{ - parseCodaContent(out, el, ParseContext{}); -} - void parseCodaContent(Coda &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/Coda.h b/src/private/mx/core/generated/Coda.h index fae463714..ba0c056f5 100644 --- a/src/private/mx/core/generated/Coda.h +++ b/src/private/mx/core/generated/Coda.h @@ -76,12 +76,8 @@ class Coda final std::optional m_id; }; -Coda parseCoda(pugi::xml_node el); - Coda parseCoda(pugi::xml_node el, const ParseContext &context); -void parseCodaContent(Coda &out, pugi::xml_node el); - void parseCodaContent(Coda &out, pugi::xml_node el, const ParseContext &context); void serializeCoda(const Coda &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Credit.cpp b/src/private/mx/core/generated/Credit.cpp index 110a7fe31..dff9671fe 100644 --- a/src/private/mx/core/generated/Credit.cpp +++ b/src/private/mx/core/generated/Credit.cpp @@ -86,11 +86,6 @@ void Credit::setChoice(CreditChoice value) m_choice = std::move(value); } -Credit parseCredit(pugi::xml_node el) -{ - return parseCredit(el, ParseContext{}); -} - Credit parseCredit(pugi::xml_node el, const ParseContext &context) { Credit out; @@ -118,11 +113,6 @@ Credit parseCredit(pugi::xml_node el, const ParseContext &context) return out; } -void parseCreditContent(Credit &out, pugi::xml_node el) -{ - parseCreditContent(out, el, ParseContext{}); -} - void parseCreditContent(Credit &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Credit.h b/src/private/mx/core/generated/Credit.h index 542e2350d..9eab4c77c 100644 --- a/src/private/mx/core/generated/Credit.h +++ b/src/private/mx/core/generated/Credit.h @@ -69,12 +69,8 @@ class Credit final CreditChoice m_choice{}; }; -Credit parseCredit(pugi::xml_node el); - Credit parseCredit(pugi::xml_node el, const ParseContext &context); -void parseCreditContent(Credit &out, pugi::xml_node el); - void parseCreditContent(Credit &out, pugi::xml_node el, const ParseContext &context); void serializeCredit(const Credit &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/CreditChoice.cpp b/src/private/mx/core/generated/CreditChoice.cpp index ca6df48d2..a42ed18a4 100644 --- a/src/private/mx/core/generated/CreditChoice.cpp +++ b/src/private/mx/core/generated/CreditChoice.cpp @@ -26,11 +26,6 @@ CreditChoice CreditChoice::group(CreditChoiceGroup value) return CreditChoice{Storage{std::in_place_index<1>, std::move(value)}}; } -CreditChoice parseCreditChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseCreditChoice(el, cursor, ParseContext{}); -} - CreditChoice parseCreditChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "credit-image"))) diff --git a/src/private/mx/core/generated/CreditChoice.h b/src/private/mx/core/generated/CreditChoice.h index a8adafede..c869b0296 100644 --- a/src/private/mx/core/generated/CreditChoice.h +++ b/src/private/mx/core/generated/CreditChoice.h @@ -82,8 +82,6 @@ class CreditChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -CreditChoice parseCreditChoice(pugi::xml_node el, pugi::xml_node &cursor); - CreditChoice parseCreditChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeCreditChoice(const CreditChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/CreditChoiceGroup.cpp b/src/private/mx/core/generated/CreditChoiceGroup.cpp index 6bfd61b5e..0303dd934 100644 --- a/src/private/mx/core/generated/CreditChoiceGroup.cpp +++ b/src/private/mx/core/generated/CreditChoiceGroup.cpp @@ -36,11 +36,6 @@ void CreditChoiceGroup::setGroup(std::vector value) m_group = std::move(value); } -CreditChoiceGroup parseCreditChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseCreditChoiceGroup(el, cursor, ParseContext{}); -} - CreditChoiceGroup parseCreditChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { CreditChoiceGroup out; diff --git a/src/private/mx/core/generated/CreditChoiceGroup.h b/src/private/mx/core/generated/CreditChoiceGroup.h index d5e760075..99a712c85 100644 --- a/src/private/mx/core/generated/CreditChoiceGroup.h +++ b/src/private/mx/core/generated/CreditChoiceGroup.h @@ -40,8 +40,6 @@ class CreditChoiceGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -CreditChoiceGroup parseCreditChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor); - CreditChoiceGroup parseCreditChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeCreditChoiceGroup(const CreditChoiceGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/CreditChoiceGroupChoice.cpp b/src/private/mx/core/generated/CreditChoiceGroupChoice.cpp index bdd8060ff..e134cd82b 100644 --- a/src/private/mx/core/generated/CreditChoiceGroupChoice.cpp +++ b/src/private/mx/core/generated/CreditChoiceGroupChoice.cpp @@ -26,11 +26,6 @@ CreditChoiceGroupChoice CreditChoiceGroupChoice::creditSymbol(FormattedSymbolID return CreditChoiceGroupChoice{Storage{std::in_place_index<1>, std::move(value)}}; } -CreditChoiceGroupChoice parseCreditChoiceGroupChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseCreditChoiceGroupChoice(el, cursor, ParseContext{}); -} - CreditChoiceGroupChoice parseCreditChoiceGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { diff --git a/src/private/mx/core/generated/CreditChoiceGroupChoice.h b/src/private/mx/core/generated/CreditChoiceGroupChoice.h index 2286eb07b..8be47776f 100644 --- a/src/private/mx/core/generated/CreditChoiceGroupChoice.h +++ b/src/private/mx/core/generated/CreditChoiceGroupChoice.h @@ -82,8 +82,6 @@ class CreditChoiceGroupChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -CreditChoiceGroupChoice parseCreditChoiceGroupChoice(pugi::xml_node el, pugi::xml_node &cursor); - CreditChoiceGroupChoice parseCreditChoiceGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); diff --git a/src/private/mx/core/generated/CreditChoiceGroupGroup.cpp b/src/private/mx/core/generated/CreditChoiceGroupGroup.cpp index 1739357b8..476ae59c5 100644 --- a/src/private/mx/core/generated/CreditChoiceGroupGroup.cpp +++ b/src/private/mx/core/generated/CreditChoiceGroupGroup.cpp @@ -51,11 +51,6 @@ void CreditChoiceGroupGroup::setChoice(CreditChoiceGroupGroupChoice value) m_choice = std::move(value); } -CreditChoiceGroupGroup parseCreditChoiceGroupGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseCreditChoiceGroupGroup(el, cursor, ParseContext{}); -} - CreditChoiceGroupGroup parseCreditChoiceGroupGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { diff --git a/src/private/mx/core/generated/CreditChoiceGroupGroup.h b/src/private/mx/core/generated/CreditChoiceGroupGroup.h index 86ef5b08b..d893ad34c 100644 --- a/src/private/mx/core/generated/CreditChoiceGroupGroup.h +++ b/src/private/mx/core/generated/CreditChoiceGroupGroup.h @@ -45,8 +45,6 @@ class CreditChoiceGroupGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -CreditChoiceGroupGroup parseCreditChoiceGroupGroup(pugi::xml_node el, pugi::xml_node &cursor); - CreditChoiceGroupGroup parseCreditChoiceGroupGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); diff --git a/src/private/mx/core/generated/CreditChoiceGroupGroupChoice.cpp b/src/private/mx/core/generated/CreditChoiceGroupGroupChoice.cpp index b305b6f84..efc53cff6 100644 --- a/src/private/mx/core/generated/CreditChoiceGroupGroupChoice.cpp +++ b/src/private/mx/core/generated/CreditChoiceGroupGroupChoice.cpp @@ -26,11 +26,6 @@ CreditChoiceGroupGroupChoice CreditChoiceGroupGroupChoice::creditSymbol(Formatte return CreditChoiceGroupGroupChoice{Storage{std::in_place_index<1>, std::move(value)}}; } -CreditChoiceGroupGroupChoice parseCreditChoiceGroupGroupChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseCreditChoiceGroupGroupChoice(el, cursor, ParseContext{}); -} - CreditChoiceGroupGroupChoice parseCreditChoiceGroupGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { diff --git a/src/private/mx/core/generated/CreditChoiceGroupGroupChoice.h b/src/private/mx/core/generated/CreditChoiceGroupGroupChoice.h index bd4a520c9..45a88d74f 100644 --- a/src/private/mx/core/generated/CreditChoiceGroupGroupChoice.h +++ b/src/private/mx/core/generated/CreditChoiceGroupGroupChoice.h @@ -82,8 +82,6 @@ class CreditChoiceGroupGroupChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -CreditChoiceGroupGroupChoice parseCreditChoiceGroupGroupChoice(pugi::xml_node el, pugi::xml_node &cursor); - CreditChoiceGroupGroupChoice parseCreditChoiceGroupGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); diff --git a/src/private/mx/core/generated/CueNoteGroup.cpp b/src/private/mx/core/generated/CueNoteGroup.cpp index fd197f65d..011c0f988 100644 --- a/src/private/mx/core/generated/CueNoteGroup.cpp +++ b/src/private/mx/core/generated/CueNoteGroup.cpp @@ -41,11 +41,6 @@ void CueNoteGroup::setDuration(PositiveDivisions value) m_duration = std::move(value); } -CueNoteGroup parseCueNoteGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseCueNoteGroup(el, cursor, ParseContext{}); -} - CueNoteGroup parseCueNoteGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { CueNoteGroup out; diff --git a/src/private/mx/core/generated/CueNoteGroup.h b/src/private/mx/core/generated/CueNoteGroup.h index 6b2cec8f1..b33c68703 100644 --- a/src/private/mx/core/generated/CueNoteGroup.h +++ b/src/private/mx/core/generated/CueNoteGroup.h @@ -43,8 +43,6 @@ class CueNoteGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -CueNoteGroup parseCueNoteGroup(pugi::xml_node el, pugi::xml_node &cursor); - CueNoteGroup parseCueNoteGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeCueNoteGroup(const CueNoteGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Dashes.cpp b/src/private/mx/core/generated/Dashes.cpp index dcff47d2f..9bd3566ac 100644 --- a/src/private/mx/core/generated/Dashes.cpp +++ b/src/private/mx/core/generated/Dashes.cpp @@ -111,11 +111,6 @@ void Dashes::setID(std::optional value) m_id = std::move(value); } -Dashes parseDashes(pugi::xml_node el) -{ - return parseDashes(el, ParseContext{}); -} - Dashes parseDashes(pugi::xml_node el, const ParseContext &context) { Dashes out; @@ -181,11 +176,6 @@ Dashes parseDashes(pugi::xml_node el, const ParseContext &context) return out; } -void parseDashesContent(Dashes &out, pugi::xml_node el) -{ - parseDashesContent(out, el, ParseContext{}); -} - void parseDashesContent(Dashes &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/Dashes.h b/src/private/mx/core/generated/Dashes.h index 436ec70c0..60ac3806b 100644 --- a/src/private/mx/core/generated/Dashes.h +++ b/src/private/mx/core/generated/Dashes.h @@ -61,12 +61,8 @@ class Dashes final std::optional m_id; }; -Dashes parseDashes(pugi::xml_node el); - Dashes parseDashes(pugi::xml_node el, const ParseContext &context); -void parseDashesContent(Dashes &out, pugi::xml_node el); - void parseDashesContent(Dashes &out, pugi::xml_node el, const ParseContext &context); void serializeDashes(const Dashes &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Defaults.cpp b/src/private/mx/core/generated/Defaults.cpp index 6d22a1246..2ae847a40 100644 --- a/src/private/mx/core/generated/Defaults.cpp +++ b/src/private/mx/core/generated/Defaults.cpp @@ -101,11 +101,6 @@ void Defaults::setLyricLanguage(std::vector value) m_lyricLanguage = std::move(value); } -Defaults parseDefaults(pugi::xml_node el) -{ - return parseDefaults(el, ParseContext{}); -} - Defaults parseDefaults(pugi::xml_node el, const ParseContext &context) { Defaults out; @@ -122,11 +117,6 @@ Defaults parseDefaults(pugi::xml_node el, const ParseContext &context) return out; } -void parseDefaultsContent(Defaults &out, pugi::xml_node el) -{ - parseDefaultsContent(out, el, ParseContext{}); -} - void parseDefaultsContent(Defaults &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Defaults.h b/src/private/mx/core/generated/Defaults.h index c12a51007..73163939b 100644 --- a/src/private/mx/core/generated/Defaults.h +++ b/src/private/mx/core/generated/Defaults.h @@ -65,12 +65,8 @@ class Defaults final std::vector m_lyricLanguage; }; -Defaults parseDefaults(pugi::xml_node el); - Defaults parseDefaults(pugi::xml_node el, const ParseContext &context); -void parseDefaultsContent(Defaults &out, pugi::xml_node el); - void parseDefaultsContent(Defaults &out, pugi::xml_node el, const ParseContext &context); void serializeDefaults(const Defaults &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/DefaultsProbe.cpp b/src/private/mx/core/generated/DefaultsProbe.cpp index 754659b3b..9f4b71aad 100644 --- a/src/private/mx/core/generated/DefaultsProbe.cpp +++ b/src/private/mx/core/generated/DefaultsProbe.cpp @@ -2,6 +2,7 @@ #include "mx/core/generated/DefaultsProbe.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include "mx/core/generated/Accidental.h" #include "mx/core/generated/AccidentalMark.h" @@ -319,1142 +320,1142 @@ void roundTripDefaults() { pugi::xml_document doc; serializeAccidental(Accidental{}, doc, "probe"); - parseAccidental(doc.document_element()); + parseAccidental(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeAccidentalMark(AccidentalMark{}, doc, "probe"); - parseAccidentalMark(doc.document_element()); + parseAccidentalMark(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeAccidentalText(AccidentalText{}, doc, "probe"); - parseAccidentalText(doc.document_element()); + parseAccidentalText(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeAccord(Accord{}, doc, "probe"); - parseAccord(doc.document_element()); + parseAccord(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeEmpty(Empty{}, doc, "probe"); - parseEmpty(doc.document_element()); + parseEmpty(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeAccordionRegistration(AccordionRegistration{}, doc, "probe"); - parseAccordionRegistration(doc.document_element()); + parseAccordionRegistration(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeDistance(Distance{}, doc, "probe"); - parseDistance(doc.document_element()); + parseDistance(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeGlyph(Glyph{}, doc, "probe"); - parseGlyph(doc.document_element()); + parseGlyph(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeLineWidth(LineWidth{}, doc, "probe"); - parseLineWidth(doc.document_element()); + parseLineWidth(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeNoteSize(NoteSize{}, doc, "probe"); - parseNoteSize(doc.document_element()); + parseNoteSize(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeOtherAppearance(OtherAppearance{}, doc, "probe"); - parseOtherAppearance(doc.document_element()); + parseOtherAppearance(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeAppearance(Appearance{}, doc, "probe"); - parseAppearance(doc.document_element()); + parseAppearance(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeArpeggiate(Arpeggiate{}, doc, "probe"); - parseArpeggiate(doc.document_element()); + parseArpeggiate(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeArrow(Arrow{}, doc, "probe"); - parseArrow(doc.document_element()); + parseArrow(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeBreathMark(BreathMark{}, doc, "probe"); - parseBreathMark(doc.document_element()); + parseBreathMark(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeCaesura(Caesura{}, doc, "probe"); - parseCaesura(doc.document_element()); + parseCaesura(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeEmptyLine(EmptyLine{}, doc, "probe"); - parseEmptyLine(doc.document_element()); + parseEmptyLine(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeEmptyPlacement(EmptyPlacement{}, doc, "probe"); - parseEmptyPlacement(doc.document_element()); + parseEmptyPlacement(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeOtherPlacementText(OtherPlacementText{}, doc, "probe"); - parseOtherPlacementText(doc.document_element()); + parseOtherPlacementText(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeStrongAccent(StrongAccent{}, doc, "probe"); - parseStrongAccent(doc.document_element()); + parseStrongAccent(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeArticulations(Articulations{}, doc, "probe"); - parseArticulations(doc.document_element()); + parseArticulations(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeAssess(Assess{}, doc, "probe"); - parseAssess(doc.document_element()); + parseAssess(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeClef(Clef{}, doc, "probe"); - parseClef(doc.document_element()); + parseClef(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeDirective(Directive{}, doc, "probe"); - parseDirective(doc.document_element()); + parseDirective(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializePartClef(PartClef{}, doc, "probe"); - parsePartClef(doc.document_element()); + parsePartClef(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeDouble(Double{}, doc, "probe"); - parseDouble(doc.document_element()); + parseDouble(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializePartTranspose(PartTranspose{}, doc, "probe"); - parsePartTranspose(doc.document_element()); + parsePartTranspose(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeForPart(ForPart{}, doc, "probe"); - parseForPart(doc.document_element()); + parseForPart(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeFormattedText(FormattedText{}, doc, "probe"); - parseFormattedText(doc.document_element()); + parseFormattedText(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeCancel(Cancel{}, doc, "probe"); - parseCancel(doc.document_element()); + parseCancel(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeKeyAccidental(KeyAccidental{}, doc, "probe"); - parseKeyAccidental(doc.document_element()); + parseKeyAccidental(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeKeyOctave(KeyOctave{}, doc, "probe"); - parseKeyOctave(doc.document_element()); + parseKeyOctave(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeKey(Key{}, doc, "probe"); - parseKey(doc.document_element()); + parseKey(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeLevel(Level{}, doc, "probe"); - parseLevel(doc.document_element()); + parseLevel(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeBeatRepeat(BeatRepeat{}, doc, "probe"); - parseBeatRepeat(doc.document_element()); + parseBeatRepeat(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeMeasureRepeat(MeasureRepeat{}, doc, "probe"); - parseMeasureRepeat(doc.document_element()); + parseMeasureRepeat(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeMultipleRest(MultipleRest{}, doc, "probe"); - parseMultipleRest(doc.document_element()); + parseMultipleRest(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeSlash(Slash{}, doc, "probe"); - parseSlash(doc.document_element()); + parseSlash(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeMeasureStyle(MeasureStyle{}, doc, "probe"); - parseMeasureStyle(doc.document_element()); + parseMeasureStyle(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializePartSymbol(PartSymbol{}, doc, "probe"); - parsePartSymbol(doc.document_element()); + parsePartSymbol(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeLineDetail(LineDetail{}, doc, "probe"); - parseLineDetail(doc.document_element()); + parseLineDetail(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeStaffSize(StaffSize{}, doc, "probe"); - parseStaffSize(doc.document_element()); + parseStaffSize(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeStaffTuning(StaffTuning{}, doc, "probe"); - parseStaffTuning(doc.document_element()); + parseStaffTuning(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeStaffDetails(StaffDetails{}, doc, "probe"); - parseStaffDetails(doc.document_element()); + parseStaffDetails(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeInterchangeable(Interchangeable{}, doc, "probe"); - parseInterchangeable(doc.document_element()); + parseInterchangeable(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeTime(Time{}, doc, "probe"); - parseTime(doc.document_element()); + parseTime(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeTranspose(Transpose{}, doc, "probe"); - parseTranspose(doc.document_element()); + parseTranspose(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeAttributes(Attributes{}, doc, "probe"); - parseAttributes(doc.document_element()); + parseAttributes(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeBackup(Backup{}, doc, "probe"); - parseBackup(doc.document_element()); + parseBackup(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeBarStyleColor(BarStyleColor{}, doc, "probe"); - parseBarStyleColor(doc.document_element()); + parseBarStyleColor(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeCoda(Coda{}, doc, "probe"); - parseCoda(doc.document_element()); + parseCoda(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeEnding(Ending{}, doc, "probe"); - parseEnding(doc.document_element()); + parseEnding(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeFermata(Fermata{}, doc, "probe"); - parseFermata(doc.document_element()); + parseFermata(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeRepeat(Repeat{}, doc, "probe"); - parseRepeat(doc.document_element()); + parseRepeat(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeSegno(Segno{}, doc, "probe"); - parseSegno(doc.document_element()); + parseSegno(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeWavyLine(WavyLine{}, doc, "probe"); - parseWavyLine(doc.document_element()); + parseWavyLine(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeBarline(Barline{}, doc, "probe"); - parseBarline(doc.document_element()); + parseBarline(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeBarre(Barre{}, doc, "probe"); - parseBarre(doc.document_element()); + parseBarre(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeBassStep(BassStep{}, doc, "probe"); - parseBassStep(doc.document_element()); + parseBassStep(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeHarmonyAlter(HarmonyAlter{}, doc, "probe"); - parseHarmonyAlter(doc.document_element()); + parseHarmonyAlter(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeStyleText(StyleText{}, doc, "probe"); - parseStyleText(doc.document_element()); + parseStyleText(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeBass(Bass{}, doc, "probe"); - parseBass(doc.document_element()); + parseBass(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeBeam(Beam{}, doc, "probe"); - parseBeam(doc.document_element()); + parseBeam(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeBeatUnitTied(BeatUnitTied{}, doc, "probe"); - parseBeatUnitTied(doc.document_element()); + parseBeatUnitTied(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeBeater(Beater{}, doc, "probe"); - parseBeater(doc.document_element()); + parseBeater(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializePlacementText(PlacementText{}, doc, "probe"); - parsePlacementText(doc.document_element()); + parsePlacementText(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeRelease(Release{}, doc, "probe"); - parseRelease(doc.document_element()); + parseRelease(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeBend(Bend{}, doc, "probe"); - parseBend(doc.document_element()); + parseBend(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeBookmark(Bookmark{}, doc, "probe"); - parseBookmark(doc.document_element()); + parseBookmark(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeBracket(Bracket{}, doc, "probe"); - parseBracket(doc.document_element()); + parseBracket(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeFormattedSymbolID(FormattedSymbolID{}, doc, "probe"); - parseFormattedSymbolID(doc.document_element()); + parseFormattedSymbolID(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeFormattedTextID(FormattedTextID{}, doc, "probe"); - parseFormattedTextID(doc.document_element()); + parseFormattedTextID(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeImage(Image{}, doc, "probe"); - parseImage(doc.document_element()); + parseImage(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeLink(Link{}, doc, "probe"); - parseLink(doc.document_element()); + parseLink(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeCredit(Credit{}, doc, "probe"); - parseCredit(doc.document_element()); + parseCredit(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeDashes(Dashes{}, doc, "probe"); - parseDashes(doc.document_element()); + parseDashes(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeEmptyFont(EmptyFont{}, doc, "probe"); - parseEmptyFont(doc.document_element()); + parseEmptyFont(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeLyricFont(LyricFont{}, doc, "probe"); - parseLyricFont(doc.document_element()); + parseLyricFont(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeLyricLanguage(LyricLanguage{}, doc, "probe"); - parseLyricLanguage(doc.document_element()); + parseLyricLanguage(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializePageMargins(PageMargins{}, doc, "probe"); - parsePageMargins(doc.document_element()); + parsePageMargins(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializePageLayout(PageLayout{}, doc, "probe"); - parsePageLayout(doc.document_element()); + parsePageLayout(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeScaling(Scaling{}, doc, "probe"); - parseScaling(doc.document_element()); + parseScaling(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeStaffLayout(StaffLayout{}, doc, "probe"); - parseStaffLayout(doc.document_element()); + parseStaffLayout(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeEmptyPrintObjectStyleAlign(EmptyPrintObjectStyleAlign{}, doc, "probe"); - parseEmptyPrintObjectStyleAlign(doc.document_element()); + parseEmptyPrintObjectStyleAlign(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeSystemDividers(SystemDividers{}, doc, "probe"); - parseSystemDividers(doc.document_element()); + parseSystemDividers(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeSystemMargins(SystemMargins{}, doc, "probe"); - parseSystemMargins(doc.document_element()); + parseSystemMargins(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeSystemLayout(SystemLayout{}, doc, "probe"); - parseSystemLayout(doc.document_element()); + parseSystemLayout(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeDefaults(Defaults{}, doc, "probe"); - parseDefaults(doc.document_element()); + parseDefaults(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeDegreeAlter(DegreeAlter{}, doc, "probe"); - parseDegreeAlter(doc.document_element()); + parseDegreeAlter(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeDegreeType(DegreeType{}, doc, "probe"); - parseDegreeType(doc.document_element()); + parseDegreeType(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeDegreeValue(DegreeValue{}, doc, "probe"); - parseDegreeValue(doc.document_element()); + parseDegreeValue(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeDegree(Degree{}, doc, "probe"); - parseDegree(doc.document_element()); + parseDegree(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeOtherText(OtherText{}, doc, "probe"); - parseOtherText(doc.document_element()); + parseOtherText(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeDynamics(Dynamics{}, doc, "probe"); - parseDynamics(doc.document_element()); + parseDynamics(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeEmptyPrintStyleAlignID(EmptyPrintStyleAlignID{}, doc, "probe"); - parseEmptyPrintStyleAlignID(doc.document_element()); + parseEmptyPrintStyleAlignID(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializePedalTuning(PedalTuning{}, doc, "probe"); - parsePedalTuning(doc.document_element()); + parsePedalTuning(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeHarpPedals(HarpPedals{}, doc, "probe"); - parseHarpPedals(doc.document_element()); + parseHarpPedals(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeMetronomeBeam(MetronomeBeam{}, doc, "probe"); - parseMetronomeBeam(doc.document_element()); + parseMetronomeBeam(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeMetronomeTied(MetronomeTied{}, doc, "probe"); - parseMetronomeTied(doc.document_element()); + parseMetronomeTied(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeTimeModification(TimeModification{}, doc, "probe"); - parseTimeModification(doc.document_element()); + parseTimeModification(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeMetronomeTuplet(MetronomeTuplet{}, doc, "probe"); - parseMetronomeTuplet(doc.document_element()); + parseMetronomeTuplet(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeMetronomeNote(MetronomeNote{}, doc, "probe"); - parseMetronomeNote(doc.document_element()); + parseMetronomeNote(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializePerMinute(PerMinute{}, doc, "probe"); - parsePerMinute(doc.document_element()); + parsePerMinute(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeMetronome(Metronome{}, doc, "probe"); - parseMetronome(doc.document_element()); + parseMetronome(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeOctaveShift(OctaveShift{}, doc, "probe"); - parseOctaveShift(doc.document_element()); + parseOctaveShift(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeOtherDirection(OtherDirection{}, doc, "probe"); - parseOtherDirection(doc.document_element()); + parseOtherDirection(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializePedal(Pedal{}, doc, "probe"); - parsePedal(doc.document_element()); + parsePedal(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeEffect(Effect{}, doc, "probe"); - parseEffect(doc.document_element()); + parseEffect(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeGlass(Glass{}, doc, "probe"); - parseGlass(doc.document_element()); + parseGlass(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeMembrane(Membrane{}, doc, "probe"); - parseMembrane(doc.document_element()); + parseMembrane(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeMetal(Metal{}, doc, "probe"); - parseMetal(doc.document_element()); + parseMetal(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializePitched(Pitched{}, doc, "probe"); - parsePitched(doc.document_element()); + parsePitched(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeStick(Stick{}, doc, "probe"); - parseStick(doc.document_element()); + parseStick(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeTimpani(Timpani{}, doc, "probe"); - parseTimpani(doc.document_element()); + parseTimpani(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeWood(Wood{}, doc, "probe"); - parseWood(doc.document_element()); + parseWood(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializePercussion(Percussion{}, doc, "probe"); - parsePercussion(doc.document_element()); + parsePercussion(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializePrincipalVoice(PrincipalVoice{}, doc, "probe"); - parsePrincipalVoice(doc.document_element()); + parsePrincipalVoice(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeScordatura(Scordatura{}, doc, "probe"); - parseScordatura(doc.document_element()); + parseScordatura(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeStaffDivide(StaffDivide{}, doc, "probe"); - parseStaffDivide(doc.document_element()); + parseStaffDivide(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeStringMute(StringMute{}, doc, "probe"); - parseStringMute(doc.document_element()); + parseStringMute(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeWedge(Wedge{}, doc, "probe"); - parseWedge(doc.document_element()); + parseWedge(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeDirectionType(DirectionType{}, doc, "probe"); - parseDirectionType(doc.document_element()); + parseDirectionType(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeOffset(Offset{}, doc, "probe"); - parseOffset(doc.document_element()); + parseOffset(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeOtherListening(OtherListening{}, doc, "probe"); - parseOtherListening(doc.document_element()); + parseOtherListening(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeSync(Sync{}, doc, "probe"); - parseSync(doc.document_element()); + parseSync(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeListening(Listening{}, doc, "probe"); - parseListening(doc.document_element()); + parseListening(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeVirtualInstrument(VirtualInstrument{}, doc, "probe"); - parseVirtualInstrument(doc.document_element()); + parseVirtualInstrument(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeInstrumentChange(InstrumentChange{}, doc, "probe"); - parseInstrumentChange(doc.document_element()); + parseInstrumentChange(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeMIDIDevice(MIDIDevice{}, doc, "probe"); - parseMIDIDevice(doc.document_element()); + parseMIDIDevice(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeMIDIInstrument(MIDIInstrument{}, doc, "probe"); - parseMIDIInstrument(doc.document_element()); + parseMIDIInstrument(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeOtherPlay(OtherPlay{}, doc, "probe"); - parseOtherPlay(doc.document_element()); + parseOtherPlay(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializePlay(Play{}, doc, "probe"); - parsePlay(doc.document_element()); + parsePlay(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeSwing(Swing{}, doc, "probe"); - parseSwing(doc.document_element()); + parseSwing(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeSound(Sound{}, doc, "probe"); - parseSound(doc.document_element()); + parseSound(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeDirection(Direction{}, doc, "probe"); - parseDirection(doc.document_element()); + parseDirection(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeElision(Elision{}, doc, "probe"); - parseElision(doc.document_element()); + parseElision(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeEmptyPlacementSmufl(EmptyPlacementSmufl{}, doc, "probe"); - parseEmptyPlacementSmufl(doc.document_element()); + parseEmptyPlacementSmufl(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeEmptyTrillSound(EmptyTrillSound{}, doc, "probe"); - parseEmptyTrillSound(doc.document_element()); + parseEmptyTrillSound(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeSupports(Supports{}, doc, "probe"); - parseSupports(doc.document_element()); + parseSupports(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeTypedText(TypedText{}, doc, "probe"); - parseTypedText(doc.document_element()); + parseTypedText(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeEncoding(Encoding{}, doc, "probe"); - parseEncoding(doc.document_element()); + parseEncoding(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeExtend(Extend{}, doc, "probe"); - parseExtend(doc.document_element()); + parseExtend(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeFeature(Feature{}, doc, "probe"); - parseFeature(doc.document_element()); + parseFeature(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeFigure(Figure{}, doc, "probe"); - parseFigure(doc.document_element()); + parseFigure(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeFiguredBass(FiguredBass{}, doc, "probe"); - parseFiguredBass(doc.document_element()); + parseFiguredBass(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeFingering(Fingering{}, doc, "probe"); - parseFingering(doc.document_element()); + parseFingering(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeFirstFret(FirstFret{}, doc, "probe"); - parseFirstFret(doc.document_element()); + parseFirstFret(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeForward(Forward{}, doc, "probe"); - parseForward(doc.document_element()); + parseForward(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeFret(Fret{}, doc, "probe"); - parseFret(doc.document_element()); + parseFret(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeString(String{}, doc, "probe"); - parseString(doc.document_element()); + parseString(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeFrameNote(FrameNote{}, doc, "probe"); - parseFrameNote(doc.document_element()); + parseFrameNote(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeFrame(Frame{}, doc, "probe"); - parseFrame(doc.document_element()); + parseFrame(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeGlissando(Glissando{}, doc, "probe"); - parseGlissando(doc.document_element()); + parseGlissando(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeGrace(Grace{}, doc, "probe"); - parseGrace(doc.document_element()); + parseGrace(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeGroupBarline(GroupBarline{}, doc, "probe"); - parseGroupBarline(doc.document_element()); + parseGroupBarline(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeGroupName(GroupName{}, doc, "probe"); - parseGroupName(doc.document_element()); + parseGroupName(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeGroupSymbol(GroupSymbol{}, doc, "probe"); - parseGroupSymbol(doc.document_element()); + parseGroupSymbol(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeGrouping(Grouping{}, doc, "probe"); - parseGrouping(doc.document_element()); + parseGrouping(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeHammerOnPullOff(HammerOnPullOff{}, doc, "probe"); - parseHammerOnPullOff(doc.document_element()); + parseHammerOnPullOff(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeHandbell(Handbell{}, doc, "probe"); - parseHandbell(doc.document_element()); + parseHandbell(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeHarmonClosed(HarmonClosed{}, doc, "probe"); - parseHarmonClosed(doc.document_element()); + parseHarmonClosed(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeHarmonMute(HarmonMute{}, doc, "probe"); - parseHarmonMute(doc.document_element()); + parseHarmonMute(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeHarmonic(Harmonic{}, doc, "probe"); - parseHarmonic(doc.document_element()); + parseHarmonic(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeInversion(Inversion{}, doc, "probe"); - parseInversion(doc.document_element()); + parseInversion(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeKind(Kind{}, doc, "probe"); - parseKind(doc.document_element()); + parseKind(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeNumeralKey(NumeralKey{}, doc, "probe"); - parseNumeralKey(doc.document_element()); + parseNumeralKey(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeNumeralRoot(NumeralRoot{}, doc, "probe"); - parseNumeralRoot(doc.document_element()); + parseNumeralRoot(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeNumeral(Numeral{}, doc, "probe"); - parseNumeral(doc.document_element()); + parseNumeral(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeRootStep(RootStep{}, doc, "probe"); - parseRootStep(doc.document_element()); + parseRootStep(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeRoot(Root{}, doc, "probe"); - parseRoot(doc.document_element()); + parseRoot(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeHarmony(Harmony{}, doc, "probe"); - parseHarmony(doc.document_element()); + parseHarmony(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeHeelToe(HeelToe{}, doc, "probe"); - parseHeelToe(doc.document_element()); + parseHeelToe(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeHoleClosed(HoleClosed{}, doc, "probe"); - parseHoleClosed(doc.document_element()); + parseHoleClosed(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeHole(Hole{}, doc, "probe"); - parseHole(doc.document_element()); + parseHole(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeHorizontalTurn(HorizontalTurn{}, doc, "probe"); - parseHorizontalTurn(doc.document_element()); + parseHorizontalTurn(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeMiscellaneousField(MiscellaneousField{}, doc, "probe"); - parseMiscellaneousField(doc.document_element()); + parseMiscellaneousField(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeMiscellaneous(Miscellaneous{}, doc, "probe"); - parseMiscellaneous(doc.document_element()); + parseMiscellaneous(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeIdentification(Identification{}, doc, "probe"); - parseIdentification(doc.document_element()); + parseIdentification(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeInstrument(Instrument{}, doc, "probe"); - parseInstrument(doc.document_element()); + parseInstrument(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeInstrumentLink(InstrumentLink{}, doc, "probe"); - parseInstrumentLink(doc.document_element()); + parseInstrumentLink(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeWait(Wait{}, doc, "probe"); - parseWait(doc.document_element()); + parseWait(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeListen(Listen{}, doc, "probe"); - parseListen(doc.document_element()); + parseListen(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeTextElementData(TextElementData{}, doc, "probe"); - parseTextElementData(doc.document_element()); + parseTextElementData(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeLyric(Lyric{}, doc, "probe"); - parseLyric(doc.document_element()); + parseLyric(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeMeasureLayout(MeasureLayout{}, doc, "probe"); - parseMeasureLayout(doc.document_element()); + parseMeasureLayout(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeMeasureNumbering(MeasureNumbering{}, doc, "probe"); - parseMeasureNumbering(doc.document_element()); + parseMeasureNumbering(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeMordent(Mordent{}, doc, "probe"); - parseMordent(doc.document_element()); + parseMordent(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeNameDisplay(NameDisplay{}, doc, "probe"); - parseNameDisplay(doc.document_element()); + parseNameDisplay(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeNonArpeggiate(NonArpeggiate{}, doc, "probe"); - parseNonArpeggiate(doc.document_element()); + parseNonArpeggiate(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeTremolo(Tremolo{}, doc, "probe"); - parseTremolo(doc.document_element()); + parseTremolo(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeOrnaments(Ornaments{}, doc, "probe"); - parseOrnaments(doc.document_element()); + parseOrnaments(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeOtherNotation(OtherNotation{}, doc, "probe"); - parseOtherNotation(doc.document_element()); + parseOtherNotation(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeSlide(Slide{}, doc, "probe"); - parseSlide(doc.document_element()); + parseSlide(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeSlur(Slur{}, doc, "probe"); - parseSlur(doc.document_element()); + parseSlur(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeTap(Tap{}, doc, "probe"); - parseTap(doc.document_element()); + parseTap(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeTechnical(Technical{}, doc, "probe"); - parseTechnical(doc.document_element()); + parseTechnical(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeTied(Tied{}, doc, "probe"); - parseTied(doc.document_element()); + parseTied(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeTupletDot(TupletDot{}, doc, "probe"); - parseTupletDot(doc.document_element()); + parseTupletDot(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeTupletNumber(TupletNumber{}, doc, "probe"); - parseTupletNumber(doc.document_element()); + parseTupletNumber(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeTupletType(TupletType{}, doc, "probe"); - parseTupletType(doc.document_element()); + parseTupletType(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeTupletPortion(TupletPortion{}, doc, "probe"); - parseTupletPortion(doc.document_element()); + parseTupletPortion(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeTuplet(Tuplet{}, doc, "probe"); - parseTuplet(doc.document_element()); + parseTuplet(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeNotations(Notations{}, doc, "probe"); - parseNotations(doc.document_element()); + parseNotations(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeNoteType(NoteType{}, doc, "probe"); - parseNoteType(doc.document_element()); + parseNoteType(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeNotehead(Notehead{}, doc, "probe"); - parseNotehead(doc.document_element()); + parseNotehead(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeNoteheadText(NoteheadText{}, doc, "probe"); - parseNoteheadText(doc.document_element()); + parseNoteheadText(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializePitch(Pitch{}, doc, "probe"); - parsePitch(doc.document_element()); + parsePitch(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeRest(Rest{}, doc, "probe"); - parseRest(doc.document_element()); + parseRest(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeStem(Stem{}, doc, "probe"); - parseStem(doc.document_element()); + parseStem(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeTie(Tie{}, doc, "probe"); - parseTie(doc.document_element()); + parseTie(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeUnpitched(Unpitched{}, doc, "probe"); - parseUnpitched(doc.document_element()); + parseUnpitched(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeNote(Note{}, doc, "probe"); - parseNote(doc.document_element()); + parseNote(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeOpus(Opus{}, doc, "probe"); - parseOpus(doc.document_element()); + parseOpus(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializePartGroup(PartGroup{}, doc, "probe"); - parsePartGroup(doc.document_element()); + parsePartGroup(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializePartLink(PartLink{}, doc, "probe"); - parsePartLink(doc.document_element()); + parsePartLink(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializePartName(PartName{}, doc, "probe"); - parsePartName(doc.document_element()); + parsePartName(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializePlayer(Player{}, doc, "probe"); - parsePlayer(doc.document_element()); + parsePlayer(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeScoreInstrument(ScoreInstrument{}, doc, "probe"); - parseScoreInstrument(doc.document_element()); + parseScoreInstrument(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeScorePart(ScorePart{}, doc, "probe"); - parseScorePart(doc.document_element()); + parseScorePart(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializePartList(PartList{}, doc, "probe"); - parsePartList(doc.document_element()); + parsePartList(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializePrint(Print{}, doc, "probe"); - parsePrint(doc.document_element()); + parsePrint(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializePartwiseMeasure(PartwiseMeasure{}, doc, "probe"); - parsePartwiseMeasure(doc.document_element()); + parsePartwiseMeasure(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializePartwisePart(PartwisePart{}, doc, "probe"); - parsePartwisePart(doc.document_element()); + parsePartwisePart(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeWork(Work{}, doc, "probe"); - parseWork(doc.document_element()); + parseWork(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeScorePartwise(ScorePartwise{}, doc, "probe"); - parseScorePartwise(doc.document_element()); + parseScorePartwise(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeTimewisePart(TimewisePart{}, doc, "probe"); - parseTimewisePart(doc.document_element()); + parseTimewisePart(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeTimewiseMeasure(TimewiseMeasure{}, doc, "probe"); - parseTimewiseMeasure(doc.document_element()); + parseTimewiseMeasure(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; serializeScoreTimewise(ScoreTimewise{}, doc, "probe"); - parseScoreTimewise(doc.document_element()); + parseScoreTimewise(doc.document_element(), ParseContext{}); } { pugi::xml_document doc; @@ -1462,7 +1463,7 @@ void roundTripDefaults() serializeTuningGroup(TuningGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseTuningGroup(el, cursor); + parseTuningGroup(el, cursor, ParseContext{}); } } { @@ -1471,7 +1472,7 @@ void roundTripDefaults() serializeClefGroup(ClefGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseClefGroup(el, cursor); + parseClefGroup(el, cursor, ParseContext{}); } } { @@ -1480,7 +1481,7 @@ void roundTripDefaults() serializeTransposeGroup(TransposeGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseTransposeGroup(el, cursor); + parseTransposeGroup(el, cursor, ParseContext{}); } } { @@ -1489,7 +1490,7 @@ void roundTripDefaults() serializeTraditionalKeyGroup(TraditionalKeyGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseTraditionalKeyGroup(el, cursor); + parseTraditionalKeyGroup(el, cursor, ParseContext{}); } } { @@ -1498,7 +1499,7 @@ void roundTripDefaults() serializeNonTraditionalKeyGroup(NonTraditionalKeyGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseNonTraditionalKeyGroup(el, cursor); + parseNonTraditionalKeyGroup(el, cursor, ParseContext{}); } } { @@ -1507,7 +1508,7 @@ void roundTripDefaults() serializeSlashGroup(SlashGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseSlashGroup(el, cursor); + parseSlashGroup(el, cursor, ParseContext{}); } } { @@ -1516,7 +1517,7 @@ void roundTripDefaults() serializeTimeSignatureGroup(TimeSignatureGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseTimeSignatureGroup(el, cursor); + parseTimeSignatureGroup(el, cursor, ParseContext{}); } } { @@ -1525,7 +1526,7 @@ void roundTripDefaults() serializeEditorialGroup(EditorialGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseEditorialGroup(el, cursor); + parseEditorialGroup(el, cursor, ParseContext{}); } } { @@ -1534,7 +1535,7 @@ void roundTripDefaults() serializeBeatUnitGroup(BeatUnitGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseBeatUnitGroup(el, cursor); + parseBeatUnitGroup(el, cursor, ParseContext{}); } } { @@ -1543,7 +1544,7 @@ void roundTripDefaults() serializeAllMarginsGroup(AllMarginsGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseAllMarginsGroup(el, cursor); + parseAllMarginsGroup(el, cursor, ParseContext{}); } } { @@ -1552,7 +1553,7 @@ void roundTripDefaults() serializeLeftRightMarginsGroup(LeftRightMarginsGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseLeftRightMarginsGroup(el, cursor); + parseLeftRightMarginsGroup(el, cursor, ParseContext{}); } } { @@ -1561,7 +1562,7 @@ void roundTripDefaults() serializeLayoutGroup(LayoutGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseLayoutGroup(el, cursor); + parseLayoutGroup(el, cursor, ParseContext{}); } } { @@ -1570,7 +1571,7 @@ void roundTripDefaults() serializeVirtualInstrumentDataGroup(VirtualInstrumentDataGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseVirtualInstrumentDataGroup(el, cursor); + parseVirtualInstrumentDataGroup(el, cursor, ParseContext{}); } } { @@ -1579,7 +1580,7 @@ void roundTripDefaults() serializeEditorialVoiceDirectionGroup(EditorialVoiceDirectionGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseEditorialVoiceDirectionGroup(el, cursor); + parseEditorialVoiceDirectionGroup(el, cursor, ParseContext{}); } } { @@ -1588,7 +1589,7 @@ void roundTripDefaults() serializeEditorialVoiceGroup(EditorialVoiceGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseEditorialVoiceGroup(el, cursor); + parseEditorialVoiceGroup(el, cursor, ParseContext{}); } } { @@ -1597,7 +1598,7 @@ void roundTripDefaults() serializeHarmonyChordGroup(HarmonyChordGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseHarmonyChordGroup(el, cursor); + parseHarmonyChordGroup(el, cursor, ParseContext{}); } } { @@ -1606,7 +1607,7 @@ void roundTripDefaults() serializeDisplayStepOctaveGroup(DisplayStepOctaveGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseDisplayStepOctaveGroup(el, cursor); + parseDisplayStepOctaveGroup(el, cursor, ParseContext{}); } } { @@ -1615,7 +1616,7 @@ void roundTripDefaults() serializeFullNoteGroup(FullNoteGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseFullNoteGroup(el, cursor); + parseFullNoteGroup(el, cursor, ParseContext{}); } } { @@ -1624,7 +1625,7 @@ void roundTripDefaults() serializeMusicDataChoice(MusicDataChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseMusicDataChoice(el, cursor); + parseMusicDataChoice(el, cursor, ParseContext{}); } } { @@ -1633,7 +1634,7 @@ void roundTripDefaults() serializeScoreHeaderGroup(ScoreHeaderGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseScoreHeaderGroup(el, cursor); + parseScoreHeaderGroup(el, cursor, ParseContext{}); } } { @@ -1642,7 +1643,7 @@ void roundTripDefaults() serializeArrowChoice(ArrowChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseArrowChoice(el, cursor); + parseArrowChoice(el, cursor, ParseContext{}); } } { @@ -1651,7 +1652,7 @@ void roundTripDefaults() serializeArrowChoiceGroup(ArrowChoiceGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseArrowChoiceGroup(el, cursor); + parseArrowChoiceGroup(el, cursor, ParseContext{}); } } { @@ -1660,7 +1661,7 @@ void roundTripDefaults() serializeArticulationsChoice(ArticulationsChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseArticulationsChoice(el, cursor); + parseArticulationsChoice(el, cursor, ParseContext{}); } } { @@ -1669,7 +1670,7 @@ void roundTripDefaults() serializeKeyChoice(KeyChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseKeyChoice(el, cursor); + parseKeyChoice(el, cursor, ParseContext{}); } } { @@ -1678,7 +1679,7 @@ void roundTripDefaults() serializeSlashGroupGroup(SlashGroupGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseSlashGroupGroup(el, cursor); + parseSlashGroupGroup(el, cursor, ParseContext{}); } } { @@ -1687,7 +1688,7 @@ void roundTripDefaults() serializeMeasureStyleChoice(MeasureStyleChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseMeasureStyleChoice(el, cursor); + parseMeasureStyleChoice(el, cursor, ParseContext{}); } } { @@ -1696,7 +1697,7 @@ void roundTripDefaults() serializeStaffDetailsGroup(StaffDetailsGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseStaffDetailsGroup(el, cursor); + parseStaffDetailsGroup(el, cursor, ParseContext{}); } } { @@ -1705,7 +1706,7 @@ void roundTripDefaults() serializeTimeChoice(TimeChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseTimeChoice(el, cursor); + parseTimeChoice(el, cursor, ParseContext{}); } } { @@ -1714,7 +1715,7 @@ void roundTripDefaults() serializeTimeChoiceGroup(TimeChoiceGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseTimeChoiceGroup(el, cursor); + parseTimeChoiceGroup(el, cursor, ParseContext{}); } } { @@ -1723,7 +1724,7 @@ void roundTripDefaults() serializeAttributesChoice(AttributesChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseAttributesChoice(el, cursor); + parseAttributesChoice(el, cursor, ParseContext{}); } } { @@ -1732,7 +1733,7 @@ void roundTripDefaults() serializeBendChoice(BendChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseBendChoice(el, cursor); + parseBendChoice(el, cursor, ParseContext{}); } } { @@ -1741,7 +1742,7 @@ void roundTripDefaults() serializeCreditChoice(CreditChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseCreditChoice(el, cursor); + parseCreditChoice(el, cursor, ParseContext{}); } } { @@ -1750,7 +1751,7 @@ void roundTripDefaults() serializeCreditChoiceGroup(CreditChoiceGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseCreditChoiceGroup(el, cursor); + parseCreditChoiceGroup(el, cursor, ParseContext{}); } } { @@ -1759,7 +1760,7 @@ void roundTripDefaults() serializeCreditChoiceGroupChoice(CreditChoiceGroupChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseCreditChoiceGroupChoice(el, cursor); + parseCreditChoiceGroupChoice(el, cursor, ParseContext{}); } } { @@ -1768,7 +1769,7 @@ void roundTripDefaults() serializeCreditChoiceGroupGroup(CreditChoiceGroupGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseCreditChoiceGroupGroup(el, cursor); + parseCreditChoiceGroupGroup(el, cursor, ParseContext{}); } } { @@ -1777,7 +1778,7 @@ void roundTripDefaults() serializeCreditChoiceGroupGroupChoice(CreditChoiceGroupGroupChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseCreditChoiceGroupGroupChoice(el, cursor); + parseCreditChoiceGroupGroupChoice(el, cursor, ParseContext{}); } } { @@ -1786,7 +1787,7 @@ void roundTripDefaults() serializePageLayoutGroup(PageLayoutGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parsePageLayoutGroup(el, cursor); + parsePageLayoutGroup(el, cursor, ParseContext{}); } } { @@ -1795,7 +1796,7 @@ void roundTripDefaults() serializeDynamicsChoice(DynamicsChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseDynamicsChoice(el, cursor); + parseDynamicsChoice(el, cursor, ParseContext{}); } } { @@ -1804,7 +1805,7 @@ void roundTripDefaults() serializeTimeModificationGroup(TimeModificationGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseTimeModificationGroup(el, cursor); + parseTimeModificationGroup(el, cursor, ParseContext{}); } } { @@ -1813,7 +1814,7 @@ void roundTripDefaults() serializeMetronomeChoice(MetronomeChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseMetronomeChoice(el, cursor); + parseMetronomeChoice(el, cursor, ParseContext{}); } } { @@ -1822,7 +1823,7 @@ void roundTripDefaults() serializeMetronomeChoiceGroup(MetronomeChoiceGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseMetronomeChoiceGroup(el, cursor); + parseMetronomeChoiceGroup(el, cursor, ParseContext{}); } } { @@ -1831,7 +1832,7 @@ void roundTripDefaults() serializeMetronomeChoiceGroupChoice(MetronomeChoiceGroupChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseMetronomeChoiceGroupChoice(el, cursor); + parseMetronomeChoiceGroupChoice(el, cursor, ParseContext{}); } } { @@ -1840,7 +1841,7 @@ void roundTripDefaults() serializeMetronomeChoiceGroupChoiceGroup(MetronomeChoiceGroupChoiceGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseMetronomeChoiceGroupChoiceGroup(el, cursor); + parseMetronomeChoiceGroupChoiceGroup(el, cursor, ParseContext{}); } } { @@ -1849,7 +1850,7 @@ void roundTripDefaults() serializeMetronomeChoiceGroup2(MetronomeChoiceGroup2{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseMetronomeChoiceGroup2(el, cursor); + parseMetronomeChoiceGroup2(el, cursor, ParseContext{}); } } { @@ -1858,7 +1859,7 @@ void roundTripDefaults() serializeMetronomeChoiceGroup2Group(MetronomeChoiceGroup2Group{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseMetronomeChoiceGroup2Group(el, cursor); + parseMetronomeChoiceGroup2Group(el, cursor, ParseContext{}); } } { @@ -1867,7 +1868,7 @@ void roundTripDefaults() serializePercussionChoice(PercussionChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parsePercussionChoice(el, cursor); + parsePercussionChoice(el, cursor, ParseContext{}); } } { @@ -1876,7 +1877,7 @@ void roundTripDefaults() serializeDirectionTypeChoice(DirectionTypeChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseDirectionTypeChoice(el, cursor); + parseDirectionTypeChoice(el, cursor, ParseContext{}); } } { @@ -1885,7 +1886,7 @@ void roundTripDefaults() serializeDirectionTypeChoiceChoice(DirectionTypeChoiceChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseDirectionTypeChoiceChoice(el, cursor); + parseDirectionTypeChoiceChoice(el, cursor, ParseContext{}); } } { @@ -1894,7 +1895,7 @@ void roundTripDefaults() serializeListeningChoice(ListeningChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseListeningChoice(el, cursor); + parseListeningChoice(el, cursor, ParseContext{}); } } { @@ -1903,7 +1904,7 @@ void roundTripDefaults() serializeVirtualInstrumentDataGroupChoice(VirtualInstrumentDataGroupChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseVirtualInstrumentDataGroupChoice(el, cursor); + parseVirtualInstrumentDataGroupChoice(el, cursor, ParseContext{}); } } { @@ -1912,7 +1913,7 @@ void roundTripDefaults() serializePlayChoice(PlayChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parsePlayChoice(el, cursor); + parsePlayChoice(el, cursor, ParseContext{}); } } { @@ -1921,7 +1922,7 @@ void roundTripDefaults() serializeSwingChoice(SwingChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseSwingChoice(el, cursor); + parseSwingChoice(el, cursor, ParseContext{}); } } { @@ -1930,7 +1931,7 @@ void roundTripDefaults() serializeSwingChoiceGroup(SwingChoiceGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseSwingChoiceGroup(el, cursor); + parseSwingChoiceGroup(el, cursor, ParseContext{}); } } { @@ -1939,7 +1940,7 @@ void roundTripDefaults() serializeSoundGroup(SoundGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseSoundGroup(el, cursor); + parseSoundGroup(el, cursor, ParseContext{}); } } { @@ -1948,7 +1949,7 @@ void roundTripDefaults() serializeEncodingChoice(EncodingChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseEncodingChoice(el, cursor); + parseEncodingChoice(el, cursor, ParseContext{}); } } { @@ -1957,7 +1958,7 @@ void roundTripDefaults() serializeHarmonicChoice(HarmonicChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseHarmonicChoice(el, cursor); + parseHarmonicChoice(el, cursor, ParseContext{}); } } { @@ -1966,7 +1967,7 @@ void roundTripDefaults() serializeHarmonicChoice2(HarmonicChoice2{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseHarmonicChoice2(el, cursor); + parseHarmonicChoice2(el, cursor, ParseContext{}); } } { @@ -1975,7 +1976,7 @@ void roundTripDefaults() serializeHarmonyChordGroupChoice(HarmonyChordGroupChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseHarmonyChordGroupChoice(el, cursor); + parseHarmonyChordGroupChoice(el, cursor, ParseContext{}); } } { @@ -1984,7 +1985,7 @@ void roundTripDefaults() serializeListenChoice(ListenChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseListenChoice(el, cursor); + parseListenChoice(el, cursor, ParseContext{}); } } { @@ -1993,7 +1994,7 @@ void roundTripDefaults() serializeLyricChoice(LyricChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseLyricChoice(el, cursor); + parseLyricChoice(el, cursor, ParseContext{}); } } { @@ -2002,7 +2003,7 @@ void roundTripDefaults() serializeLyricTextGroup(LyricTextGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseLyricTextGroup(el, cursor); + parseLyricTextGroup(el, cursor, ParseContext{}); } } { @@ -2011,7 +2012,7 @@ void roundTripDefaults() serializeLyricSyllableGroup(LyricSyllableGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseLyricSyllableGroup(el, cursor); + parseLyricSyllableGroup(el, cursor, ParseContext{}); } } { @@ -2020,7 +2021,7 @@ void roundTripDefaults() serializeElisionSyllabicGroup(ElisionSyllabicGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseElisionSyllabicGroup(el, cursor); + parseElisionSyllabicGroup(el, cursor, ParseContext{}); } } { @@ -2029,7 +2030,7 @@ void roundTripDefaults() serializeNameDisplayChoice(NameDisplayChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseNameDisplayChoice(el, cursor); + parseNameDisplayChoice(el, cursor, ParseContext{}); } } { @@ -2038,7 +2039,7 @@ void roundTripDefaults() serializeOrnamentsGroup(OrnamentsGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseOrnamentsGroup(el, cursor); + parseOrnamentsGroup(el, cursor, ParseContext{}); } } { @@ -2047,7 +2048,7 @@ void roundTripDefaults() serializeOrnamentsGroupChoice(OrnamentsGroupChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseOrnamentsGroupChoice(el, cursor); + parseOrnamentsGroupChoice(el, cursor, ParseContext{}); } } { @@ -2056,7 +2057,7 @@ void roundTripDefaults() serializeTechnicalChoice(TechnicalChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseTechnicalChoice(el, cursor); + parseTechnicalChoice(el, cursor, ParseContext{}); } } { @@ -2065,7 +2066,7 @@ void roundTripDefaults() serializeNotationsChoice(NotationsChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseNotationsChoice(el, cursor); + parseNotationsChoice(el, cursor, ParseContext{}); } } { @@ -2074,7 +2075,7 @@ void roundTripDefaults() serializeNoteheadTextChoice(NoteheadTextChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseNoteheadTextChoice(el, cursor); + parseNoteheadTextChoice(el, cursor, ParseContext{}); } } { @@ -2083,7 +2084,7 @@ void roundTripDefaults() serializeNoteChoice(NoteChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseNoteChoice(el, cursor); + parseNoteChoice(el, cursor, ParseContext{}); } } { @@ -2092,7 +2093,7 @@ void roundTripDefaults() serializeGraceNoteGroup(GraceNoteGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseGraceNoteGroup(el, cursor); + parseGraceNoteGroup(el, cursor, ParseContext{}); } } { @@ -2101,7 +2102,7 @@ void roundTripDefaults() serializeGraceNoteChoice(GraceNoteChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseGraceNoteChoice(el, cursor); + parseGraceNoteChoice(el, cursor, ParseContext{}); } } { @@ -2110,7 +2111,7 @@ void roundTripDefaults() serializeGraceNormalNoteGroup(GraceNormalNoteGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseGraceNormalNoteGroup(el, cursor); + parseGraceNormalNoteGroup(el, cursor, ParseContext{}); } } { @@ -2119,7 +2120,7 @@ void roundTripDefaults() serializeFullNoteGroupChoice(FullNoteGroupChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseFullNoteGroupChoice(el, cursor); + parseFullNoteGroupChoice(el, cursor, ParseContext{}); } } { @@ -2128,7 +2129,7 @@ void roundTripDefaults() serializeGraceCueNoteGroup(GraceCueNoteGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseGraceCueNoteGroup(el, cursor); + parseGraceCueNoteGroup(el, cursor, ParseContext{}); } } { @@ -2137,7 +2138,7 @@ void roundTripDefaults() serializeCueNoteGroup(CueNoteGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseCueNoteGroup(el, cursor); + parseCueNoteGroup(el, cursor, ParseContext{}); } } { @@ -2146,7 +2147,7 @@ void roundTripDefaults() serializeNormalNoteGroup(NormalNoteGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseNormalNoteGroup(el, cursor); + parseNormalNoteGroup(el, cursor, ParseContext{}); } } { @@ -2155,7 +2156,7 @@ void roundTripDefaults() serializeScorePartMIDIGroup(ScorePartMIDIGroup{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parseScorePartMIDIGroup(el, cursor); + parseScorePartMIDIGroup(el, cursor, ParseContext{}); } } { @@ -2164,7 +2165,7 @@ void roundTripDefaults() serializePartListChoice(PartListChoice{}, el); if (pugi::xml_node cursor = firstElement(el)) { - parsePartListChoice(el, cursor); + parsePartListChoice(el, cursor, ParseContext{}); } } } diff --git a/src/private/mx/core/generated/Degree.cpp b/src/private/mx/core/generated/Degree.cpp index cd31a10a7..6a8a98b5f 100644 --- a/src/private/mx/core/generated/Degree.cpp +++ b/src/private/mx/core/generated/Degree.cpp @@ -51,11 +51,6 @@ void Degree::setDegreeType(DegreeType value) m_degreeType = std::move(value); } -Degree parseDegree(pugi::xml_node el) -{ - return parseDegree(el, ParseContext{}); -} - Degree parseDegree(pugi::xml_node el, const ParseContext &context) { Degree out; @@ -79,11 +74,6 @@ Degree parseDegree(pugi::xml_node el, const ParseContext &context) return out; } -void parseDegreeContent(Degree &out, pugi::xml_node el) -{ - parseDegreeContent(out, el, ParseContext{}); -} - void parseDegreeContent(Degree &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Degree.h b/src/private/mx/core/generated/Degree.h index bffb8a108..24cbe756c 100644 --- a/src/private/mx/core/generated/Degree.h +++ b/src/private/mx/core/generated/Degree.h @@ -50,12 +50,8 @@ class Degree final DegreeType m_degreeType{}; }; -Degree parseDegree(pugi::xml_node el); - Degree parseDegree(pugi::xml_node el, const ParseContext &context); -void parseDegreeContent(Degree &out, pugi::xml_node el); - void parseDegreeContent(Degree &out, pugi::xml_node el, const ParseContext &context); void serializeDegree(const Degree &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/DegreeAlter.cpp b/src/private/mx/core/generated/DegreeAlter.cpp index 05e89fa4e..127557012 100644 --- a/src/private/mx/core/generated/DegreeAlter.cpp +++ b/src/private/mx/core/generated/DegreeAlter.cpp @@ -121,11 +121,6 @@ void DegreeAlter::setValue(Semitones value) m_value = std::move(value); } -DegreeAlter parseDegreeAlter(pugi::xml_node el) -{ - return parseDegreeAlter(el, ParseContext{}); -} - DegreeAlter parseDegreeAlter(pugi::xml_node el, const ParseContext &context) { DegreeAlter out; @@ -185,11 +180,6 @@ DegreeAlter parseDegreeAlter(pugi::xml_node el, const ParseContext &context) return out; } -void parseDegreeAlterContent(DegreeAlter &out, pugi::xml_node el) -{ - parseDegreeAlterContent(out, el, ParseContext{}); -} - void parseDegreeAlterContent(DegreeAlter &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/DegreeAlter.h b/src/private/mx/core/generated/DegreeAlter.h index 032aef0c9..e76d72640 100644 --- a/src/private/mx/core/generated/DegreeAlter.h +++ b/src/private/mx/core/generated/DegreeAlter.h @@ -71,12 +71,8 @@ class DegreeAlter final Semitones m_value{}; }; -DegreeAlter parseDegreeAlter(pugi::xml_node el); - DegreeAlter parseDegreeAlter(pugi::xml_node el, const ParseContext &context); -void parseDegreeAlterContent(DegreeAlter &out, pugi::xml_node el); - void parseDegreeAlterContent(DegreeAlter &out, pugi::xml_node el, const ParseContext &context); void serializeDegreeAlter(const DegreeAlter &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/DegreeType.cpp b/src/private/mx/core/generated/DegreeType.cpp index fa0ab7731..668de3da2 100644 --- a/src/private/mx/core/generated/DegreeType.cpp +++ b/src/private/mx/core/generated/DegreeType.cpp @@ -121,11 +121,6 @@ void DegreeType::setValue(DegreeTypeValue value) m_value = std::move(value); } -DegreeType parseDegreeType(pugi::xml_node el) -{ - return parseDegreeType(el, ParseContext{}); -} - DegreeType parseDegreeType(pugi::xml_node el, const ParseContext &context) { DegreeType out; @@ -185,11 +180,6 @@ DegreeType parseDegreeType(pugi::xml_node el, const ParseContext &context) return out; } -void parseDegreeTypeContent(DegreeType &out, pugi::xml_node el) -{ - parseDegreeTypeContent(out, el, ParseContext{}); -} - void parseDegreeTypeContent(DegreeType &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/DegreeType.h b/src/private/mx/core/generated/DegreeType.h index 2f540cf12..a130afb07 100644 --- a/src/private/mx/core/generated/DegreeType.h +++ b/src/private/mx/core/generated/DegreeType.h @@ -68,12 +68,8 @@ class DegreeType final DegreeTypeValue m_value{}; }; -DegreeType parseDegreeType(pugi::xml_node el); - DegreeType parseDegreeType(pugi::xml_node el, const ParseContext &context); -void parseDegreeTypeContent(DegreeType &out, pugi::xml_node el); - void parseDegreeTypeContent(DegreeType &out, pugi::xml_node el, const ParseContext &context); void serializeDegreeType(const DegreeType &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/DegreeValue.cpp b/src/private/mx/core/generated/DegreeValue.cpp index 72ca5bd37..b88ada1f7 100644 --- a/src/private/mx/core/generated/DegreeValue.cpp +++ b/src/private/mx/core/generated/DegreeValue.cpp @@ -131,11 +131,6 @@ void DegreeValue::setValue(int value) m_value = std::move(value); } -DegreeValue parseDegreeValue(pugi::xml_node el) -{ - return parseDegreeValue(el, ParseContext{}); -} - DegreeValue parseDegreeValue(pugi::xml_node el, const ParseContext &context) { DegreeValue out; @@ -199,11 +194,6 @@ DegreeValue parseDegreeValue(pugi::xml_node el, const ParseContext &context) return out; } -void parseDegreeValueContent(DegreeValue &out, pugi::xml_node el) -{ - parseDegreeValueContent(out, el, ParseContext{}); -} - void parseDegreeValueContent(DegreeValue &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseIntegerValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/DegreeValue.h b/src/private/mx/core/generated/DegreeValue.h index 04cd6b4a6..830a86648 100644 --- a/src/private/mx/core/generated/DegreeValue.h +++ b/src/private/mx/core/generated/DegreeValue.h @@ -71,12 +71,8 @@ class DegreeValue final int m_value{}; }; -DegreeValue parseDegreeValue(pugi::xml_node el); - DegreeValue parseDegreeValue(pugi::xml_node el, const ParseContext &context); -void parseDegreeValueContent(DegreeValue &out, pugi::xml_node el); - void parseDegreeValueContent(DegreeValue &out, pugi::xml_node el, const ParseContext &context); void serializeDegreeValue(const DegreeValue &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Direction.cpp b/src/private/mx/core/generated/Direction.cpp index 1e5972312..a3bcc7b3f 100644 --- a/src/private/mx/core/generated/Direction.cpp +++ b/src/private/mx/core/generated/Direction.cpp @@ -116,11 +116,6 @@ void Direction::setListening(std::optional value) m_listening = std::move(value); } -Direction parseDirection(pugi::xml_node el) -{ - return parseDirection(el, ParseContext{}); -} - Direction parseDirection(pugi::xml_node el, const ParseContext &context) { Direction out; @@ -156,11 +151,6 @@ Direction parseDirection(pugi::xml_node el, const ParseContext &context) return out; } -void parseDirectionContent(Direction &out, pugi::xml_node el) -{ - parseDirectionContent(out, el, ParseContext{}); -} - void parseDirectionContent(Direction &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Direction.h b/src/private/mx/core/generated/Direction.h index b82f96b3f..ddc91eb4a 100644 --- a/src/private/mx/core/generated/Direction.h +++ b/src/private/mx/core/generated/Direction.h @@ -78,12 +78,8 @@ class Direction final std::optional m_listening; }; -Direction parseDirection(pugi::xml_node el); - Direction parseDirection(pugi::xml_node el, const ParseContext &context); -void parseDirectionContent(Direction &out, pugi::xml_node el); - void parseDirectionContent(Direction &out, pugi::xml_node el, const ParseContext &context); void serializeDirection(const Direction &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/DirectionType.cpp b/src/private/mx/core/generated/DirectionType.cpp index 6a820e6e2..4e12e8d06 100644 --- a/src/private/mx/core/generated/DirectionType.cpp +++ b/src/private/mx/core/generated/DirectionType.cpp @@ -31,11 +31,6 @@ void DirectionType::setChoice(DirectionTypeChoice value) m_choice = std::move(value); } -DirectionType parseDirectionType(pugi::xml_node el) -{ - return parseDirectionType(el, ParseContext{}); -} - DirectionType parseDirectionType(pugi::xml_node el, const ParseContext &context) { DirectionType out; @@ -59,11 +54,6 @@ DirectionType parseDirectionType(pugi::xml_node el, const ParseContext &context) return out; } -void parseDirectionTypeContent(DirectionType &out, pugi::xml_node el) -{ - parseDirectionTypeContent(out, el, ParseContext{}); -} - void parseDirectionTypeContent(DirectionType &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/DirectionType.h b/src/private/mx/core/generated/DirectionType.h index 6e0cdcc47..9e7035359 100644 --- a/src/private/mx/core/generated/DirectionType.h +++ b/src/private/mx/core/generated/DirectionType.h @@ -40,12 +40,8 @@ class DirectionType final DirectionTypeChoice m_choice{}; }; -DirectionType parseDirectionType(pugi::xml_node el); - DirectionType parseDirectionType(pugi::xml_node el, const ParseContext &context); -void parseDirectionTypeContent(DirectionType &out, pugi::xml_node el); - void parseDirectionTypeContent(DirectionType &out, pugi::xml_node el, const ParseContext &context); void serializeDirectionType(const DirectionType &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/DirectionTypeChoice.cpp b/src/private/mx/core/generated/DirectionTypeChoice.cpp index 271d3895b..61ca801a1 100644 --- a/src/private/mx/core/generated/DirectionTypeChoice.cpp +++ b/src/private/mx/core/generated/DirectionTypeChoice.cpp @@ -131,11 +131,6 @@ DirectionTypeChoice DirectionTypeChoice::otherDirection(OtherDirection value) return DirectionTypeChoice{Storage{std::in_place_index<22>, std::move(value)}}; } -DirectionTypeChoice parseDirectionTypeChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseDirectionTypeChoice(el, cursor, ParseContext{}); -} - DirectionTypeChoice parseDirectionTypeChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "rehearsal"))) diff --git a/src/private/mx/core/generated/DirectionTypeChoice.h b/src/private/mx/core/generated/DirectionTypeChoice.h index f78bf1a3d..12cc82486 100644 --- a/src/private/mx/core/generated/DirectionTypeChoice.h +++ b/src/private/mx/core/generated/DirectionTypeChoice.h @@ -401,8 +401,6 @@ class DirectionTypeChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -DirectionTypeChoice parseDirectionTypeChoice(pugi::xml_node el, pugi::xml_node &cursor); - DirectionTypeChoice parseDirectionTypeChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeDirectionTypeChoice(const DirectionTypeChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/DirectionTypeChoiceChoice.cpp b/src/private/mx/core/generated/DirectionTypeChoiceChoice.cpp index d533df35e..55989c376 100644 --- a/src/private/mx/core/generated/DirectionTypeChoiceChoice.cpp +++ b/src/private/mx/core/generated/DirectionTypeChoiceChoice.cpp @@ -26,11 +26,6 @@ DirectionTypeChoiceChoice DirectionTypeChoiceChoice::symbol(FormattedSymbolID va return DirectionTypeChoiceChoice{Storage{std::in_place_index<1>, std::move(value)}}; } -DirectionTypeChoiceChoice parseDirectionTypeChoiceChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseDirectionTypeChoiceChoice(el, cursor, ParseContext{}); -} - DirectionTypeChoiceChoice parseDirectionTypeChoiceChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { diff --git a/src/private/mx/core/generated/DirectionTypeChoiceChoice.h b/src/private/mx/core/generated/DirectionTypeChoiceChoice.h index 2d04f69e2..c6cbfe1f8 100644 --- a/src/private/mx/core/generated/DirectionTypeChoiceChoice.h +++ b/src/private/mx/core/generated/DirectionTypeChoiceChoice.h @@ -82,8 +82,6 @@ class DirectionTypeChoiceChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -DirectionTypeChoiceChoice parseDirectionTypeChoiceChoice(pugi::xml_node el, pugi::xml_node &cursor); - DirectionTypeChoiceChoice parseDirectionTypeChoiceChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); diff --git a/src/private/mx/core/generated/Directive.cpp b/src/private/mx/core/generated/Directive.cpp index 0e8ec17b5..0f2da367d 100644 --- a/src/private/mx/core/generated/Directive.cpp +++ b/src/private/mx/core/generated/Directive.cpp @@ -121,11 +121,6 @@ void Directive::setValue(std::string value) m_value = std::move(value); } -Directive parseDirective(pugi::xml_node el) -{ - return parseDirective(el, ParseContext{}); -} - Directive parseDirective(pugi::xml_node el, const ParseContext &context) { Directive out; @@ -185,11 +180,6 @@ Directive parseDirective(pugi::xml_node el, const ParseContext &context) return out; } -void parseDirectiveContent(Directive &out, pugi::xml_node el) -{ - parseDirectiveContent(out, el, ParseContext{}); -} - void parseDirectiveContent(Directive &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/Directive.h b/src/private/mx/core/generated/Directive.h index c7829a9dd..ad1da1ef7 100644 --- a/src/private/mx/core/generated/Directive.h +++ b/src/private/mx/core/generated/Directive.h @@ -63,12 +63,8 @@ class Directive final std::string m_value{}; }; -Directive parseDirective(pugi::xml_node el); - Directive parseDirective(pugi::xml_node el, const ParseContext &context); -void parseDirectiveContent(Directive &out, pugi::xml_node el); - void parseDirectiveContent(Directive &out, pugi::xml_node el, const ParseContext &context); void serializeDirective(const Directive &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/DisplayStepOctaveGroup.cpp b/src/private/mx/core/generated/DisplayStepOctaveGroup.cpp index d78ff85c8..02b6bdd69 100644 --- a/src/private/mx/core/generated/DisplayStepOctaveGroup.cpp +++ b/src/private/mx/core/generated/DisplayStepOctaveGroup.cpp @@ -31,11 +31,6 @@ void DisplayStepOctaveGroup::setDisplayOctave(Octave value) m_displayOctave = std::move(value); } -DisplayStepOctaveGroup parseDisplayStepOctaveGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseDisplayStepOctaveGroup(el, cursor, ParseContext{}); -} - DisplayStepOctaveGroup parseDisplayStepOctaveGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { diff --git a/src/private/mx/core/generated/DisplayStepOctaveGroup.h b/src/private/mx/core/generated/DisplayStepOctaveGroup.h index 91f3929dc..339bdc246 100644 --- a/src/private/mx/core/generated/DisplayStepOctaveGroup.h +++ b/src/private/mx/core/generated/DisplayStepOctaveGroup.h @@ -43,8 +43,6 @@ class DisplayStepOctaveGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -DisplayStepOctaveGroup parseDisplayStepOctaveGroup(pugi::xml_node el, pugi::xml_node &cursor); - DisplayStepOctaveGroup parseDisplayStepOctaveGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); diff --git a/src/private/mx/core/generated/Distance.cpp b/src/private/mx/core/generated/Distance.cpp index 26d21a181..6923aba10 100644 --- a/src/private/mx/core/generated/Distance.cpp +++ b/src/private/mx/core/generated/Distance.cpp @@ -31,11 +31,6 @@ void Distance::setValue(Tenths value) m_value = std::move(value); } -Distance parseDistance(pugi::xml_node el) -{ - return parseDistance(el, ParseContext{}); -} - Distance parseDistance(pugi::xml_node el, const ParseContext &context) { Distance out; @@ -65,11 +60,6 @@ Distance parseDistance(pugi::xml_node el, const ParseContext &context) return out; } -void parseDistanceContent(Distance &out, pugi::xml_node el) -{ - parseDistanceContent(out, el, ParseContext{}); -} - void parseDistanceContent(Distance &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/Distance.h b/src/private/mx/core/generated/Distance.h index 99b0297ec..264451b73 100644 --- a/src/private/mx/core/generated/Distance.h +++ b/src/private/mx/core/generated/Distance.h @@ -35,12 +35,8 @@ class Distance final Tenths m_value{}; }; -Distance parseDistance(pugi::xml_node el); - Distance parseDistance(pugi::xml_node el, const ParseContext &context); -void parseDistanceContent(Distance &out, pugi::xml_node el); - void parseDistanceContent(Distance &out, pugi::xml_node el, const ParseContext &context); void serializeDistance(const Distance &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Document.cpp b/src/private/mx/core/generated/Document.cpp index 7eff91ab3..38f30621d 100644 --- a/src/private/mx/core/generated/Document.cpp +++ b/src/private/mx/core/generated/Document.cpp @@ -14,11 +14,6 @@ namespace mx::core { -Result parse(const pugi::xml_document &doc) -{ - return parse(doc, ParseContext{}); -} - Result parse(const pugi::xml_document &doc, const ParseContext &context) { try diff --git a/src/private/mx/core/generated/Document.h b/src/private/mx/core/generated/Document.h index de1e5fabb..36a2bcb96 100644 --- a/src/private/mx/core/generated/Document.h +++ b/src/private/mx/core/generated/Document.h @@ -103,8 +103,6 @@ class Document final /// The parse error boundary (plan ยง2.5): strict on names and structure, /// lenient on values; a root declaring a version newer than /// SupportedMusicXMLVersion is rejected with unsupportedVersion. -Result parse(const pugi::xml_document &doc); - Result parse(const pugi::xml_document &doc, const ParseContext &context); /// Total for every Document (ยง1.1 guarantees validity): writes the XML diff --git a/src/private/mx/core/generated/Double.cpp b/src/private/mx/core/generated/Double.cpp index 3bb94b4f9..2fa145997 100644 --- a/src/private/mx/core/generated/Double.cpp +++ b/src/private/mx/core/generated/Double.cpp @@ -21,11 +21,6 @@ void Double::setAbove(std::optional value) m_above = std::move(value); } -Double parseDouble(pugi::xml_node el) -{ - return parseDouble(el, ParseContext{}); -} - Double parseDouble(pugi::xml_node el, const ParseContext &context) { Double out; @@ -49,11 +44,6 @@ Double parseDouble(pugi::xml_node el, const ParseContext &context) return out; } -void parseDoubleContent(Double &out, pugi::xml_node el) -{ - parseDoubleContent(out, el, ParseContext{}); -} - void parseDoubleContent(Double &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/Double.h b/src/private/mx/core/generated/Double.h index f6717df37..fbb4f02ad 100644 --- a/src/private/mx/core/generated/Double.h +++ b/src/private/mx/core/generated/Double.h @@ -32,12 +32,8 @@ class Double final std::optional m_above; }; -Double parseDouble(pugi::xml_node el); - Double parseDouble(pugi::xml_node el, const ParseContext &context); -void parseDoubleContent(Double &out, pugi::xml_node el); - void parseDoubleContent(Double &out, pugi::xml_node el, const ParseContext &context); void serializeDouble(const Double &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Dynamics.cpp b/src/private/mx/core/generated/Dynamics.cpp index 5203f1887..f3193e082 100644 --- a/src/private/mx/core/generated/Dynamics.cpp +++ b/src/private/mx/core/generated/Dynamics.cpp @@ -196,11 +196,6 @@ void Dynamics::setChoice(std::vector value) m_choice = std::move(value); } -Dynamics parseDynamics(pugi::xml_node el) -{ - return parseDynamics(el, ParseContext{}); -} - Dynamics parseDynamics(pugi::xml_node el, const ParseContext &context) { Dynamics out; @@ -288,11 +283,6 @@ Dynamics parseDynamics(pugi::xml_node el, const ParseContext &context) return out; } -void parseDynamicsContent(Dynamics &out, pugi::xml_node el) -{ - parseDynamicsContent(out, el, ParseContext{}); -} - void parseDynamicsContent(Dynamics &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Dynamics.h b/src/private/mx/core/generated/Dynamics.h index 88cf9d5e2..bf7e1762d 100644 --- a/src/private/mx/core/generated/Dynamics.h +++ b/src/private/mx/core/generated/Dynamics.h @@ -109,12 +109,8 @@ class Dynamics final std::vector m_choice; }; -Dynamics parseDynamics(pugi::xml_node el); - Dynamics parseDynamics(pugi::xml_node el, const ParseContext &context); -void parseDynamicsContent(Dynamics &out, pugi::xml_node el); - void parseDynamicsContent(Dynamics &out, pugi::xml_node el, const ParseContext &context); void serializeDynamics(const Dynamics &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/DynamicsChoice.cpp b/src/private/mx/core/generated/DynamicsChoice.cpp index 5b224b696..069f8a04a 100644 --- a/src/private/mx/core/generated/DynamicsChoice.cpp +++ b/src/private/mx/core/generated/DynamicsChoice.cpp @@ -151,11 +151,6 @@ DynamicsChoice DynamicsChoice::otherDynamics(OtherText value) return DynamicsChoice{Storage{std::in_place_index<26>, std::move(value)}}; } -DynamicsChoice parseDynamicsChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseDynamicsChoice(el, cursor, ParseContext{}); -} - DynamicsChoice parseDynamicsChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "p"))) diff --git a/src/private/mx/core/generated/DynamicsChoice.h b/src/private/mx/core/generated/DynamicsChoice.h index 981dcdcf5..bf28ceac7 100644 --- a/src/private/mx/core/generated/DynamicsChoice.h +++ b/src/private/mx/core/generated/DynamicsChoice.h @@ -434,8 +434,6 @@ class DynamicsChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -DynamicsChoice parseDynamicsChoice(pugi::xml_node el, pugi::xml_node &cursor); - DynamicsChoice parseDynamicsChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeDynamicsChoice(const DynamicsChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/EditorialGroup.cpp b/src/private/mx/core/generated/EditorialGroup.cpp index d4ff21f37..0ae7149a4 100644 --- a/src/private/mx/core/generated/EditorialGroup.cpp +++ b/src/private/mx/core/generated/EditorialGroup.cpp @@ -31,11 +31,6 @@ void EditorialGroup::setLevel(std::optional value) m_level = std::move(value); } -EditorialGroup parseEditorialGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseEditorialGroup(el, cursor, ParseContext{}); -} - EditorialGroup parseEditorialGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { EditorialGroup out; diff --git a/src/private/mx/core/generated/EditorialGroup.h b/src/private/mx/core/generated/EditorialGroup.h index 812c79369..fb0122d88 100644 --- a/src/private/mx/core/generated/EditorialGroup.h +++ b/src/private/mx/core/generated/EditorialGroup.h @@ -39,8 +39,6 @@ class EditorialGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -EditorialGroup parseEditorialGroup(pugi::xml_node el, pugi::xml_node &cursor); - EditorialGroup parseEditorialGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeEditorialGroup(const EditorialGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/EditorialVoiceDirectionGroup.cpp b/src/private/mx/core/generated/EditorialVoiceDirectionGroup.cpp index dffcba704..0a5acd666 100644 --- a/src/private/mx/core/generated/EditorialVoiceDirectionGroup.cpp +++ b/src/private/mx/core/generated/EditorialVoiceDirectionGroup.cpp @@ -41,11 +41,6 @@ void EditorialVoiceDirectionGroup::setVoice(std::optional value) m_voice = std::move(value); } -EditorialVoiceDirectionGroup parseEditorialVoiceDirectionGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseEditorialVoiceDirectionGroup(el, cursor, ParseContext{}); -} - EditorialVoiceDirectionGroup parseEditorialVoiceDirectionGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { diff --git a/src/private/mx/core/generated/EditorialVoiceDirectionGroup.h b/src/private/mx/core/generated/EditorialVoiceDirectionGroup.h index e22840ecc..390e14033 100644 --- a/src/private/mx/core/generated/EditorialVoiceDirectionGroup.h +++ b/src/private/mx/core/generated/EditorialVoiceDirectionGroup.h @@ -45,8 +45,6 @@ class EditorialVoiceDirectionGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -EditorialVoiceDirectionGroup parseEditorialVoiceDirectionGroup(pugi::xml_node el, pugi::xml_node &cursor); - EditorialVoiceDirectionGroup parseEditorialVoiceDirectionGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); diff --git a/src/private/mx/core/generated/EditorialVoiceGroup.cpp b/src/private/mx/core/generated/EditorialVoiceGroup.cpp index 6086f3922..51b9f560e 100644 --- a/src/private/mx/core/generated/EditorialVoiceGroup.cpp +++ b/src/private/mx/core/generated/EditorialVoiceGroup.cpp @@ -41,11 +41,6 @@ void EditorialVoiceGroup::setVoice(std::optional value) m_voice = std::move(value); } -EditorialVoiceGroup parseEditorialVoiceGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseEditorialVoiceGroup(el, cursor, ParseContext{}); -} - EditorialVoiceGroup parseEditorialVoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { EditorialVoiceGroup out; diff --git a/src/private/mx/core/generated/EditorialVoiceGroup.h b/src/private/mx/core/generated/EditorialVoiceGroup.h index ad8882ec7..123934d0f 100644 --- a/src/private/mx/core/generated/EditorialVoiceGroup.h +++ b/src/private/mx/core/generated/EditorialVoiceGroup.h @@ -43,8 +43,6 @@ class EditorialVoiceGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -EditorialVoiceGroup parseEditorialVoiceGroup(pugi::xml_node el, pugi::xml_node &cursor); - EditorialVoiceGroup parseEditorialVoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeEditorialVoiceGroup(const EditorialVoiceGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Effect.cpp b/src/private/mx/core/generated/Effect.cpp index 4de9c6384..f2c82aba6 100644 --- a/src/private/mx/core/generated/Effect.cpp +++ b/src/private/mx/core/generated/Effect.cpp @@ -31,11 +31,6 @@ void Effect::setValue(EffectValue value) m_value = std::move(value); } -Effect parseEffect(pugi::xml_node el) -{ - return parseEffect(el, ParseContext{}); -} - Effect parseEffect(pugi::xml_node el, const ParseContext &context) { Effect out; @@ -59,11 +54,6 @@ Effect parseEffect(pugi::xml_node el, const ParseContext &context) return out; } -void parseEffectContent(Effect &out, pugi::xml_node el) -{ - parseEffectContent(out, el, ParseContext{}); -} - void parseEffectContent(Effect &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/Effect.h b/src/private/mx/core/generated/Effect.h index 91ab7943a..2968f6726 100644 --- a/src/private/mx/core/generated/Effect.h +++ b/src/private/mx/core/generated/Effect.h @@ -34,12 +34,8 @@ class Effect final EffectValue m_value{}; }; -Effect parseEffect(pugi::xml_node el); - Effect parseEffect(pugi::xml_node el, const ParseContext &context); -void parseEffectContent(Effect &out, pugi::xml_node el); - void parseEffectContent(Effect &out, pugi::xml_node el, const ParseContext &context); void serializeEffect(const Effect &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Elision.cpp b/src/private/mx/core/generated/Elision.cpp index 82d2b119c..f24ac39a1 100644 --- a/src/private/mx/core/generated/Elision.cpp +++ b/src/private/mx/core/generated/Elision.cpp @@ -81,11 +81,6 @@ void Elision::setValue(std::string value) m_value = std::move(value); } -Elision parseElision(pugi::xml_node el) -{ - return parseElision(el, ParseContext{}); -} - Elision parseElision(pugi::xml_node el, const ParseContext &context) { Elision out; @@ -129,11 +124,6 @@ Elision parseElision(pugi::xml_node el, const ParseContext &context) return out; } -void parseElisionContent(Elision &out, pugi::xml_node el) -{ - parseElisionContent(out, el, ParseContext{}); -} - void parseElisionContent(Elision &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/Elision.h b/src/private/mx/core/generated/Elision.h index 98def3af4..5022a9ce5 100644 --- a/src/private/mx/core/generated/Elision.h +++ b/src/private/mx/core/generated/Elision.h @@ -58,12 +58,8 @@ class Elision final std::string m_value{}; }; -Elision parseElision(pugi::xml_node el); - Elision parseElision(pugi::xml_node el, const ParseContext &context); -void parseElisionContent(Elision &out, pugi::xml_node el); - void parseElisionContent(Elision &out, pugi::xml_node el, const ParseContext &context); void serializeElision(const Elision &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/ElisionSyllabicGroup.cpp b/src/private/mx/core/generated/ElisionSyllabicGroup.cpp index 0f358b878..4a703bbed 100644 --- a/src/private/mx/core/generated/ElisionSyllabicGroup.cpp +++ b/src/private/mx/core/generated/ElisionSyllabicGroup.cpp @@ -31,11 +31,6 @@ void ElisionSyllabicGroup::setSyllabic(std::optional value) m_syllabic = std::move(value); } -ElisionSyllabicGroup parseElisionSyllabicGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseElisionSyllabicGroup(el, cursor, ParseContext{}); -} - ElisionSyllabicGroup parseElisionSyllabicGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { ElisionSyllabicGroup out; diff --git a/src/private/mx/core/generated/ElisionSyllabicGroup.h b/src/private/mx/core/generated/ElisionSyllabicGroup.h index 72f511c1f..dc5307a8f 100644 --- a/src/private/mx/core/generated/ElisionSyllabicGroup.h +++ b/src/private/mx/core/generated/ElisionSyllabicGroup.h @@ -39,8 +39,6 @@ class ElisionSyllabicGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -ElisionSyllabicGroup parseElisionSyllabicGroup(pugi::xml_node el, pugi::xml_node &cursor); - ElisionSyllabicGroup parseElisionSyllabicGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeElisionSyllabicGroup(const ElisionSyllabicGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Empty.cpp b/src/private/mx/core/generated/Empty.cpp index 931deadeb..ef4278afe 100644 --- a/src/private/mx/core/generated/Empty.cpp +++ b/src/private/mx/core/generated/Empty.cpp @@ -8,11 +8,6 @@ namespace mx::core { -Empty parseEmpty(pugi::xml_node el) -{ - return parseEmpty(el, ParseContext{}); -} - Empty parseEmpty(pugi::xml_node el, const ParseContext &context) { Empty out; @@ -29,11 +24,6 @@ Empty parseEmpty(pugi::xml_node el, const ParseContext &context) return out; } -void parseEmptyContent(Empty &out, pugi::xml_node el) -{ - parseEmptyContent(out, el, ParseContext{}); -} - void parseEmptyContent(Empty &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/Empty.h b/src/private/mx/core/generated/Empty.h index 4b172eef8..550f036b6 100644 --- a/src/private/mx/core/generated/Empty.h +++ b/src/private/mx/core/generated/Empty.h @@ -22,12 +22,8 @@ class Empty bool operator==(const Empty &) const noexcept = default; }; -Empty parseEmpty(pugi::xml_node el); - Empty parseEmpty(pugi::xml_node el, const ParseContext &context); -void parseEmptyContent(Empty &out, pugi::xml_node el); - void parseEmptyContent(Empty &out, pugi::xml_node el, const ParseContext &context); void serializeEmpty(const Empty &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/EmptyFont.cpp b/src/private/mx/core/generated/EmptyFont.cpp index 6f4b97c52..772ea13ad 100644 --- a/src/private/mx/core/generated/EmptyFont.cpp +++ b/src/private/mx/core/generated/EmptyFont.cpp @@ -51,11 +51,6 @@ void EmptyFont::setFontWeight(std::optional value) m_fontWeight = std::move(value); } -EmptyFont parseEmptyFont(pugi::xml_node el) -{ - return parseEmptyFont(el, ParseContext{}); -} - EmptyFont parseEmptyFont(pugi::xml_node el, const ParseContext &context) { EmptyFont out; @@ -91,11 +86,6 @@ EmptyFont parseEmptyFont(pugi::xml_node el, const ParseContext &context) return out; } -void parseEmptyFontContent(EmptyFont &out, pugi::xml_node el) -{ - parseEmptyFontContent(out, el, ParseContext{}); -} - void parseEmptyFontContent(EmptyFont &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/EmptyFont.h b/src/private/mx/core/generated/EmptyFont.h index affe836b2..92371040c 100644 --- a/src/private/mx/core/generated/EmptyFont.h +++ b/src/private/mx/core/generated/EmptyFont.h @@ -41,12 +41,8 @@ class EmptyFont final std::optional m_fontWeight; }; -EmptyFont parseEmptyFont(pugi::xml_node el); - EmptyFont parseEmptyFont(pugi::xml_node el, const ParseContext &context); -void parseEmptyFontContent(EmptyFont &out, pugi::xml_node el); - void parseEmptyFontContent(EmptyFont &out, pugi::xml_node el, const ParseContext &context); void serializeEmptyFont(const EmptyFont &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/EmptyLine.cpp b/src/private/mx/core/generated/EmptyLine.cpp index 9abe96c27..a92531a25 100644 --- a/src/private/mx/core/generated/EmptyLine.cpp +++ b/src/private/mx/core/generated/EmptyLine.cpp @@ -161,11 +161,6 @@ void EmptyLine::setPlacement(std::optional value) m_placement = std::move(value); } -EmptyLine parseEmptyLine(pugi::xml_node el) -{ - return parseEmptyLine(el, ParseContext{}); -} - EmptyLine parseEmptyLine(pugi::xml_node el, const ParseContext &context) { EmptyLine out; @@ -245,11 +240,6 @@ EmptyLine parseEmptyLine(pugi::xml_node el, const ParseContext &context) return out; } -void parseEmptyLineContent(EmptyLine &out, pugi::xml_node el) -{ - parseEmptyLineContent(out, el, ParseContext{}); -} - void parseEmptyLineContent(EmptyLine &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/EmptyLine.h b/src/private/mx/core/generated/EmptyLine.h index 6cea161f4..9dd599cdb 100644 --- a/src/private/mx/core/generated/EmptyLine.h +++ b/src/private/mx/core/generated/EmptyLine.h @@ -81,12 +81,8 @@ class EmptyLine final std::optional m_placement; }; -EmptyLine parseEmptyLine(pugi::xml_node el); - EmptyLine parseEmptyLine(pugi::xml_node el, const ParseContext &context); -void parseEmptyLineContent(EmptyLine &out, pugi::xml_node el); - void parseEmptyLineContent(EmptyLine &out, pugi::xml_node el, const ParseContext &context); void serializeEmptyLine(const EmptyLine &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/EmptyPlacement.cpp b/src/private/mx/core/generated/EmptyPlacement.cpp index a8a68f126..c829ef8a4 100644 --- a/src/private/mx/core/generated/EmptyPlacement.cpp +++ b/src/private/mx/core/generated/EmptyPlacement.cpp @@ -111,11 +111,6 @@ void EmptyPlacement::setPlacement(std::optional value) m_placement = std::move(value); } -EmptyPlacement parseEmptyPlacement(pugi::xml_node el) -{ - return parseEmptyPlacement(el, ParseContext{}); -} - EmptyPlacement parseEmptyPlacement(pugi::xml_node el, const ParseContext &context) { EmptyPlacement out; @@ -175,11 +170,6 @@ EmptyPlacement parseEmptyPlacement(pugi::xml_node el, const ParseContext &contex return out; } -void parseEmptyPlacementContent(EmptyPlacement &out, pugi::xml_node el) -{ - parseEmptyPlacementContent(out, el, ParseContext{}); -} - void parseEmptyPlacementContent(EmptyPlacement &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/EmptyPlacement.h b/src/private/mx/core/generated/EmptyPlacement.h index 0aa066430..d1b3f45ed 100644 --- a/src/private/mx/core/generated/EmptyPlacement.h +++ b/src/private/mx/core/generated/EmptyPlacement.h @@ -62,12 +62,8 @@ class EmptyPlacement std::optional m_placement; }; -EmptyPlacement parseEmptyPlacement(pugi::xml_node el); - EmptyPlacement parseEmptyPlacement(pugi::xml_node el, const ParseContext &context); -void parseEmptyPlacementContent(EmptyPlacement &out, pugi::xml_node el); - void parseEmptyPlacementContent(EmptyPlacement &out, pugi::xml_node el, const ParseContext &context); void serializeEmptyPlacement(const EmptyPlacement &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/EmptyPlacementSmufl.cpp b/src/private/mx/core/generated/EmptyPlacementSmufl.cpp index 93e4d6a01..597b66dd3 100644 --- a/src/private/mx/core/generated/EmptyPlacementSmufl.cpp +++ b/src/private/mx/core/generated/EmptyPlacementSmufl.cpp @@ -121,11 +121,6 @@ void EmptyPlacementSmufl::setSmufl(std::optional value) m_smufl = std::move(value); } -EmptyPlacementSmufl parseEmptyPlacementSmufl(pugi::xml_node el) -{ - return parseEmptyPlacementSmufl(el, ParseContext{}); -} - EmptyPlacementSmufl parseEmptyPlacementSmufl(pugi::xml_node el, const ParseContext &context) { EmptyPlacementSmufl out; @@ -189,11 +184,6 @@ EmptyPlacementSmufl parseEmptyPlacementSmufl(pugi::xml_node el, const ParseConte return out; } -void parseEmptyPlacementSmuflContent(EmptyPlacementSmufl &out, pugi::xml_node el) -{ - parseEmptyPlacementSmuflContent(out, el, ParseContext{}); -} - void parseEmptyPlacementSmuflContent(EmptyPlacementSmufl &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/EmptyPlacementSmufl.h b/src/private/mx/core/generated/EmptyPlacementSmufl.h index cd4161053..b0acd3265 100644 --- a/src/private/mx/core/generated/EmptyPlacementSmufl.h +++ b/src/private/mx/core/generated/EmptyPlacementSmufl.h @@ -67,12 +67,8 @@ class EmptyPlacementSmufl final std::optional m_smufl; }; -EmptyPlacementSmufl parseEmptyPlacementSmufl(pugi::xml_node el); - EmptyPlacementSmufl parseEmptyPlacementSmufl(pugi::xml_node el, const ParseContext &context); -void parseEmptyPlacementSmuflContent(EmptyPlacementSmufl &out, pugi::xml_node el); - void parseEmptyPlacementSmuflContent(EmptyPlacementSmufl &out, pugi::xml_node el, const ParseContext &context); void serializeEmptyPlacementSmufl(const EmptyPlacementSmufl &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/EmptyPrintObjectStyleAlign.cpp b/src/private/mx/core/generated/EmptyPrintObjectStyleAlign.cpp index 17c9ffb43..673e90ea3 100644 --- a/src/private/mx/core/generated/EmptyPrintObjectStyleAlign.cpp +++ b/src/private/mx/core/generated/EmptyPrintObjectStyleAlign.cpp @@ -131,11 +131,6 @@ void EmptyPrintObjectStyleAlign::setValign(std::optional value) m_valign = std::move(value); } -EmptyPrintObjectStyleAlign parseEmptyPrintObjectStyleAlign(pugi::xml_node el) -{ - return parseEmptyPrintObjectStyleAlign(el, ParseContext{}); -} - EmptyPrintObjectStyleAlign parseEmptyPrintObjectStyleAlign(pugi::xml_node el, const ParseContext &context) { EmptyPrintObjectStyleAlign out; @@ -203,11 +198,6 @@ EmptyPrintObjectStyleAlign parseEmptyPrintObjectStyleAlign(pugi::xml_node el, co return out; } -void parseEmptyPrintObjectStyleAlignContent(EmptyPrintObjectStyleAlign &out, pugi::xml_node el) -{ - parseEmptyPrintObjectStyleAlignContent(out, el, ParseContext{}); -} - void parseEmptyPrintObjectStyleAlignContent(EmptyPrintObjectStyleAlign &out, pugi::xml_node el, const ParseContext &context) { diff --git a/src/private/mx/core/generated/EmptyPrintObjectStyleAlign.h b/src/private/mx/core/generated/EmptyPrintObjectStyleAlign.h index b83d87018..03d875f8a 100644 --- a/src/private/mx/core/generated/EmptyPrintObjectStyleAlign.h +++ b/src/private/mx/core/generated/EmptyPrintObjectStyleAlign.h @@ -71,12 +71,8 @@ class EmptyPrintObjectStyleAlign final std::optional m_valign; }; -EmptyPrintObjectStyleAlign parseEmptyPrintObjectStyleAlign(pugi::xml_node el); - EmptyPrintObjectStyleAlign parseEmptyPrintObjectStyleAlign(pugi::xml_node el, const ParseContext &context); -void parseEmptyPrintObjectStyleAlignContent(EmptyPrintObjectStyleAlign &out, pugi::xml_node el); - void parseEmptyPrintObjectStyleAlignContent(EmptyPrintObjectStyleAlign &out, pugi::xml_node el, const ParseContext &context); diff --git a/src/private/mx/core/generated/EmptyPrintStyleAlignID.cpp b/src/private/mx/core/generated/EmptyPrintStyleAlignID.cpp index 3414ab500..2720d13cd 100644 --- a/src/private/mx/core/generated/EmptyPrintStyleAlignID.cpp +++ b/src/private/mx/core/generated/EmptyPrintStyleAlignID.cpp @@ -131,11 +131,6 @@ void EmptyPrintStyleAlignID::setID(std::optional value) m_id = std::move(value); } -EmptyPrintStyleAlignID parseEmptyPrintStyleAlignID(pugi::xml_node el) -{ - return parseEmptyPrintStyleAlignID(el, ParseContext{}); -} - EmptyPrintStyleAlignID parseEmptyPrintStyleAlignID(pugi::xml_node el, const ParseContext &context) { EmptyPrintStyleAlignID out; @@ -203,11 +198,6 @@ EmptyPrintStyleAlignID parseEmptyPrintStyleAlignID(pugi::xml_node el, const Pars return out; } -void parseEmptyPrintStyleAlignIDContent(EmptyPrintStyleAlignID &out, pugi::xml_node el) -{ - parseEmptyPrintStyleAlignIDContent(out, el, ParseContext{}); -} - void parseEmptyPrintStyleAlignIDContent(EmptyPrintStyleAlignID &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/EmptyPrintStyleAlignID.h b/src/private/mx/core/generated/EmptyPrintStyleAlignID.h index e72d9b55d..c9166209f 100644 --- a/src/private/mx/core/generated/EmptyPrintStyleAlignID.h +++ b/src/private/mx/core/generated/EmptyPrintStyleAlignID.h @@ -72,12 +72,8 @@ class EmptyPrintStyleAlignID final std::optional m_id; }; -EmptyPrintStyleAlignID parseEmptyPrintStyleAlignID(pugi::xml_node el); - EmptyPrintStyleAlignID parseEmptyPrintStyleAlignID(pugi::xml_node el, const ParseContext &context); -void parseEmptyPrintStyleAlignIDContent(EmptyPrintStyleAlignID &out, pugi::xml_node el); - void parseEmptyPrintStyleAlignIDContent(EmptyPrintStyleAlignID &out, pugi::xml_node el, const ParseContext &context); void serializeEmptyPrintStyleAlignID(const EmptyPrintStyleAlignID &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/EmptyTrillSound.cpp b/src/private/mx/core/generated/EmptyTrillSound.cpp index 3c58694d2..5c0538e53 100644 --- a/src/private/mx/core/generated/EmptyTrillSound.cpp +++ b/src/private/mx/core/generated/EmptyTrillSound.cpp @@ -181,11 +181,6 @@ void EmptyTrillSound::setLastBeat(std::optional value) m_lastBeat = std::move(value); } -EmptyTrillSound parseEmptyTrillSound(pugi::xml_node el) -{ - return parseEmptyTrillSound(el, ParseContext{}); -} - EmptyTrillSound parseEmptyTrillSound(pugi::xml_node el, const ParseContext &context) { EmptyTrillSound out; @@ -273,11 +268,6 @@ EmptyTrillSound parseEmptyTrillSound(pugi::xml_node el, const ParseContext &cont return out; } -void parseEmptyTrillSoundContent(EmptyTrillSound &out, pugi::xml_node el) -{ - parseEmptyTrillSoundContent(out, el, ParseContext{}); -} - void parseEmptyTrillSoundContent(EmptyTrillSound &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/EmptyTrillSound.h b/src/private/mx/core/generated/EmptyTrillSound.h index 0312699f8..01f529c8c 100644 --- a/src/private/mx/core/generated/EmptyTrillSound.h +++ b/src/private/mx/core/generated/EmptyTrillSound.h @@ -90,12 +90,8 @@ class EmptyTrillSound std::optional m_lastBeat; }; -EmptyTrillSound parseEmptyTrillSound(pugi::xml_node el); - EmptyTrillSound parseEmptyTrillSound(pugi::xml_node el, const ParseContext &context); -void parseEmptyTrillSoundContent(EmptyTrillSound &out, pugi::xml_node el); - void parseEmptyTrillSoundContent(EmptyTrillSound &out, pugi::xml_node el, const ParseContext &context); void serializeEmptyTrillSound(const EmptyTrillSound &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Encoding.cpp b/src/private/mx/core/generated/Encoding.cpp index 499de23b5..16402d437 100644 --- a/src/private/mx/core/generated/Encoding.cpp +++ b/src/private/mx/core/generated/Encoding.cpp @@ -26,11 +26,6 @@ void Encoding::setChoice(std::vector value) m_choice = std::move(value); } -Encoding parseEncoding(pugi::xml_node el) -{ - return parseEncoding(el, ParseContext{}); -} - Encoding parseEncoding(pugi::xml_node el, const ParseContext &context) { Encoding out; @@ -47,11 +42,6 @@ Encoding parseEncoding(pugi::xml_node el, const ParseContext &context) return out; } -void parseEncodingContent(Encoding &out, pugi::xml_node el) -{ - parseEncodingContent(out, el, ParseContext{}); -} - void parseEncodingContent(Encoding &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Encoding.h b/src/private/mx/core/generated/Encoding.h index 4945e46fe..f8d2a8416 100644 --- a/src/private/mx/core/generated/Encoding.h +++ b/src/private/mx/core/generated/Encoding.h @@ -37,12 +37,8 @@ class Encoding final std::vector m_choice; }; -Encoding parseEncoding(pugi::xml_node el); - Encoding parseEncoding(pugi::xml_node el, const ParseContext &context); -void parseEncodingContent(Encoding &out, pugi::xml_node el); - void parseEncodingContent(Encoding &out, pugi::xml_node el, const ParseContext &context); void serializeEncoding(const Encoding &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/EncodingChoice.cpp b/src/private/mx/core/generated/EncodingChoice.cpp index 5bc0c5b19..046cf63b4 100644 --- a/src/private/mx/core/generated/EncodingChoice.cpp +++ b/src/private/mx/core/generated/EncodingChoice.cpp @@ -41,11 +41,6 @@ EncodingChoice EncodingChoice::supports(Supports value) return EncodingChoice{Storage{std::in_place_index<4>, std::move(value)}}; } -EncodingChoice parseEncodingChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseEncodingChoice(el, cursor, ParseContext{}); -} - EncodingChoice parseEncodingChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "encoding-date"))) diff --git a/src/private/mx/core/generated/EncodingChoice.h b/src/private/mx/core/generated/EncodingChoice.h index b282da60e..dda15de8e 100644 --- a/src/private/mx/core/generated/EncodingChoice.h +++ b/src/private/mx/core/generated/EncodingChoice.h @@ -125,8 +125,6 @@ class EncodingChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -EncodingChoice parseEncodingChoice(pugi::xml_node el, pugi::xml_node &cursor); - EncodingChoice parseEncodingChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeEncodingChoice(const EncodingChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Ending.cpp b/src/private/mx/core/generated/Ending.cpp index 71a8db6b6..57daf629a 100644 --- a/src/private/mx/core/generated/Ending.cpp +++ b/src/private/mx/core/generated/Ending.cpp @@ -181,11 +181,6 @@ void Ending::setValue(std::string value) m_value = std::move(value); } -Ending parseEnding(pugi::xml_node el) -{ - return parseEnding(el, ParseContext{}); -} - Ending parseEnding(pugi::xml_node el, const ParseContext &context) { Ending out; @@ -281,11 +276,6 @@ Ending parseEnding(pugi::xml_node el, const ParseContext &context) return out; } -void parseEndingContent(Ending &out, pugi::xml_node el) -{ - parseEndingContent(out, el, ParseContext{}); -} - void parseEndingContent(Ending &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/Ending.h b/src/private/mx/core/generated/Ending.h index 2bbb02918..0ec39556a 100644 --- a/src/private/mx/core/generated/Ending.h +++ b/src/private/mx/core/generated/Ending.h @@ -100,12 +100,8 @@ class Ending final std::string m_value{}; }; -Ending parseEnding(pugi::xml_node el); - Ending parseEnding(pugi::xml_node el, const ParseContext &context); -void parseEndingContent(Ending &out, pugi::xml_node el); - void parseEndingContent(Ending &out, pugi::xml_node el, const ParseContext &context); void serializeEnding(const Ending &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Extend.cpp b/src/private/mx/core/generated/Extend.cpp index e0ad130f5..ca40f7d1e 100644 --- a/src/private/mx/core/generated/Extend.cpp +++ b/src/private/mx/core/generated/Extend.cpp @@ -71,11 +71,6 @@ void Extend::setColor(std::optional value) m_color = std::move(value); } -Extend parseExtend(pugi::xml_node el) -{ - return parseExtend(el, ParseContext{}); -} - Extend parseExtend(pugi::xml_node el, const ParseContext &context) { Extend out; @@ -119,11 +114,6 @@ Extend parseExtend(pugi::xml_node el, const ParseContext &context) return out; } -void parseExtendContent(Extend &out, pugi::xml_node el) -{ - parseExtendContent(out, el, ParseContext{}); -} - void parseExtendContent(Extend &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/Extend.h b/src/private/mx/core/generated/Extend.h index 2ea659af1..dec4cfa81 100644 --- a/src/private/mx/core/generated/Extend.h +++ b/src/private/mx/core/generated/Extend.h @@ -48,12 +48,8 @@ class Extend final std::optional m_color; }; -Extend parseExtend(pugi::xml_node el); - Extend parseExtend(pugi::xml_node el, const ParseContext &context); -void parseExtendContent(Extend &out, pugi::xml_node el); - void parseExtendContent(Extend &out, pugi::xml_node el, const ParseContext &context); void serializeExtend(const Extend &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Feature.cpp b/src/private/mx/core/generated/Feature.cpp index 98009ab6f..ed88564e0 100644 --- a/src/private/mx/core/generated/Feature.cpp +++ b/src/private/mx/core/generated/Feature.cpp @@ -31,11 +31,6 @@ void Feature::setValue(std::string value) m_value = std::move(value); } -Feature parseFeature(pugi::xml_node el) -{ - return parseFeature(el, ParseContext{}); -} - Feature parseFeature(pugi::xml_node el, const ParseContext &context) { Feature out; @@ -59,11 +54,6 @@ Feature parseFeature(pugi::xml_node el, const ParseContext &context) return out; } -void parseFeatureContent(Feature &out, pugi::xml_node el) -{ - parseFeatureContent(out, el, ParseContext{}); -} - void parseFeatureContent(Feature &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/Feature.h b/src/private/mx/core/generated/Feature.h index 801780ed3..6c977be34 100644 --- a/src/private/mx/core/generated/Feature.h +++ b/src/private/mx/core/generated/Feature.h @@ -32,12 +32,8 @@ class Feature final std::string m_value{}; }; -Feature parseFeature(pugi::xml_node el); - Feature parseFeature(pugi::xml_node el, const ParseContext &context); -void parseFeatureContent(Feature &out, pugi::xml_node el); - void parseFeatureContent(Feature &out, pugi::xml_node el, const ParseContext &context); void serializeFeature(const Feature &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Fermata.cpp b/src/private/mx/core/generated/Fermata.cpp index 588c12c95..014336d8f 100644 --- a/src/private/mx/core/generated/Fermata.cpp +++ b/src/private/mx/core/generated/Fermata.cpp @@ -131,11 +131,6 @@ void Fermata::setValue(FermataShape value) m_value = std::move(value); } -Fermata parseFermata(pugi::xml_node el) -{ - return parseFermata(el, ParseContext{}); -} - Fermata parseFermata(pugi::xml_node el, const ParseContext &context) { Fermata out; @@ -199,11 +194,6 @@ Fermata parseFermata(pugi::xml_node el, const ParseContext &context) return out; } -void parseFermataContent(Fermata &out, pugi::xml_node el) -{ - parseFermataContent(out, el, ParseContext{}); -} - void parseFermataContent(Fermata &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/Fermata.h b/src/private/mx/core/generated/Fermata.h index e645ecc40..9b8969e82 100644 --- a/src/private/mx/core/generated/Fermata.h +++ b/src/private/mx/core/generated/Fermata.h @@ -72,12 +72,8 @@ class Fermata final FermataShape m_value{}; }; -Fermata parseFermata(pugi::xml_node el); - Fermata parseFermata(pugi::xml_node el, const ParseContext &context); -void parseFermataContent(Fermata &out, pugi::xml_node el); - void parseFermataContent(Fermata &out, pugi::xml_node el, const ParseContext &context); void serializeFermata(const Fermata &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Figure.cpp b/src/private/mx/core/generated/Figure.cpp index 954e78a1a..108b0d35e 100644 --- a/src/private/mx/core/generated/Figure.cpp +++ b/src/private/mx/core/generated/Figure.cpp @@ -61,11 +61,6 @@ void Figure::setEditorial(EditorialGroup value) m_editorial = std::move(value); } -Figure parseFigure(pugi::xml_node el) -{ - return parseFigure(el, ParseContext{}); -} - Figure parseFigure(pugi::xml_node el, const ParseContext &context) { Figure out; @@ -82,11 +77,6 @@ Figure parseFigure(pugi::xml_node el, const ParseContext &context) return out; } -void parseFigureContent(Figure &out, pugi::xml_node el) -{ - parseFigureContent(out, el, ParseContext{}); -} - void parseFigureContent(Figure &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Figure.h b/src/private/mx/core/generated/Figure.h index e9ae5e3e2..476f33c98 100644 --- a/src/private/mx/core/generated/Figure.h +++ b/src/private/mx/core/generated/Figure.h @@ -47,12 +47,8 @@ class Figure final EditorialGroup m_editorial{}; }; -Figure parseFigure(pugi::xml_node el); - Figure parseFigure(pugi::xml_node el, const ParseContext &context); -void parseFigureContent(Figure &out, pugi::xml_node el); - void parseFigureContent(Figure &out, pugi::xml_node el, const ParseContext &context); void serializeFigure(const Figure &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/FiguredBass.cpp b/src/private/mx/core/generated/FiguredBass.cpp index 3699b1fc4..53557f047 100644 --- a/src/private/mx/core/generated/FiguredBass.cpp +++ b/src/private/mx/core/generated/FiguredBass.cpp @@ -226,11 +226,6 @@ void FiguredBass::setEditorial(EditorialGroup value) m_editorial = std::move(value); } -FiguredBass parseFiguredBass(pugi::xml_node el) -{ - return parseFiguredBass(el, ParseContext{}); -} - FiguredBass parseFiguredBass(pugi::xml_node el, const ParseContext &context) { FiguredBass out; @@ -322,11 +317,6 @@ FiguredBass parseFiguredBass(pugi::xml_node el, const ParseContext &context) return out; } -void parseFiguredBassContent(FiguredBass &out, pugi::xml_node el) -{ - parseFiguredBassContent(out, el, ParseContext{}); -} - void parseFiguredBassContent(FiguredBass &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/FiguredBass.h b/src/private/mx/core/generated/FiguredBass.h index 5ae63b372..d5674e8d3 100644 --- a/src/private/mx/core/generated/FiguredBass.h +++ b/src/private/mx/core/generated/FiguredBass.h @@ -112,12 +112,8 @@ class FiguredBass final EditorialGroup m_editorial{}; }; -FiguredBass parseFiguredBass(pugi::xml_node el); - FiguredBass parseFiguredBass(pugi::xml_node el, const ParseContext &context); -void parseFiguredBassContent(FiguredBass &out, pugi::xml_node el); - void parseFiguredBassContent(FiguredBass &out, pugi::xml_node el, const ParseContext &context); void serializeFiguredBass(const FiguredBass &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Fingering.cpp b/src/private/mx/core/generated/Fingering.cpp index c781c67fb..6525398ed 100644 --- a/src/private/mx/core/generated/Fingering.cpp +++ b/src/private/mx/core/generated/Fingering.cpp @@ -141,11 +141,6 @@ void Fingering::setValue(std::string value) m_value = std::move(value); } -Fingering parseFingering(pugi::xml_node el) -{ - return parseFingering(el, ParseContext{}); -} - Fingering parseFingering(pugi::xml_node el, const ParseContext &context) { Fingering out; @@ -213,11 +208,6 @@ Fingering parseFingering(pugi::xml_node el, const ParseContext &context) return out; } -void parseFingeringContent(Fingering &out, pugi::xml_node el) -{ - parseFingeringContent(out, el, ParseContext{}); -} - void parseFingeringContent(Fingering &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/Fingering.h b/src/private/mx/core/generated/Fingering.h index d31bac000..e88fe44be 100644 --- a/src/private/mx/core/generated/Fingering.h +++ b/src/private/mx/core/generated/Fingering.h @@ -75,12 +75,8 @@ class Fingering final std::string m_value{}; }; -Fingering parseFingering(pugi::xml_node el); - Fingering parseFingering(pugi::xml_node el, const ParseContext &context); -void parseFingeringContent(Fingering &out, pugi::xml_node el); - void parseFingeringContent(Fingering &out, pugi::xml_node el, const ParseContext &context); void serializeFingering(const Fingering &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/FirstFret.cpp b/src/private/mx/core/generated/FirstFret.cpp index da4c9a2ef..5aa96db09 100644 --- a/src/private/mx/core/generated/FirstFret.cpp +++ b/src/private/mx/core/generated/FirstFret.cpp @@ -41,11 +41,6 @@ void FirstFret::setValue(int value) m_value = std::move(value); } -FirstFret parseFirstFret(pugi::xml_node el) -{ - return parseFirstFret(el, ParseContext{}); -} - FirstFret parseFirstFret(pugi::xml_node el, const ParseContext &context) { FirstFret out; @@ -73,11 +68,6 @@ FirstFret parseFirstFret(pugi::xml_node el, const ParseContext &context) return out; } -void parseFirstFretContent(FirstFret &out, pugi::xml_node el) -{ - parseFirstFretContent(out, el, ParseContext{}); -} - void parseFirstFretContent(FirstFret &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseIntegerValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/FirstFret.h b/src/private/mx/core/generated/FirstFret.h index b9b2867ab..42a1e0952 100644 --- a/src/private/mx/core/generated/FirstFret.h +++ b/src/private/mx/core/generated/FirstFret.h @@ -38,12 +38,8 @@ class FirstFret final int m_value{}; }; -FirstFret parseFirstFret(pugi::xml_node el); - FirstFret parseFirstFret(pugi::xml_node el, const ParseContext &context); -void parseFirstFretContent(FirstFret &out, pugi::xml_node el); - void parseFirstFretContent(FirstFret &out, pugi::xml_node el, const ParseContext &context); void serializeFirstFret(const FirstFret &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/ForPart.cpp b/src/private/mx/core/generated/ForPart.cpp index 40bb4b7a2..5748a109e 100644 --- a/src/private/mx/core/generated/ForPart.cpp +++ b/src/private/mx/core/generated/ForPart.cpp @@ -51,11 +51,6 @@ void ForPart::setPartTranspose(PartTranspose value) m_partTranspose = std::move(value); } -ForPart parseForPart(pugi::xml_node el) -{ - return parseForPart(el, ParseContext{}); -} - ForPart parseForPart(pugi::xml_node el, const ParseContext &context) { ForPart out; @@ -83,11 +78,6 @@ ForPart parseForPart(pugi::xml_node el, const ParseContext &context) return out; } -void parseForPartContent(ForPart &out, pugi::xml_node el) -{ - parseForPartContent(out, el, ParseContext{}); -} - void parseForPartContent(ForPart &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/ForPart.h b/src/private/mx/core/generated/ForPart.h index 4f3089676..0e63083a5 100644 --- a/src/private/mx/core/generated/ForPart.h +++ b/src/private/mx/core/generated/ForPart.h @@ -50,12 +50,8 @@ class ForPart final PartTranspose m_partTranspose{}; }; -ForPart parseForPart(pugi::xml_node el); - ForPart parseForPart(pugi::xml_node el, const ParseContext &context); -void parseForPartContent(ForPart &out, pugi::xml_node el); - void parseForPartContent(ForPart &out, pugi::xml_node el, const ParseContext &context); void serializeForPart(const ForPart &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/FormattedSymbolID.cpp b/src/private/mx/core/generated/FormattedSymbolID.cpp index 4f58b76e4..ecc9a2d42 100644 --- a/src/private/mx/core/generated/FormattedSymbolID.cpp +++ b/src/private/mx/core/generated/FormattedSymbolID.cpp @@ -231,11 +231,6 @@ void FormattedSymbolID::setValue(SmuflGlyphName value) m_value = std::move(value); } -FormattedSymbolID parseFormattedSymbolID(pugi::xml_node el) -{ - return parseFormattedSymbolID(el, ParseContext{}); -} - FormattedSymbolID parseFormattedSymbolID(pugi::xml_node el, const ParseContext &context) { FormattedSymbolID out; @@ -339,11 +334,6 @@ FormattedSymbolID parseFormattedSymbolID(pugi::xml_node el, const ParseContext & return out; } -void parseFormattedSymbolIDContent(FormattedSymbolID &out, pugi::xml_node el) -{ - parseFormattedSymbolIDContent(out, el, ParseContext{}); -} - void parseFormattedSymbolIDContent(FormattedSymbolID &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/FormattedSymbolID.h b/src/private/mx/core/generated/FormattedSymbolID.h index 5e55f4bbc..73d58fdde 100644 --- a/src/private/mx/core/generated/FormattedSymbolID.h +++ b/src/private/mx/core/generated/FormattedSymbolID.h @@ -108,12 +108,8 @@ class FormattedSymbolID final SmuflGlyphName m_value{}; }; -FormattedSymbolID parseFormattedSymbolID(pugi::xml_node el); - FormattedSymbolID parseFormattedSymbolID(pugi::xml_node el, const ParseContext &context); -void parseFormattedSymbolIDContent(FormattedSymbolID &out, pugi::xml_node el); - void parseFormattedSymbolIDContent(FormattedSymbolID &out, pugi::xml_node el, const ParseContext &context); void serializeFormattedSymbolID(const FormattedSymbolID &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/FormattedText.cpp b/src/private/mx/core/generated/FormattedText.cpp index 0bcda494f..68898015c 100644 --- a/src/private/mx/core/generated/FormattedText.cpp +++ b/src/private/mx/core/generated/FormattedText.cpp @@ -241,11 +241,6 @@ void FormattedText::setValue(std::string value) m_value = std::move(value); } -FormattedText parseFormattedText(pugi::xml_node el) -{ - return parseFormattedText(el, ParseContext{}); -} - FormattedText parseFormattedText(pugi::xml_node el, const ParseContext &context) { FormattedText out; @@ -353,11 +348,6 @@ FormattedText parseFormattedText(pugi::xml_node el, const ParseContext &context) return out; } -void parseFormattedTextContent(FormattedText &out, pugi::xml_node el) -{ - parseFormattedTextContent(out, el, ParseContext{}); -} - void parseFormattedTextContent(FormattedText &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/FormattedText.h b/src/private/mx/core/generated/FormattedText.h index 0a1205215..576513849 100644 --- a/src/private/mx/core/generated/FormattedText.h +++ b/src/private/mx/core/generated/FormattedText.h @@ -107,12 +107,8 @@ class FormattedText final std::string m_value{}; }; -FormattedText parseFormattedText(pugi::xml_node el); - FormattedText parseFormattedText(pugi::xml_node el, const ParseContext &context); -void parseFormattedTextContent(FormattedText &out, pugi::xml_node el); - void parseFormattedTextContent(FormattedText &out, pugi::xml_node el, const ParseContext &context); void serializeFormattedText(const FormattedText &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/FormattedTextID.cpp b/src/private/mx/core/generated/FormattedTextID.cpp index 1cf81365f..c6e2717af 100644 --- a/src/private/mx/core/generated/FormattedTextID.cpp +++ b/src/private/mx/core/generated/FormattedTextID.cpp @@ -251,11 +251,6 @@ void FormattedTextID::setValue(std::string value) m_value = std::move(value); } -FormattedTextID parseFormattedTextID(pugi::xml_node el) -{ - return parseFormattedTextID(el, ParseContext{}); -} - FormattedTextID parseFormattedTextID(pugi::xml_node el, const ParseContext &context) { FormattedTextID out; @@ -367,11 +362,6 @@ FormattedTextID parseFormattedTextID(pugi::xml_node el, const ParseContext &cont return out; } -void parseFormattedTextIDContent(FormattedTextID &out, pugi::xml_node el) -{ - parseFormattedTextIDContent(out, el, ParseContext{}); -} - void parseFormattedTextIDContent(FormattedTextID &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/FormattedTextID.h b/src/private/mx/core/generated/FormattedTextID.h index 89d396fe3..4cb107b6c 100644 --- a/src/private/mx/core/generated/FormattedTextID.h +++ b/src/private/mx/core/generated/FormattedTextID.h @@ -112,12 +112,8 @@ class FormattedTextID final std::string m_value{}; }; -FormattedTextID parseFormattedTextID(pugi::xml_node el); - FormattedTextID parseFormattedTextID(pugi::xml_node el, const ParseContext &context); -void parseFormattedTextIDContent(FormattedTextID &out, pugi::xml_node el); - void parseFormattedTextIDContent(FormattedTextID &out, pugi::xml_node el, const ParseContext &context); void serializeFormattedTextID(const FormattedTextID &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Forward.cpp b/src/private/mx/core/generated/Forward.cpp index 741c4746c..263c5cbeb 100644 --- a/src/private/mx/core/generated/Forward.cpp +++ b/src/private/mx/core/generated/Forward.cpp @@ -41,11 +41,6 @@ void Forward::setStaff(std::optional value) m_staff = std::move(value); } -Forward parseForward(pugi::xml_node el) -{ - return parseForward(el, ParseContext{}); -} - Forward parseForward(pugi::xml_node el, const ParseContext &context) { Forward out; @@ -62,11 +57,6 @@ Forward parseForward(pugi::xml_node el, const ParseContext &context) return out; } -void parseForwardContent(Forward &out, pugi::xml_node el) -{ - parseForwardContent(out, el, ParseContext{}); -} - void parseForwardContent(Forward &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Forward.h b/src/private/mx/core/generated/Forward.h index a46fea183..1893e4bdc 100644 --- a/src/private/mx/core/generated/Forward.h +++ b/src/private/mx/core/generated/Forward.h @@ -43,12 +43,8 @@ class Forward final std::optional m_staff; }; -Forward parseForward(pugi::xml_node el); - Forward parseForward(pugi::xml_node el, const ParseContext &context); -void parseForwardContent(Forward &out, pugi::xml_node el); - void parseForwardContent(Forward &out, pugi::xml_node el, const ParseContext &context); void serializeForward(const Forward &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Frame.cpp b/src/private/mx/core/generated/Frame.cpp index 9a39955fe..5b82c7662 100644 --- a/src/private/mx/core/generated/Frame.cpp +++ b/src/private/mx/core/generated/Frame.cpp @@ -166,11 +166,6 @@ void Frame::setFrameNote(OneOrMore value) m_frameNote = std::move(value); } -Frame parseFrame(pugi::xml_node el) -{ - return parseFrame(el, ParseContext{}); -} - Frame parseFrame(pugi::xml_node el, const ParseContext &context) { Frame out; @@ -234,11 +229,6 @@ Frame parseFrame(pugi::xml_node el, const ParseContext &context) return out; } -void parseFrameContent(Frame &out, pugi::xml_node el) -{ - parseFrameContent(out, el, ParseContext{}); -} - void parseFrameContent(Frame &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Frame.h b/src/private/mx/core/generated/Frame.h index 8a6d27419..9ca10c848 100644 --- a/src/private/mx/core/generated/Frame.h +++ b/src/private/mx/core/generated/Frame.h @@ -88,12 +88,8 @@ class Frame final OneOrMore m_frameNote; }; -Frame parseFrame(pugi::xml_node el); - Frame parseFrame(pugi::xml_node el, const ParseContext &context); -void parseFrameContent(Frame &out, pugi::xml_node el); - void parseFrameContent(Frame &out, pugi::xml_node el, const ParseContext &context); void serializeFrame(const Frame &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/FrameNote.cpp b/src/private/mx/core/generated/FrameNote.cpp index 34ad9bd03..c991a6b92 100644 --- a/src/private/mx/core/generated/FrameNote.cpp +++ b/src/private/mx/core/generated/FrameNote.cpp @@ -51,11 +51,6 @@ void FrameNote::setBarre(std::optional value) m_barre = std::move(value); } -FrameNote parseFrameNote(pugi::xml_node el) -{ - return parseFrameNote(el, ParseContext{}); -} - FrameNote parseFrameNote(pugi::xml_node el, const ParseContext &context) { FrameNote out; @@ -72,11 +67,6 @@ FrameNote parseFrameNote(pugi::xml_node el, const ParseContext &context) return out; } -void parseFrameNoteContent(FrameNote &out, pugi::xml_node el) -{ - parseFrameNoteContent(out, el, ParseContext{}); -} - void parseFrameNoteContent(FrameNote &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/FrameNote.h b/src/private/mx/core/generated/FrameNote.h index 9d44f6ef5..5696672a1 100644 --- a/src/private/mx/core/generated/FrameNote.h +++ b/src/private/mx/core/generated/FrameNote.h @@ -46,12 +46,8 @@ class FrameNote final std::optional m_barre; }; -FrameNote parseFrameNote(pugi::xml_node el); - FrameNote parseFrameNote(pugi::xml_node el, const ParseContext &context); -void parseFrameNoteContent(FrameNote &out, pugi::xml_node el); - void parseFrameNoteContent(FrameNote &out, pugi::xml_node el, const ParseContext &context); void serializeFrameNote(const FrameNote &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Fret.cpp b/src/private/mx/core/generated/Fret.cpp index 87f9d605e..633b4b7ef 100644 --- a/src/private/mx/core/generated/Fret.cpp +++ b/src/private/mx/core/generated/Fret.cpp @@ -71,11 +71,6 @@ void Fret::setValue(int value) m_value = std::move(value); } -Fret parseFret(pugi::xml_node el) -{ - return parseFret(el, ParseContext{}); -} - Fret parseFret(pugi::xml_node el, const ParseContext &context) { Fret out; @@ -115,11 +110,6 @@ Fret parseFret(pugi::xml_node el, const ParseContext &context) return out; } -void parseFretContent(Fret &out, pugi::xml_node el) -{ - parseFretContent(out, el, ParseContext{}); -} - void parseFretContent(Fret &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseIntegerValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/Fret.h b/src/private/mx/core/generated/Fret.h index e5dbee518..81438825c 100644 --- a/src/private/mx/core/generated/Fret.h +++ b/src/private/mx/core/generated/Fret.h @@ -49,12 +49,8 @@ class Fret final int m_value{}; }; -Fret parseFret(pugi::xml_node el); - Fret parseFret(pugi::xml_node el, const ParseContext &context); -void parseFretContent(Fret &out, pugi::xml_node el); - void parseFretContent(Fret &out, pugi::xml_node el, const ParseContext &context); void serializeFret(const Fret &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/FullNoteGroup.cpp b/src/private/mx/core/generated/FullNoteGroup.cpp index 4dd59f444..99d83ac00 100644 --- a/src/private/mx/core/generated/FullNoteGroup.cpp +++ b/src/private/mx/core/generated/FullNoteGroup.cpp @@ -31,11 +31,6 @@ void FullNoteGroup::setChoice(FullNoteGroupChoice value) m_choice = std::move(value); } -FullNoteGroup parseFullNoteGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseFullNoteGroup(el, cursor, ParseContext{}); -} - FullNoteGroup parseFullNoteGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { FullNoteGroup out; diff --git a/src/private/mx/core/generated/FullNoteGroup.h b/src/private/mx/core/generated/FullNoteGroup.h index 54930541d..351ff3b72 100644 --- a/src/private/mx/core/generated/FullNoteGroup.h +++ b/src/private/mx/core/generated/FullNoteGroup.h @@ -42,8 +42,6 @@ class FullNoteGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -FullNoteGroup parseFullNoteGroup(pugi::xml_node el, pugi::xml_node &cursor); - FullNoteGroup parseFullNoteGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeFullNoteGroup(const FullNoteGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/FullNoteGroupChoice.cpp b/src/private/mx/core/generated/FullNoteGroupChoice.cpp index 1e56c25f6..764997421 100644 --- a/src/private/mx/core/generated/FullNoteGroupChoice.cpp +++ b/src/private/mx/core/generated/FullNoteGroupChoice.cpp @@ -31,11 +31,6 @@ FullNoteGroupChoice FullNoteGroupChoice::rest(Rest value) return FullNoteGroupChoice{Storage{std::in_place_index<2>, std::move(value)}}; } -FullNoteGroupChoice parseFullNoteGroupChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseFullNoteGroupChoice(el, cursor, ParseContext{}); -} - FullNoteGroupChoice parseFullNoteGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "pitch"))) diff --git a/src/private/mx/core/generated/FullNoteGroupChoice.h b/src/private/mx/core/generated/FullNoteGroupChoice.h index d447a28d2..cceafe445 100644 --- a/src/private/mx/core/generated/FullNoteGroupChoice.h +++ b/src/private/mx/core/generated/FullNoteGroupChoice.h @@ -97,8 +97,6 @@ class FullNoteGroupChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -FullNoteGroupChoice parseFullNoteGroupChoice(pugi::xml_node el, pugi::xml_node &cursor); - FullNoteGroupChoice parseFullNoteGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeFullNoteGroupChoice(const FullNoteGroupChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Glass.cpp b/src/private/mx/core/generated/Glass.cpp index 4e242f436..811b5fb21 100644 --- a/src/private/mx/core/generated/Glass.cpp +++ b/src/private/mx/core/generated/Glass.cpp @@ -31,11 +31,6 @@ void Glass::setValue(GlassValue value) m_value = std::move(value); } -Glass parseGlass(pugi::xml_node el) -{ - return parseGlass(el, ParseContext{}); -} - Glass parseGlass(pugi::xml_node el, const ParseContext &context) { Glass out; @@ -59,11 +54,6 @@ Glass parseGlass(pugi::xml_node el, const ParseContext &context) return out; } -void parseGlassContent(Glass &out, pugi::xml_node el) -{ - parseGlassContent(out, el, ParseContext{}); -} - void parseGlassContent(Glass &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/Glass.h b/src/private/mx/core/generated/Glass.h index 0681c8c9e..2c401794b 100644 --- a/src/private/mx/core/generated/Glass.h +++ b/src/private/mx/core/generated/Glass.h @@ -35,12 +35,8 @@ class Glass final GlassValue m_value{}; }; -Glass parseGlass(pugi::xml_node el); - Glass parseGlass(pugi::xml_node el, const ParseContext &context); -void parseGlassContent(Glass &out, pugi::xml_node el); - void parseGlassContent(Glass &out, pugi::xml_node el, const ParseContext &context); void serializeGlass(const Glass &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Glissando.cpp b/src/private/mx/core/generated/Glissando.cpp index 0c0ca1e65..c2c58eb1a 100644 --- a/src/private/mx/core/generated/Glissando.cpp +++ b/src/private/mx/core/generated/Glissando.cpp @@ -171,11 +171,6 @@ void Glissando::setValue(std::string value) m_value = std::move(value); } -Glissando parseGlissando(pugi::xml_node el) -{ - return parseGlissando(el, ParseContext{}); -} - Glissando parseGlissando(pugi::xml_node el, const ParseContext &context) { Glissando out; @@ -261,11 +256,6 @@ Glissando parseGlissando(pugi::xml_node el, const ParseContext &context) return out; } -void parseGlissandoContent(Glissando &out, pugi::xml_node el) -{ - parseGlissandoContent(out, el, ParseContext{}); -} - void parseGlissandoContent(Glissando &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/Glissando.h b/src/private/mx/core/generated/Glissando.h index 46e57e251..a779eabfb 100644 --- a/src/private/mx/core/generated/Glissando.h +++ b/src/private/mx/core/generated/Glissando.h @@ -86,12 +86,8 @@ class Glissando final std::string m_value{}; }; -Glissando parseGlissando(pugi::xml_node el); - Glissando parseGlissando(pugi::xml_node el, const ParseContext &context); -void parseGlissandoContent(Glissando &out, pugi::xml_node el); - void parseGlissandoContent(Glissando &out, pugi::xml_node el, const ParseContext &context); void serializeGlissando(const Glissando &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Glyph.cpp b/src/private/mx/core/generated/Glyph.cpp index b6d9eb321..f9662bbc2 100644 --- a/src/private/mx/core/generated/Glyph.cpp +++ b/src/private/mx/core/generated/Glyph.cpp @@ -31,11 +31,6 @@ void Glyph::setValue(SmuflGlyphName value) m_value = std::move(value); } -Glyph parseGlyph(pugi::xml_node el) -{ - return parseGlyph(el, ParseContext{}); -} - Glyph parseGlyph(pugi::xml_node el, const ParseContext &context) { Glyph out; @@ -65,11 +60,6 @@ Glyph parseGlyph(pugi::xml_node el, const ParseContext &context) return out; } -void parseGlyphContent(Glyph &out, pugi::xml_node el) -{ - parseGlyphContent(out, el, ParseContext{}); -} - void parseGlyphContent(Glyph &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/Glyph.h b/src/private/mx/core/generated/Glyph.h index bd4de6ee2..0b2d6645e 100644 --- a/src/private/mx/core/generated/Glyph.h +++ b/src/private/mx/core/generated/Glyph.h @@ -39,12 +39,8 @@ class Glyph final SmuflGlyphName m_value{}; }; -Glyph parseGlyph(pugi::xml_node el); - Glyph parseGlyph(pugi::xml_node el, const ParseContext &context); -void parseGlyphContent(Glyph &out, pugi::xml_node el); - void parseGlyphContent(Glyph &out, pugi::xml_node el, const ParseContext &context); void serializeGlyph(const Glyph &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Grace.cpp b/src/private/mx/core/generated/Grace.cpp index 79aec44e8..e256da580 100644 --- a/src/private/mx/core/generated/Grace.cpp +++ b/src/private/mx/core/generated/Grace.cpp @@ -51,11 +51,6 @@ void Grace::setSlash(std::optional value) m_slash = std::move(value); } -Grace parseGrace(pugi::xml_node el) -{ - return parseGrace(el, ParseContext{}); -} - Grace parseGrace(pugi::xml_node el, const ParseContext &context) { Grace out; @@ -91,11 +86,6 @@ Grace parseGrace(pugi::xml_node el, const ParseContext &context) return out; } -void parseGraceContent(Grace &out, pugi::xml_node el) -{ - parseGraceContent(out, el, ParseContext{}); -} - void parseGraceContent(Grace &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/Grace.h b/src/private/mx/core/generated/Grace.h index fad129cd6..ca82e6014 100644 --- a/src/private/mx/core/generated/Grace.h +++ b/src/private/mx/core/generated/Grace.h @@ -45,12 +45,8 @@ class Grace final std::optional m_slash; }; -Grace parseGrace(pugi::xml_node el); - Grace parseGrace(pugi::xml_node el, const ParseContext &context); -void parseGraceContent(Grace &out, pugi::xml_node el); - void parseGraceContent(Grace &out, pugi::xml_node el, const ParseContext &context); void serializeGrace(const Grace &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/GraceCueNoteGroup.cpp b/src/private/mx/core/generated/GraceCueNoteGroup.cpp index 1ed667bd8..0b71339a5 100644 --- a/src/private/mx/core/generated/GraceCueNoteGroup.cpp +++ b/src/private/mx/core/generated/GraceCueNoteGroup.cpp @@ -31,11 +31,6 @@ void GraceCueNoteGroup::setFullNote(FullNoteGroup value) m_fullNote = std::move(value); } -GraceCueNoteGroup parseGraceCueNoteGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseGraceCueNoteGroup(el, cursor, ParseContext{}); -} - GraceCueNoteGroup parseGraceCueNoteGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { GraceCueNoteGroup out; diff --git a/src/private/mx/core/generated/GraceCueNoteGroup.h b/src/private/mx/core/generated/GraceCueNoteGroup.h index 68c269c03..646a84ed2 100644 --- a/src/private/mx/core/generated/GraceCueNoteGroup.h +++ b/src/private/mx/core/generated/GraceCueNoteGroup.h @@ -39,8 +39,6 @@ class GraceCueNoteGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -GraceCueNoteGroup parseGraceCueNoteGroup(pugi::xml_node el, pugi::xml_node &cursor); - GraceCueNoteGroup parseGraceCueNoteGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeGraceCueNoteGroup(const GraceCueNoteGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/GraceNormalNoteGroup.cpp b/src/private/mx/core/generated/GraceNormalNoteGroup.cpp index c9936c544..05a7aa2ac 100644 --- a/src/private/mx/core/generated/GraceNormalNoteGroup.cpp +++ b/src/private/mx/core/generated/GraceNormalNoteGroup.cpp @@ -41,11 +41,6 @@ void GraceNormalNoteGroup::clearTie() noexcept m_tie.clear(); } -GraceNormalNoteGroup parseGraceNormalNoteGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseGraceNormalNoteGroup(el, cursor, ParseContext{}); -} - GraceNormalNoteGroup parseGraceNormalNoteGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { GraceNormalNoteGroup out; diff --git a/src/private/mx/core/generated/GraceNormalNoteGroup.h b/src/private/mx/core/generated/GraceNormalNoteGroup.h index 0bd0758cd..c13d77531 100644 --- a/src/private/mx/core/generated/GraceNormalNoteGroup.h +++ b/src/private/mx/core/generated/GraceNormalNoteGroup.h @@ -43,8 +43,6 @@ class GraceNormalNoteGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -GraceNormalNoteGroup parseGraceNormalNoteGroup(pugi::xml_node el, pugi::xml_node &cursor); - GraceNormalNoteGroup parseGraceNormalNoteGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeGraceNormalNoteGroup(const GraceNormalNoteGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/GraceNoteChoice.cpp b/src/private/mx/core/generated/GraceNoteChoice.cpp index b732a73d7..185b734ce 100644 --- a/src/private/mx/core/generated/GraceNoteChoice.cpp +++ b/src/private/mx/core/generated/GraceNoteChoice.cpp @@ -26,11 +26,6 @@ GraceNoteChoice GraceNoteChoice::graceCueNoteGroup(GraceCueNoteGroup value) return GraceNoteChoice{Storage{std::in_place_index<1>, std::move(value)}}; } -GraceNoteChoice parseGraceNoteChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseGraceNoteChoice(el, cursor, ParseContext{}); -} - GraceNoteChoice parseGraceNoteChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "chord") || cursorIs(cursor, "pitch") || cursorIs(cursor, "unpitched") || diff --git a/src/private/mx/core/generated/GraceNoteChoice.h b/src/private/mx/core/generated/GraceNoteChoice.h index c1dc2ca2e..44bd2381e 100644 --- a/src/private/mx/core/generated/GraceNoteChoice.h +++ b/src/private/mx/core/generated/GraceNoteChoice.h @@ -82,8 +82,6 @@ class GraceNoteChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -GraceNoteChoice parseGraceNoteChoice(pugi::xml_node el, pugi::xml_node &cursor); - GraceNoteChoice parseGraceNoteChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeGraceNoteChoice(const GraceNoteChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/GraceNoteGroup.cpp b/src/private/mx/core/generated/GraceNoteGroup.cpp index 63d50be74..ea7941e75 100644 --- a/src/private/mx/core/generated/GraceNoteGroup.cpp +++ b/src/private/mx/core/generated/GraceNoteGroup.cpp @@ -31,11 +31,6 @@ void GraceNoteGroup::setGraceNoteChoice(GraceNoteChoice value) m_graceNoteChoice = std::move(value); } -GraceNoteGroup parseGraceNoteGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseGraceNoteGroup(el, cursor, ParseContext{}); -} - GraceNoteGroup parseGraceNoteGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { GraceNoteGroup out; diff --git a/src/private/mx/core/generated/GraceNoteGroup.h b/src/private/mx/core/generated/GraceNoteGroup.h index e25562a19..64a802afb 100644 --- a/src/private/mx/core/generated/GraceNoteGroup.h +++ b/src/private/mx/core/generated/GraceNoteGroup.h @@ -39,8 +39,6 @@ class GraceNoteGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -GraceNoteGroup parseGraceNoteGroup(pugi::xml_node el, pugi::xml_node &cursor); - GraceNoteGroup parseGraceNoteGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeGraceNoteGroup(const GraceNoteGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/GroupBarline.cpp b/src/private/mx/core/generated/GroupBarline.cpp index 594f4bdb2..c1b58e3f9 100644 --- a/src/private/mx/core/generated/GroupBarline.cpp +++ b/src/private/mx/core/generated/GroupBarline.cpp @@ -31,11 +31,6 @@ void GroupBarline::setValue(GroupBarlineValue value) m_value = std::move(value); } -GroupBarline parseGroupBarline(pugi::xml_node el) -{ - return parseGroupBarline(el, ParseContext{}); -} - GroupBarline parseGroupBarline(pugi::xml_node el, const ParseContext &context) { GroupBarline out; @@ -59,11 +54,6 @@ GroupBarline parseGroupBarline(pugi::xml_node el, const ParseContext &context) return out; } -void parseGroupBarlineContent(GroupBarline &out, pugi::xml_node el) -{ - parseGroupBarlineContent(out, el, ParseContext{}); -} - void parseGroupBarlineContent(GroupBarline &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/GroupBarline.h b/src/private/mx/core/generated/GroupBarline.h index 0de66b1a5..0d0bfff8f 100644 --- a/src/private/mx/core/generated/GroupBarline.h +++ b/src/private/mx/core/generated/GroupBarline.h @@ -33,12 +33,8 @@ class GroupBarline final GroupBarlineValue m_value{}; }; -GroupBarline parseGroupBarline(pugi::xml_node el); - GroupBarline parseGroupBarline(pugi::xml_node el, const ParseContext &context); -void parseGroupBarlineContent(GroupBarline &out, pugi::xml_node el); - void parseGroupBarlineContent(GroupBarline &out, pugi::xml_node el, const ParseContext &context); void serializeGroupBarline(const GroupBarline &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/GroupName.cpp b/src/private/mx/core/generated/GroupName.cpp index 52ab90753..380d150bc 100644 --- a/src/private/mx/core/generated/GroupName.cpp +++ b/src/private/mx/core/generated/GroupName.cpp @@ -121,11 +121,6 @@ void GroupName::setValue(std::string value) m_value = std::move(value); } -GroupName parseGroupName(pugi::xml_node el) -{ - return parseGroupName(el, ParseContext{}); -} - GroupName parseGroupName(pugi::xml_node el, const ParseContext &context) { GroupName out; @@ -185,11 +180,6 @@ GroupName parseGroupName(pugi::xml_node el, const ParseContext &context) return out; } -void parseGroupNameContent(GroupName &out, pugi::xml_node el) -{ - parseGroupNameContent(out, el, ParseContext{}); -} - void parseGroupNameContent(GroupName &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/GroupName.h b/src/private/mx/core/generated/GroupName.h index ad810daea..8eff5d9cb 100644 --- a/src/private/mx/core/generated/GroupName.h +++ b/src/private/mx/core/generated/GroupName.h @@ -67,12 +67,8 @@ class GroupName final std::string m_value{}; }; -GroupName parseGroupName(pugi::xml_node el); - GroupName parseGroupName(pugi::xml_node el, const ParseContext &context); -void parseGroupNameContent(GroupName &out, pugi::xml_node el); - void parseGroupNameContent(GroupName &out, pugi::xml_node el, const ParseContext &context); void serializeGroupName(const GroupName &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/GroupSymbol.cpp b/src/private/mx/core/generated/GroupSymbol.cpp index b8ec0c6ff..b46d40869 100644 --- a/src/private/mx/core/generated/GroupSymbol.cpp +++ b/src/private/mx/core/generated/GroupSymbol.cpp @@ -71,11 +71,6 @@ void GroupSymbol::setValue(GroupSymbolValue value) m_value = std::move(value); } -GroupSymbol parseGroupSymbol(pugi::xml_node el) -{ - return parseGroupSymbol(el, ParseContext{}); -} - GroupSymbol parseGroupSymbol(pugi::xml_node el, const ParseContext &context) { GroupSymbol out; @@ -115,11 +110,6 @@ GroupSymbol parseGroupSymbol(pugi::xml_node el, const ParseContext &context) return out; } -void parseGroupSymbolContent(GroupSymbol &out, pugi::xml_node el) -{ - parseGroupSymbolContent(out, el, ParseContext{}); -} - void parseGroupSymbolContent(GroupSymbol &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/GroupSymbol.h b/src/private/mx/core/generated/GroupSymbol.h index 0f96d3bd7..f463ddf9c 100644 --- a/src/private/mx/core/generated/GroupSymbol.h +++ b/src/private/mx/core/generated/GroupSymbol.h @@ -47,12 +47,8 @@ class GroupSymbol final GroupSymbolValue m_value{}; }; -GroupSymbol parseGroupSymbol(pugi::xml_node el); - GroupSymbol parseGroupSymbol(pugi::xml_node el, const ParseContext &context); -void parseGroupSymbolContent(GroupSymbol &out, pugi::xml_node el); - void parseGroupSymbolContent(GroupSymbol &out, pugi::xml_node el, const ParseContext &context); void serializeGroupSymbol(const GroupSymbol &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Grouping.cpp b/src/private/mx/core/generated/Grouping.cpp index 02fc4b8ab..ec3c463d5 100644 --- a/src/private/mx/core/generated/Grouping.cpp +++ b/src/private/mx/core/generated/Grouping.cpp @@ -66,11 +66,6 @@ void Grouping::setFeature(std::vector value) m_feature = std::move(value); } -Grouping parseGrouping(pugi::xml_node el) -{ - return parseGrouping(el, ParseContext{}); -} - Grouping parseGrouping(pugi::xml_node el, const ParseContext &context) { Grouping out; @@ -112,11 +107,6 @@ Grouping parseGrouping(pugi::xml_node el, const ParseContext &context) return out; } -void parseGroupingContent(Grouping &out, pugi::xml_node el) -{ - parseGroupingContent(out, el, ParseContext{}); -} - void parseGroupingContent(Grouping &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Grouping.h b/src/private/mx/core/generated/Grouping.h index e77c70ef0..3047801fc 100644 --- a/src/private/mx/core/generated/Grouping.h +++ b/src/private/mx/core/generated/Grouping.h @@ -55,12 +55,8 @@ class Grouping final std::vector m_feature; }; -Grouping parseGrouping(pugi::xml_node el); - Grouping parseGrouping(pugi::xml_node el, const ParseContext &context); -void parseGroupingContent(Grouping &out, pugi::xml_node el); - void parseGroupingContent(Grouping &out, pugi::xml_node el, const ParseContext &context); void serializeGrouping(const Grouping &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/HammerOnPullOff.cpp b/src/private/mx/core/generated/HammerOnPullOff.cpp index d59622745..7b1140880 100644 --- a/src/private/mx/core/generated/HammerOnPullOff.cpp +++ b/src/private/mx/core/generated/HammerOnPullOff.cpp @@ -141,11 +141,6 @@ void HammerOnPullOff::setValue(std::string value) m_value = std::move(value); } -HammerOnPullOff parseHammerOnPullOff(pugi::xml_node el) -{ - return parseHammerOnPullOff(el, ParseContext{}); -} - HammerOnPullOff parseHammerOnPullOff(pugi::xml_node el, const ParseContext &context) { HammerOnPullOff out; @@ -219,11 +214,6 @@ HammerOnPullOff parseHammerOnPullOff(pugi::xml_node el, const ParseContext &cont return out; } -void parseHammerOnPullOffContent(HammerOnPullOff &out, pugi::xml_node el) -{ - parseHammerOnPullOffContent(out, el, ParseContext{}); -} - void parseHammerOnPullOffContent(HammerOnPullOff &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/HammerOnPullOff.h b/src/private/mx/core/generated/HammerOnPullOff.h index 99f0ad5ac..07c304ddf 100644 --- a/src/private/mx/core/generated/HammerOnPullOff.h +++ b/src/private/mx/core/generated/HammerOnPullOff.h @@ -77,12 +77,8 @@ class HammerOnPullOff final std::string m_value{}; }; -HammerOnPullOff parseHammerOnPullOff(pugi::xml_node el); - HammerOnPullOff parseHammerOnPullOff(pugi::xml_node el, const ParseContext &context); -void parseHammerOnPullOffContent(HammerOnPullOff &out, pugi::xml_node el); - void parseHammerOnPullOffContent(HammerOnPullOff &out, pugi::xml_node el, const ParseContext &context); void serializeHammerOnPullOff(const HammerOnPullOff &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Handbell.cpp b/src/private/mx/core/generated/Handbell.cpp index a5ae68b60..43db326c2 100644 --- a/src/private/mx/core/generated/Handbell.cpp +++ b/src/private/mx/core/generated/Handbell.cpp @@ -121,11 +121,6 @@ void Handbell::setValue(HandbellValue value) m_value = std::move(value); } -Handbell parseHandbell(pugi::xml_node el) -{ - return parseHandbell(el, ParseContext{}); -} - Handbell parseHandbell(pugi::xml_node el, const ParseContext &context) { Handbell out; @@ -185,11 +180,6 @@ Handbell parseHandbell(pugi::xml_node el, const ParseContext &context) return out; } -void parseHandbellContent(Handbell &out, pugi::xml_node el) -{ - parseHandbellContent(out, el, ParseContext{}); -} - void parseHandbellContent(Handbell &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/Handbell.h b/src/private/mx/core/generated/Handbell.h index ea21ce2b8..9335b1d80 100644 --- a/src/private/mx/core/generated/Handbell.h +++ b/src/private/mx/core/generated/Handbell.h @@ -67,12 +67,8 @@ class Handbell final HandbellValue m_value{}; }; -Handbell parseHandbell(pugi::xml_node el); - Handbell parseHandbell(pugi::xml_node el, const ParseContext &context); -void parseHandbellContent(Handbell &out, pugi::xml_node el); - void parseHandbellContent(Handbell &out, pugi::xml_node el, const ParseContext &context); void serializeHandbell(const Handbell &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/HarmonClosed.cpp b/src/private/mx/core/generated/HarmonClosed.cpp index 9a3368d59..659e579cf 100644 --- a/src/private/mx/core/generated/HarmonClosed.cpp +++ b/src/private/mx/core/generated/HarmonClosed.cpp @@ -31,11 +31,6 @@ void HarmonClosed::setValue(HarmonClosedValue value) m_value = std::move(value); } -HarmonClosed parseHarmonClosed(pugi::xml_node el) -{ - return parseHarmonClosed(el, ParseContext{}); -} - HarmonClosed parseHarmonClosed(pugi::xml_node el, const ParseContext &context) { HarmonClosed out; @@ -59,11 +54,6 @@ HarmonClosed parseHarmonClosed(pugi::xml_node el, const ParseContext &context) return out; } -void parseHarmonClosedContent(HarmonClosed &out, pugi::xml_node el) -{ - parseHarmonClosedContent(out, el, ParseContext{}); -} - void parseHarmonClosedContent(HarmonClosed &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/HarmonClosed.h b/src/private/mx/core/generated/HarmonClosed.h index 7484989cd..4848383ac 100644 --- a/src/private/mx/core/generated/HarmonClosed.h +++ b/src/private/mx/core/generated/HarmonClosed.h @@ -35,12 +35,8 @@ class HarmonClosed final HarmonClosedValue m_value{}; }; -HarmonClosed parseHarmonClosed(pugi::xml_node el); - HarmonClosed parseHarmonClosed(pugi::xml_node el, const ParseContext &context); -void parseHarmonClosedContent(HarmonClosed &out, pugi::xml_node el); - void parseHarmonClosedContent(HarmonClosed &out, pugi::xml_node el, const ParseContext &context); void serializeHarmonClosed(const HarmonClosed &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/HarmonMute.cpp b/src/private/mx/core/generated/HarmonMute.cpp index 65a1edfe8..c5c1edc4f 100644 --- a/src/private/mx/core/generated/HarmonMute.cpp +++ b/src/private/mx/core/generated/HarmonMute.cpp @@ -121,11 +121,6 @@ void HarmonMute::setHarmonClosed(HarmonClosed value) m_harmonClosed = std::move(value); } -HarmonMute parseHarmonMute(pugi::xml_node el) -{ - return parseHarmonMute(el, ParseContext{}); -} - HarmonMute parseHarmonMute(pugi::xml_node el, const ParseContext &context) { HarmonMute out; @@ -185,11 +180,6 @@ HarmonMute parseHarmonMute(pugi::xml_node el, const ParseContext &context) return out; } -void parseHarmonMuteContent(HarmonMute &out, pugi::xml_node el) -{ - parseHarmonMuteContent(out, el, ParseContext{}); -} - void parseHarmonMuteContent(HarmonMute &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/HarmonMute.h b/src/private/mx/core/generated/HarmonMute.h index fe216ec78..1d9ea1e86 100644 --- a/src/private/mx/core/generated/HarmonMute.h +++ b/src/private/mx/core/generated/HarmonMute.h @@ -70,12 +70,8 @@ class HarmonMute final HarmonClosed m_harmonClosed{}; }; -HarmonMute parseHarmonMute(pugi::xml_node el); - HarmonMute parseHarmonMute(pugi::xml_node el, const ParseContext &context); -void parseHarmonMuteContent(HarmonMute &out, pugi::xml_node el); - void parseHarmonMuteContent(HarmonMute &out, pugi::xml_node el, const ParseContext &context); void serializeHarmonMute(const HarmonMute &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Harmonic.cpp b/src/private/mx/core/generated/Harmonic.cpp index 0d5112d7e..b1a0289ce 100644 --- a/src/private/mx/core/generated/Harmonic.cpp +++ b/src/private/mx/core/generated/Harmonic.cpp @@ -141,11 +141,6 @@ void Harmonic::setChoice2(std::optional value) m_choice2 = std::move(value); } -Harmonic parseHarmonic(pugi::xml_node el) -{ - return parseHarmonic(el, ParseContext{}); -} - Harmonic parseHarmonic(pugi::xml_node el, const ParseContext &context) { Harmonic out; @@ -209,11 +204,6 @@ Harmonic parseHarmonic(pugi::xml_node el, const ParseContext &context) return out; } -void parseHarmonicContent(Harmonic &out, pugi::xml_node el) -{ - parseHarmonicContent(out, el, ParseContext{}); -} - void parseHarmonicContent(Harmonic &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Harmonic.h b/src/private/mx/core/generated/Harmonic.h index 3b750fab0..630f55756 100644 --- a/src/private/mx/core/generated/Harmonic.h +++ b/src/private/mx/core/generated/Harmonic.h @@ -83,12 +83,8 @@ class Harmonic final std::optional m_choice2; }; -Harmonic parseHarmonic(pugi::xml_node el); - Harmonic parseHarmonic(pugi::xml_node el, const ParseContext &context); -void parseHarmonicContent(Harmonic &out, pugi::xml_node el); - void parseHarmonicContent(Harmonic &out, pugi::xml_node el, const ParseContext &context); void serializeHarmonic(const Harmonic &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/HarmonicChoice.cpp b/src/private/mx/core/generated/HarmonicChoice.cpp index fa4a9fab4..4df858688 100644 --- a/src/private/mx/core/generated/HarmonicChoice.cpp +++ b/src/private/mx/core/generated/HarmonicChoice.cpp @@ -26,11 +26,6 @@ HarmonicChoice HarmonicChoice::artificial(Empty value) return HarmonicChoice{Storage{std::in_place_index<1>, std::move(value)}}; } -HarmonicChoice parseHarmonicChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseHarmonicChoice(el, cursor, ParseContext{}); -} - HarmonicChoice parseHarmonicChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "natural"))) diff --git a/src/private/mx/core/generated/HarmonicChoice.h b/src/private/mx/core/generated/HarmonicChoice.h index e6290374f..7250cc369 100644 --- a/src/private/mx/core/generated/HarmonicChoice.h +++ b/src/private/mx/core/generated/HarmonicChoice.h @@ -81,8 +81,6 @@ class HarmonicChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -HarmonicChoice parseHarmonicChoice(pugi::xml_node el, pugi::xml_node &cursor); - HarmonicChoice parseHarmonicChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeHarmonicChoice(const HarmonicChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/HarmonicChoice2.cpp b/src/private/mx/core/generated/HarmonicChoice2.cpp index 61dbca832..12e7ca443 100644 --- a/src/private/mx/core/generated/HarmonicChoice2.cpp +++ b/src/private/mx/core/generated/HarmonicChoice2.cpp @@ -31,11 +31,6 @@ HarmonicChoice2 HarmonicChoice2::soundingPitch(Empty value) return HarmonicChoice2{Storage{std::in_place_index<2>, std::move(value)}}; } -HarmonicChoice2 parseHarmonicChoice2(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseHarmonicChoice2(el, cursor, ParseContext{}); -} - HarmonicChoice2 parseHarmonicChoice2(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "base-pitch"))) diff --git a/src/private/mx/core/generated/HarmonicChoice2.h b/src/private/mx/core/generated/HarmonicChoice2.h index 3f37e3484..0faba368d 100644 --- a/src/private/mx/core/generated/HarmonicChoice2.h +++ b/src/private/mx/core/generated/HarmonicChoice2.h @@ -95,8 +95,6 @@ class HarmonicChoice2 final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -HarmonicChoice2 parseHarmonicChoice2(pugi::xml_node el, pugi::xml_node &cursor); - HarmonicChoice2 parseHarmonicChoice2(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeHarmonicChoice2(const HarmonicChoice2 &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Harmony.cpp b/src/private/mx/core/generated/Harmony.cpp index 0045514dd..af4b9ad3f 100644 --- a/src/private/mx/core/generated/Harmony.cpp +++ b/src/private/mx/core/generated/Harmony.cpp @@ -226,11 +226,6 @@ void Harmony::setStaff(std::optional value) m_staff = std::move(value); } -Harmony parseHarmony(pugi::xml_node el) -{ - return parseHarmony(el, ParseContext{}); -} - Harmony parseHarmony(pugi::xml_node el, const ParseContext &context) { Harmony out; @@ -314,11 +309,6 @@ Harmony parseHarmony(pugi::xml_node el, const ParseContext &context) return out; } -void parseHarmonyContent(Harmony &out, pugi::xml_node el) -{ - parseHarmonyContent(out, el, ParseContext{}); -} - void parseHarmonyContent(Harmony &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Harmony.h b/src/private/mx/core/generated/Harmony.h index 6645f3b14..abc4862f6 100644 --- a/src/private/mx/core/generated/Harmony.h +++ b/src/private/mx/core/generated/Harmony.h @@ -121,12 +121,8 @@ class Harmony final std::optional m_staff; }; -Harmony parseHarmony(pugi::xml_node el); - Harmony parseHarmony(pugi::xml_node el, const ParseContext &context); -void parseHarmonyContent(Harmony &out, pugi::xml_node el); - void parseHarmonyContent(Harmony &out, pugi::xml_node el, const ParseContext &context); void serializeHarmony(const Harmony &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/HarmonyAlter.cpp b/src/private/mx/core/generated/HarmonyAlter.cpp index 9180f65d9..aa08b5f59 100644 --- a/src/private/mx/core/generated/HarmonyAlter.cpp +++ b/src/private/mx/core/generated/HarmonyAlter.cpp @@ -131,11 +131,6 @@ void HarmonyAlter::setValue(Semitones value) m_value = std::move(value); } -HarmonyAlter parseHarmonyAlter(pugi::xml_node el) -{ - return parseHarmonyAlter(el, ParseContext{}); -} - HarmonyAlter parseHarmonyAlter(pugi::xml_node el, const ParseContext &context) { HarmonyAlter out; @@ -199,11 +194,6 @@ HarmonyAlter parseHarmonyAlter(pugi::xml_node el, const ParseContext &context) return out; } -void parseHarmonyAlterContent(HarmonyAlter &out, pugi::xml_node el) -{ - parseHarmonyAlterContent(out, el, ParseContext{}); -} - void parseHarmonyAlterContent(HarmonyAlter &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/HarmonyAlter.h b/src/private/mx/core/generated/HarmonyAlter.h index 520be4cfc..09ca22c09 100644 --- a/src/private/mx/core/generated/HarmonyAlter.h +++ b/src/private/mx/core/generated/HarmonyAlter.h @@ -74,12 +74,8 @@ class HarmonyAlter final Semitones m_value{}; }; -HarmonyAlter parseHarmonyAlter(pugi::xml_node el); - HarmonyAlter parseHarmonyAlter(pugi::xml_node el, const ParseContext &context); -void parseHarmonyAlterContent(HarmonyAlter &out, pugi::xml_node el); - void parseHarmonyAlterContent(HarmonyAlter &out, pugi::xml_node el, const ParseContext &context); void serializeHarmonyAlter(const HarmonyAlter &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/HarmonyChordGroup.cpp b/src/private/mx/core/generated/HarmonyChordGroup.cpp index f7c583f9b..a945865f6 100644 --- a/src/private/mx/core/generated/HarmonyChordGroup.cpp +++ b/src/private/mx/core/generated/HarmonyChordGroup.cpp @@ -66,11 +66,6 @@ void HarmonyChordGroup::setDegree(std::vector value) m_degree = std::move(value); } -HarmonyChordGroup parseHarmonyChordGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseHarmonyChordGroup(el, cursor, ParseContext{}); -} - HarmonyChordGroup parseHarmonyChordGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { HarmonyChordGroup out; diff --git a/src/private/mx/core/generated/HarmonyChordGroup.h b/src/private/mx/core/generated/HarmonyChordGroup.h index 551b8a8e1..18c2fa33b 100644 --- a/src/private/mx/core/generated/HarmonyChordGroup.h +++ b/src/private/mx/core/generated/HarmonyChordGroup.h @@ -59,8 +59,6 @@ class HarmonyChordGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -HarmonyChordGroup parseHarmonyChordGroup(pugi::xml_node el, pugi::xml_node &cursor); - HarmonyChordGroup parseHarmonyChordGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeHarmonyChordGroup(const HarmonyChordGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/HarmonyChordGroupChoice.cpp b/src/private/mx/core/generated/HarmonyChordGroupChoice.cpp index 9503cd5c8..2a5030c64 100644 --- a/src/private/mx/core/generated/HarmonyChordGroupChoice.cpp +++ b/src/private/mx/core/generated/HarmonyChordGroupChoice.cpp @@ -31,11 +31,6 @@ HarmonyChordGroupChoice HarmonyChordGroupChoice::function(StyleText value) return HarmonyChordGroupChoice{Storage{std::in_place_index<2>, std::move(value)}}; } -HarmonyChordGroupChoice parseHarmonyChordGroupChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseHarmonyChordGroupChoice(el, cursor, ParseContext{}); -} - HarmonyChordGroupChoice parseHarmonyChordGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { diff --git a/src/private/mx/core/generated/HarmonyChordGroupChoice.h b/src/private/mx/core/generated/HarmonyChordGroupChoice.h index 98821d09e..60ce4b004 100644 --- a/src/private/mx/core/generated/HarmonyChordGroupChoice.h +++ b/src/private/mx/core/generated/HarmonyChordGroupChoice.h @@ -97,8 +97,6 @@ class HarmonyChordGroupChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -HarmonyChordGroupChoice parseHarmonyChordGroupChoice(pugi::xml_node el, pugi::xml_node &cursor); - HarmonyChordGroupChoice parseHarmonyChordGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); diff --git a/src/private/mx/core/generated/HarpPedals.cpp b/src/private/mx/core/generated/HarpPedals.cpp index 762df8f29..22d6c8d39 100644 --- a/src/private/mx/core/generated/HarpPedals.cpp +++ b/src/private/mx/core/generated/HarpPedals.cpp @@ -146,11 +146,6 @@ void HarpPedals::setPedalTuning(OneOrMore value) m_pedalTuning = std::move(value); } -HarpPedals parseHarpPedals(pugi::xml_node el) -{ - return parseHarpPedals(el, ParseContext{}); -} - HarpPedals parseHarpPedals(pugi::xml_node el, const ParseContext &context) { HarpPedals out; @@ -218,11 +213,6 @@ HarpPedals parseHarpPedals(pugi::xml_node el, const ParseContext &context) return out; } -void parseHarpPedalsContent(HarpPedals &out, pugi::xml_node el) -{ - parseHarpPedalsContent(out, el, ParseContext{}); -} - void parseHarpPedalsContent(HarpPedals &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/HarpPedals.h b/src/private/mx/core/generated/HarpPedals.h index c4ba49421..59d65e917 100644 --- a/src/private/mx/core/generated/HarpPedals.h +++ b/src/private/mx/core/generated/HarpPedals.h @@ -84,12 +84,8 @@ class HarpPedals final OneOrMore m_pedalTuning; }; -HarpPedals parseHarpPedals(pugi::xml_node el); - HarpPedals parseHarpPedals(pugi::xml_node el, const ParseContext &context); -void parseHarpPedalsContent(HarpPedals &out, pugi::xml_node el); - void parseHarpPedalsContent(HarpPedals &out, pugi::xml_node el, const ParseContext &context); void serializeHarpPedals(const HarpPedals &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/HeelToe.cpp b/src/private/mx/core/generated/HeelToe.cpp index 79f4c1239..be2966f68 100644 --- a/src/private/mx/core/generated/HeelToe.cpp +++ b/src/private/mx/core/generated/HeelToe.cpp @@ -21,11 +21,6 @@ void HeelToe::setSubstitution(std::optional value) m_substitution = std::move(value); } -HeelToe parseHeelToe(pugi::xml_node el) -{ - return parseHeelToe(el, ParseContext{}); -} - HeelToe parseHeelToe(pugi::xml_node el, const ParseContext &context) { HeelToe out; diff --git a/src/private/mx/core/generated/HeelToe.h b/src/private/mx/core/generated/HeelToe.h index ae38618dc..c2325488c 100644 --- a/src/private/mx/core/generated/HeelToe.h +++ b/src/private/mx/core/generated/HeelToe.h @@ -33,8 +33,6 @@ class HeelToe : public EmptyPlacement std::optional m_substitution; }; -HeelToe parseHeelToe(pugi::xml_node el); - HeelToe parseHeelToe(pugi::xml_node el, const ParseContext &context); void serializeHeelToe(const HeelToe &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Hole.cpp b/src/private/mx/core/generated/Hole.cpp index 6fa4fe15a..927c3d9ef 100644 --- a/src/private/mx/core/generated/Hole.cpp +++ b/src/private/mx/core/generated/Hole.cpp @@ -141,11 +141,6 @@ void Hole::setHoleShape(std::optional value) m_holeShape = std::move(value); } -Hole parseHole(pugi::xml_node el) -{ - return parseHole(el, ParseContext{}); -} - Hole parseHole(pugi::xml_node el, const ParseContext &context) { Hole out; @@ -205,11 +200,6 @@ Hole parseHole(pugi::xml_node el, const ParseContext &context) return out; } -void parseHoleContent(Hole &out, pugi::xml_node el) -{ - parseHoleContent(out, el, ParseContext{}); -} - void parseHoleContent(Hole &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Hole.h b/src/private/mx/core/generated/Hole.h index 748bafc73..61d103c28 100644 --- a/src/private/mx/core/generated/Hole.h +++ b/src/private/mx/core/generated/Hole.h @@ -77,12 +77,8 @@ class Hole final std::optional m_holeShape; }; -Hole parseHole(pugi::xml_node el); - Hole parseHole(pugi::xml_node el, const ParseContext &context); -void parseHoleContent(Hole &out, pugi::xml_node el); - void parseHoleContent(Hole &out, pugi::xml_node el, const ParseContext &context); void serializeHole(const Hole &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/HoleClosed.cpp b/src/private/mx/core/generated/HoleClosed.cpp index 9d0a73ed4..ffd0de243 100644 --- a/src/private/mx/core/generated/HoleClosed.cpp +++ b/src/private/mx/core/generated/HoleClosed.cpp @@ -31,11 +31,6 @@ void HoleClosed::setValue(HoleClosedValue value) m_value = std::move(value); } -HoleClosed parseHoleClosed(pugi::xml_node el) -{ - return parseHoleClosed(el, ParseContext{}); -} - HoleClosed parseHoleClosed(pugi::xml_node el, const ParseContext &context) { HoleClosed out; @@ -59,11 +54,6 @@ HoleClosed parseHoleClosed(pugi::xml_node el, const ParseContext &context) return out; } -void parseHoleClosedContent(HoleClosed &out, pugi::xml_node el) -{ - parseHoleClosedContent(out, el, ParseContext{}); -} - void parseHoleClosedContent(HoleClosed &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/HoleClosed.h b/src/private/mx/core/generated/HoleClosed.h index a57301ea2..ae9fac286 100644 --- a/src/private/mx/core/generated/HoleClosed.h +++ b/src/private/mx/core/generated/HoleClosed.h @@ -35,12 +35,8 @@ class HoleClosed final HoleClosedValue m_value{}; }; -HoleClosed parseHoleClosed(pugi::xml_node el); - HoleClosed parseHoleClosed(pugi::xml_node el, const ParseContext &context); -void parseHoleClosedContent(HoleClosed &out, pugi::xml_node el); - void parseHoleClosedContent(HoleClosed &out, pugi::xml_node el, const ParseContext &context); void serializeHoleClosed(const HoleClosed &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/HorizontalTurn.cpp b/src/private/mx/core/generated/HorizontalTurn.cpp index 806d467ab..e9347b14c 100644 --- a/src/private/mx/core/generated/HorizontalTurn.cpp +++ b/src/private/mx/core/generated/HorizontalTurn.cpp @@ -191,11 +191,6 @@ void HorizontalTurn::setLastBeat(std::optional value) m_lastBeat = std::move(value); } -HorizontalTurn parseHorizontalTurn(pugi::xml_node el) -{ - return parseHorizontalTurn(el, ParseContext{}); -} - HorizontalTurn parseHorizontalTurn(pugi::xml_node el, const ParseContext &context) { HorizontalTurn out; @@ -287,11 +282,6 @@ HorizontalTurn parseHorizontalTurn(pugi::xml_node el, const ParseContext &contex return out; } -void parseHorizontalTurnContent(HorizontalTurn &out, pugi::xml_node el) -{ - parseHorizontalTurnContent(out, el, ParseContext{}); -} - void parseHorizontalTurnContent(HorizontalTurn &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/HorizontalTurn.h b/src/private/mx/core/generated/HorizontalTurn.h index 0cf5ec7a7..ccb35817e 100644 --- a/src/private/mx/core/generated/HorizontalTurn.h +++ b/src/private/mx/core/generated/HorizontalTurn.h @@ -94,12 +94,8 @@ class HorizontalTurn final std::optional m_lastBeat; }; -HorizontalTurn parseHorizontalTurn(pugi::xml_node el); - HorizontalTurn parseHorizontalTurn(pugi::xml_node el, const ParseContext &context); -void parseHorizontalTurnContent(HorizontalTurn &out, pugi::xml_node el); - void parseHorizontalTurnContent(HorizontalTurn &out, pugi::xml_node el, const ParseContext &context); void serializeHorizontalTurn(const HorizontalTurn &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Identification.cpp b/src/private/mx/core/generated/Identification.cpp index ee1de1bc2..c67ea3602 100644 --- a/src/private/mx/core/generated/Identification.cpp +++ b/src/private/mx/core/generated/Identification.cpp @@ -86,11 +86,6 @@ void Identification::setMiscellaneous(std::optional value) m_miscellaneous = std::move(value); } -Identification parseIdentification(pugi::xml_node el) -{ - return parseIdentification(el, ParseContext{}); -} - Identification parseIdentification(pugi::xml_node el, const ParseContext &context) { Identification out; @@ -107,11 +102,6 @@ Identification parseIdentification(pugi::xml_node el, const ParseContext &contex return out; } -void parseIdentificationContent(Identification &out, pugi::xml_node el) -{ - parseIdentificationContent(out, el, ParseContext{}); -} - void parseIdentificationContent(Identification &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Identification.h b/src/private/mx/core/generated/Identification.h index e8641dd2e..1ce7bcbe7 100644 --- a/src/private/mx/core/generated/Identification.h +++ b/src/private/mx/core/generated/Identification.h @@ -55,12 +55,8 @@ class Identification final std::optional m_miscellaneous; }; -Identification parseIdentification(pugi::xml_node el); - Identification parseIdentification(pugi::xml_node el, const ParseContext &context); -void parseIdentificationContent(Identification &out, pugi::xml_node el); - void parseIdentificationContent(Identification &out, pugi::xml_node el, const ParseContext &context); void serializeIdentification(const Identification &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Image.cpp b/src/private/mx/core/generated/Image.cpp index bff3c5ea7..1bfd99f57 100644 --- a/src/private/mx/core/generated/Image.cpp +++ b/src/private/mx/core/generated/Image.cpp @@ -121,11 +121,6 @@ void Image::setID(std::optional value) m_id = std::move(value); } -Image parseImage(pugi::xml_node el) -{ - return parseImage(el, ParseContext{}); -} - Image parseImage(pugi::xml_node el, const ParseContext &context) { Image out; @@ -201,11 +196,6 @@ Image parseImage(pugi::xml_node el, const ParseContext &context) return out; } -void parseImageContent(Image &out, pugi::xml_node el) -{ - parseImageContent(out, el, ParseContext{}); -} - void parseImageContent(Image &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/Image.h b/src/private/mx/core/generated/Image.h index 7f8bf17c7..ee6d1a7bb 100644 --- a/src/private/mx/core/generated/Image.h +++ b/src/private/mx/core/generated/Image.h @@ -63,12 +63,8 @@ class Image final std::optional m_id; }; -Image parseImage(pugi::xml_node el); - Image parseImage(pugi::xml_node el, const ParseContext &context); -void parseImageContent(Image &out, pugi::xml_node el); - void parseImageContent(Image &out, pugi::xml_node el, const ParseContext &context); void serializeImage(const Image &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Instrument.cpp b/src/private/mx/core/generated/Instrument.cpp index f41526d23..dab2810e8 100644 --- a/src/private/mx/core/generated/Instrument.cpp +++ b/src/private/mx/core/generated/Instrument.cpp @@ -21,11 +21,6 @@ void Instrument::setID(Token value) m_id = std::move(value); } -Instrument parseInstrument(pugi::xml_node el) -{ - return parseInstrument(el, ParseContext{}); -} - Instrument parseInstrument(pugi::xml_node el, const ParseContext &context) { Instrument out; @@ -55,11 +50,6 @@ Instrument parseInstrument(pugi::xml_node el, const ParseContext &context) return out; } -void parseInstrumentContent(Instrument &out, pugi::xml_node el) -{ - parseInstrumentContent(out, el, ParseContext{}); -} - void parseInstrumentContent(Instrument &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/Instrument.h b/src/private/mx/core/generated/Instrument.h index 3d9d8734e..3b5d0a12b 100644 --- a/src/private/mx/core/generated/Instrument.h +++ b/src/private/mx/core/generated/Instrument.h @@ -33,12 +33,8 @@ class Instrument final Token m_id{}; }; -Instrument parseInstrument(pugi::xml_node el); - Instrument parseInstrument(pugi::xml_node el, const ParseContext &context); -void parseInstrumentContent(Instrument &out, pugi::xml_node el); - void parseInstrumentContent(Instrument &out, pugi::xml_node el, const ParseContext &context); void serializeInstrument(const Instrument &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/InstrumentChange.cpp b/src/private/mx/core/generated/InstrumentChange.cpp index 811d477ce..c1d31768f 100644 --- a/src/private/mx/core/generated/InstrumentChange.cpp +++ b/src/private/mx/core/generated/InstrumentChange.cpp @@ -31,11 +31,6 @@ void InstrumentChange::setVirtualInstrumentData(VirtualInstrumentDataGroup value m_virtualInstrumentData = std::move(value); } -InstrumentChange parseInstrumentChange(pugi::xml_node el) -{ - return parseInstrumentChange(el, ParseContext{}); -} - InstrumentChange parseInstrumentChange(pugi::xml_node el, const ParseContext &context) { InstrumentChange out; @@ -65,11 +60,6 @@ InstrumentChange parseInstrumentChange(pugi::xml_node el, const ParseContext &co return out; } -void parseInstrumentChangeContent(InstrumentChange &out, pugi::xml_node el) -{ - parseInstrumentChangeContent(out, el, ParseContext{}); -} - void parseInstrumentChangeContent(InstrumentChange &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/InstrumentChange.h b/src/private/mx/core/generated/InstrumentChange.h index 3b1b584bf..557001783 100644 --- a/src/private/mx/core/generated/InstrumentChange.h +++ b/src/private/mx/core/generated/InstrumentChange.h @@ -41,12 +41,8 @@ class InstrumentChange final VirtualInstrumentDataGroup m_virtualInstrumentData{}; }; -InstrumentChange parseInstrumentChange(pugi::xml_node el); - InstrumentChange parseInstrumentChange(pugi::xml_node el, const ParseContext &context); -void parseInstrumentChangeContent(InstrumentChange &out, pugi::xml_node el); - void parseInstrumentChangeContent(InstrumentChange &out, pugi::xml_node el, const ParseContext &context); void serializeInstrumentChange(const InstrumentChange &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/InstrumentLink.cpp b/src/private/mx/core/generated/InstrumentLink.cpp index dc6d61e6d..27c22f038 100644 --- a/src/private/mx/core/generated/InstrumentLink.cpp +++ b/src/private/mx/core/generated/InstrumentLink.cpp @@ -21,11 +21,6 @@ void InstrumentLink::setID(Token value) m_id = std::move(value); } -InstrumentLink parseInstrumentLink(pugi::xml_node el) -{ - return parseInstrumentLink(el, ParseContext{}); -} - InstrumentLink parseInstrumentLink(pugi::xml_node el, const ParseContext &context) { InstrumentLink out; @@ -55,11 +50,6 @@ InstrumentLink parseInstrumentLink(pugi::xml_node el, const ParseContext &contex return out; } -void parseInstrumentLinkContent(InstrumentLink &out, pugi::xml_node el) -{ - parseInstrumentLinkContent(out, el, ParseContext{}); -} - void parseInstrumentLinkContent(InstrumentLink &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/InstrumentLink.h b/src/private/mx/core/generated/InstrumentLink.h index a7160b7e4..d2ffa29af 100644 --- a/src/private/mx/core/generated/InstrumentLink.h +++ b/src/private/mx/core/generated/InstrumentLink.h @@ -34,12 +34,8 @@ class InstrumentLink final Token m_id{}; }; -InstrumentLink parseInstrumentLink(pugi::xml_node el); - InstrumentLink parseInstrumentLink(pugi::xml_node el, const ParseContext &context); -void parseInstrumentLinkContent(InstrumentLink &out, pugi::xml_node el); - void parseInstrumentLinkContent(InstrumentLink &out, pugi::xml_node el, const ParseContext &context); void serializeInstrumentLink(const InstrumentLink &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Interchangeable.cpp b/src/private/mx/core/generated/Interchangeable.cpp index 145dcab28..88dea540e 100644 --- a/src/private/mx/core/generated/Interchangeable.cpp +++ b/src/private/mx/core/generated/Interchangeable.cpp @@ -56,11 +56,6 @@ void Interchangeable::setTimeSignature(OneOrMore value) m_timeSignature = std::move(value); } -Interchangeable parseInterchangeable(pugi::xml_node el) -{ - return parseInterchangeable(el, ParseContext{}); -} - Interchangeable parseInterchangeable(pugi::xml_node el, const ParseContext &context) { Interchangeable out; @@ -88,11 +83,6 @@ Interchangeable parseInterchangeable(pugi::xml_node el, const ParseContext &cont return out; } -void parseInterchangeableContent(Interchangeable &out, pugi::xml_node el) -{ - parseInterchangeableContent(out, el, ParseContext{}); -} - void parseInterchangeableContent(Interchangeable &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Interchangeable.h b/src/private/mx/core/generated/Interchangeable.h index f3313c9d0..db98ca10e 100644 --- a/src/private/mx/core/generated/Interchangeable.h +++ b/src/private/mx/core/generated/Interchangeable.h @@ -49,12 +49,8 @@ class Interchangeable final OneOrMore m_timeSignature; }; -Interchangeable parseInterchangeable(pugi::xml_node el); - Interchangeable parseInterchangeable(pugi::xml_node el, const ParseContext &context); -void parseInterchangeableContent(Interchangeable &out, pugi::xml_node el); - void parseInterchangeableContent(Interchangeable &out, pugi::xml_node el, const ParseContext &context); void serializeInterchangeable(const Interchangeable &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Inversion.cpp b/src/private/mx/core/generated/Inversion.cpp index dce0b9a7d..cb6d98f09 100644 --- a/src/private/mx/core/generated/Inversion.cpp +++ b/src/private/mx/core/generated/Inversion.cpp @@ -121,11 +121,6 @@ void Inversion::setValue(int value) m_value = std::move(value); } -Inversion parseInversion(pugi::xml_node el) -{ - return parseInversion(el, ParseContext{}); -} - Inversion parseInversion(pugi::xml_node el, const ParseContext &context) { Inversion out; @@ -185,11 +180,6 @@ Inversion parseInversion(pugi::xml_node el, const ParseContext &context) return out; } -void parseInversionContent(Inversion &out, pugi::xml_node el) -{ - parseInversionContent(out, el, ParseContext{}); -} - void parseInversionContent(Inversion &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseIntegerValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/Inversion.h b/src/private/mx/core/generated/Inversion.h index 70cdc599d..f6333b3c4 100644 --- a/src/private/mx/core/generated/Inversion.h +++ b/src/private/mx/core/generated/Inversion.h @@ -66,12 +66,8 @@ class Inversion final int m_value{}; }; -Inversion parseInversion(pugi::xml_node el); - Inversion parseInversion(pugi::xml_node el, const ParseContext &context); -void parseInversionContent(Inversion &out, pugi::xml_node el); - void parseInversionContent(Inversion &out, pugi::xml_node el, const ParseContext &context); void serializeInversion(const Inversion &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Key.cpp b/src/private/mx/core/generated/Key.cpp index da1cacb50..12eee0737 100644 --- a/src/private/mx/core/generated/Key.cpp +++ b/src/private/mx/core/generated/Key.cpp @@ -156,11 +156,6 @@ void Key::setKeyOctave(std::vector value) m_keyOctave = std::move(value); } -Key parseKey(pugi::xml_node el) -{ - return parseKey(el, ParseContext{}); -} - Key parseKey(pugi::xml_node el, const ParseContext &context) { Key out; @@ -228,11 +223,6 @@ Key parseKey(pugi::xml_node el, const ParseContext &context) return out; } -void parseKeyContent(Key &out, pugi::xml_node el) -{ - parseKeyContent(out, el, ParseContext{}); -} - void parseKeyContent(Key &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Key.h b/src/private/mx/core/generated/Key.h index 13741805e..40ec9f6ed 100644 --- a/src/private/mx/core/generated/Key.h +++ b/src/private/mx/core/generated/Key.h @@ -87,12 +87,8 @@ class Key final std::vector m_keyOctave; }; -Key parseKey(pugi::xml_node el); - Key parseKey(pugi::xml_node el, const ParseContext &context); -void parseKeyContent(Key &out, pugi::xml_node el); - void parseKeyContent(Key &out, pugi::xml_node el, const ParseContext &context); void serializeKey(const Key &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/KeyAccidental.cpp b/src/private/mx/core/generated/KeyAccidental.cpp index e1661a6ee..0d7a228d5 100644 --- a/src/private/mx/core/generated/KeyAccidental.cpp +++ b/src/private/mx/core/generated/KeyAccidental.cpp @@ -31,11 +31,6 @@ void KeyAccidental::setValue(AccidentalValue value) m_value = std::move(value); } -KeyAccidental parseKeyAccidental(pugi::xml_node el) -{ - return parseKeyAccidental(el, ParseContext{}); -} - KeyAccidental parseKeyAccidental(pugi::xml_node el, const ParseContext &context) { KeyAccidental out; @@ -59,11 +54,6 @@ KeyAccidental parseKeyAccidental(pugi::xml_node el, const ParseContext &context) return out; } -void parseKeyAccidentalContent(KeyAccidental &out, pugi::xml_node el) -{ - parseKeyAccidentalContent(out, el, ParseContext{}); -} - void parseKeyAccidentalContent(KeyAccidental &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/KeyAccidental.h b/src/private/mx/core/generated/KeyAccidental.h index aa17976fa..65837f9d0 100644 --- a/src/private/mx/core/generated/KeyAccidental.h +++ b/src/private/mx/core/generated/KeyAccidental.h @@ -35,12 +35,8 @@ class KeyAccidental final AccidentalValue m_value{}; }; -KeyAccidental parseKeyAccidental(pugi::xml_node el); - KeyAccidental parseKeyAccidental(pugi::xml_node el, const ParseContext &context); -void parseKeyAccidentalContent(KeyAccidental &out, pugi::xml_node el); - void parseKeyAccidentalContent(KeyAccidental &out, pugi::xml_node el, const ParseContext &context); void serializeKeyAccidental(const KeyAccidental &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/KeyChoice.cpp b/src/private/mx/core/generated/KeyChoice.cpp index 936e88e16..9c156c9ab 100644 --- a/src/private/mx/core/generated/KeyChoice.cpp +++ b/src/private/mx/core/generated/KeyChoice.cpp @@ -26,11 +26,6 @@ KeyChoice KeyChoice::nonTraditionalKey(std::vector value return KeyChoice{Storage{std::in_place_index<1>, std::move(value)}}; } -KeyChoice parseKeyChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseKeyChoice(el, cursor, ParseContext{}); -} - KeyChoice parseKeyChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "cancel") || cursorIs(cursor, "fifths"))) diff --git a/src/private/mx/core/generated/KeyChoice.h b/src/private/mx/core/generated/KeyChoice.h index 6aba2d631..9f9a63e71 100644 --- a/src/private/mx/core/generated/KeyChoice.h +++ b/src/private/mx/core/generated/KeyChoice.h @@ -83,8 +83,6 @@ class KeyChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -KeyChoice parseKeyChoice(pugi::xml_node el, pugi::xml_node &cursor); - KeyChoice parseKeyChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeKeyChoice(const KeyChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/KeyOctave.cpp b/src/private/mx/core/generated/KeyOctave.cpp index e6dee9bc5..9d66fbf59 100644 --- a/src/private/mx/core/generated/KeyOctave.cpp +++ b/src/private/mx/core/generated/KeyOctave.cpp @@ -41,11 +41,6 @@ void KeyOctave::setValue(Octave value) m_value = std::move(value); } -KeyOctave parseKeyOctave(pugi::xml_node el) -{ - return parseKeyOctave(el, ParseContext{}); -} - KeyOctave parseKeyOctave(pugi::xml_node el, const ParseContext &context) { KeyOctave out; @@ -79,11 +74,6 @@ KeyOctave parseKeyOctave(pugi::xml_node el, const ParseContext &context) return out; } -void parseKeyOctaveContent(KeyOctave &out, pugi::xml_node el) -{ - parseKeyOctaveContent(out, el, ParseContext{}); -} - void parseKeyOctaveContent(KeyOctave &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/KeyOctave.h b/src/private/mx/core/generated/KeyOctave.h index de9f09228..0c6f2d111 100644 --- a/src/private/mx/core/generated/KeyOctave.h +++ b/src/private/mx/core/generated/KeyOctave.h @@ -42,12 +42,8 @@ class KeyOctave final Octave m_value{}; }; -KeyOctave parseKeyOctave(pugi::xml_node el); - KeyOctave parseKeyOctave(pugi::xml_node el, const ParseContext &context); -void parseKeyOctaveContent(KeyOctave &out, pugi::xml_node el); - void parseKeyOctaveContent(KeyOctave &out, pugi::xml_node el, const ParseContext &context); void serializeKeyOctave(const KeyOctave &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Kind.cpp b/src/private/mx/core/generated/Kind.cpp index d88f42614..47e3eec07 100644 --- a/src/private/mx/core/generated/Kind.cpp +++ b/src/private/mx/core/generated/Kind.cpp @@ -181,11 +181,6 @@ void Kind::setValue(KindValue value) m_value = std::move(value); } -Kind parseKind(pugi::xml_node el) -{ - return parseKind(el, ParseContext{}); -} - Kind parseKind(pugi::xml_node el, const ParseContext &context) { Kind out; @@ -269,11 +264,6 @@ Kind parseKind(pugi::xml_node el, const ParseContext &context) return out; } -void parseKindContent(Kind &out, pugi::xml_node el) -{ - parseKindContent(out, el, ParseContext{}); -} - void parseKindContent(Kind &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/Kind.h b/src/private/mx/core/generated/Kind.h index e54ecbf0d..c598a03fc 100644 --- a/src/private/mx/core/generated/Kind.h +++ b/src/private/mx/core/generated/Kind.h @@ -104,12 +104,8 @@ class Kind final KindValue m_value{}; }; -Kind parseKind(pugi::xml_node el); - Kind parseKind(pugi::xml_node el, const ParseContext &context); -void parseKindContent(Kind &out, pugi::xml_node el); - void parseKindContent(Kind &out, pugi::xml_node el, const ParseContext &context); void serializeKind(const Kind &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/LayoutGroup.cpp b/src/private/mx/core/generated/LayoutGroup.cpp index a66e483aa..b230ed9b1 100644 --- a/src/private/mx/core/generated/LayoutGroup.cpp +++ b/src/private/mx/core/generated/LayoutGroup.cpp @@ -46,11 +46,6 @@ void LayoutGroup::setStaffLayout(std::vector value) m_staffLayout = std::move(value); } -LayoutGroup parseLayoutGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseLayoutGroup(el, cursor, ParseContext{}); -} - LayoutGroup parseLayoutGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { LayoutGroup out; diff --git a/src/private/mx/core/generated/LayoutGroup.h b/src/private/mx/core/generated/LayoutGroup.h index 01f6d7123..f616dbbac 100644 --- a/src/private/mx/core/generated/LayoutGroup.h +++ b/src/private/mx/core/generated/LayoutGroup.h @@ -45,8 +45,6 @@ class LayoutGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -LayoutGroup parseLayoutGroup(pugi::xml_node el, pugi::xml_node &cursor); - LayoutGroup parseLayoutGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeLayoutGroup(const LayoutGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/LeftRightMarginsGroup.cpp b/src/private/mx/core/generated/LeftRightMarginsGroup.cpp index 9d3f7d624..dac357df2 100644 --- a/src/private/mx/core/generated/LeftRightMarginsGroup.cpp +++ b/src/private/mx/core/generated/LeftRightMarginsGroup.cpp @@ -31,11 +31,6 @@ void LeftRightMarginsGroup::setRightMargin(Tenths value) m_rightMargin = std::move(value); } -LeftRightMarginsGroup parseLeftRightMarginsGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseLeftRightMarginsGroup(el, cursor, ParseContext{}); -} - LeftRightMarginsGroup parseLeftRightMarginsGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { LeftRightMarginsGroup out; diff --git a/src/private/mx/core/generated/LeftRightMarginsGroup.h b/src/private/mx/core/generated/LeftRightMarginsGroup.h index f54462f3f..63a222b95 100644 --- a/src/private/mx/core/generated/LeftRightMarginsGroup.h +++ b/src/private/mx/core/generated/LeftRightMarginsGroup.h @@ -38,8 +38,6 @@ class LeftRightMarginsGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -LeftRightMarginsGroup parseLeftRightMarginsGroup(pugi::xml_node el, pugi::xml_node &cursor); - LeftRightMarginsGroup parseLeftRightMarginsGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); diff --git a/src/private/mx/core/generated/Level.cpp b/src/private/mx/core/generated/Level.cpp index 2aa8dc957..f60ffcd6d 100644 --- a/src/private/mx/core/generated/Level.cpp +++ b/src/private/mx/core/generated/Level.cpp @@ -71,11 +71,6 @@ void Level::setValue(std::string value) m_value = std::move(value); } -Level parseLevel(pugi::xml_node el) -{ - return parseLevel(el, ParseContext{}); -} - Level parseLevel(pugi::xml_node el, const ParseContext &context) { Level out; @@ -115,11 +110,6 @@ Level parseLevel(pugi::xml_node el, const ParseContext &context) return out; } -void parseLevelContent(Level &out, pugi::xml_node el) -{ - parseLevelContent(out, el, ParseContext{}); -} - void parseLevelContent(Level &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/Level.h b/src/private/mx/core/generated/Level.h index e0e6d4650..977a3e8a3 100644 --- a/src/private/mx/core/generated/Level.h +++ b/src/private/mx/core/generated/Level.h @@ -53,12 +53,8 @@ class Level final std::string m_value{}; }; -Level parseLevel(pugi::xml_node el); - Level parseLevel(pugi::xml_node el, const ParseContext &context); -void parseLevelContent(Level &out, pugi::xml_node el); - void parseLevelContent(Level &out, pugi::xml_node el, const ParseContext &context); void serializeLevel(const Level &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/LineDetail.cpp b/src/private/mx/core/generated/LineDetail.cpp index 6aa1995b8..bdc625512 100644 --- a/src/private/mx/core/generated/LineDetail.cpp +++ b/src/private/mx/core/generated/LineDetail.cpp @@ -61,11 +61,6 @@ void LineDetail::setPrintObject(std::optional value) m_printObject = std::move(value); } -LineDetail parseLineDetail(pugi::xml_node el) -{ - return parseLineDetail(el, ParseContext{}); -} - LineDetail parseLineDetail(pugi::xml_node el, const ParseContext &context) { LineDetail out; @@ -111,11 +106,6 @@ LineDetail parseLineDetail(pugi::xml_node el, const ParseContext &context) return out; } -void parseLineDetailContent(LineDetail &out, pugi::xml_node el) -{ - parseLineDetailContent(out, el, ParseContext{}); -} - void parseLineDetailContent(LineDetail &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/LineDetail.h b/src/private/mx/core/generated/LineDetail.h index fc222f99c..661b5fafb 100644 --- a/src/private/mx/core/generated/LineDetail.h +++ b/src/private/mx/core/generated/LineDetail.h @@ -51,12 +51,8 @@ class LineDetail final std::optional m_printObject; }; -LineDetail parseLineDetail(pugi::xml_node el); - LineDetail parseLineDetail(pugi::xml_node el, const ParseContext &context); -void parseLineDetailContent(LineDetail &out, pugi::xml_node el); - void parseLineDetailContent(LineDetail &out, pugi::xml_node el, const ParseContext &context); void serializeLineDetail(const LineDetail &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/LineWidth.cpp b/src/private/mx/core/generated/LineWidth.cpp index f442128ab..0f7f2a09d 100644 --- a/src/private/mx/core/generated/LineWidth.cpp +++ b/src/private/mx/core/generated/LineWidth.cpp @@ -31,11 +31,6 @@ void LineWidth::setValue(Tenths value) m_value = std::move(value); } -LineWidth parseLineWidth(pugi::xml_node el) -{ - return parseLineWidth(el, ParseContext{}); -} - LineWidth parseLineWidth(pugi::xml_node el, const ParseContext &context) { LineWidth out; @@ -65,11 +60,6 @@ LineWidth parseLineWidth(pugi::xml_node el, const ParseContext &context) return out; } -void parseLineWidthContent(LineWidth &out, pugi::xml_node el) -{ - parseLineWidthContent(out, el, ParseContext{}); -} - void parseLineWidthContent(LineWidth &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/LineWidth.h b/src/private/mx/core/generated/LineWidth.h index 9cbdcb27a..c8a6cb616 100644 --- a/src/private/mx/core/generated/LineWidth.h +++ b/src/private/mx/core/generated/LineWidth.h @@ -36,12 +36,8 @@ class LineWidth final Tenths m_value{}; }; -LineWidth parseLineWidth(pugi::xml_node el); - LineWidth parseLineWidth(pugi::xml_node el, const ParseContext &context); -void parseLineWidthContent(LineWidth &out, pugi::xml_node el); - void parseLineWidthContent(LineWidth &out, pugi::xml_node el, const ParseContext &context); void serializeLineWidth(const LineWidth &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Link.cpp b/src/private/mx/core/generated/Link.cpp index c8ab249af..76d4c26e0 100644 --- a/src/private/mx/core/generated/Link.cpp +++ b/src/private/mx/core/generated/Link.cpp @@ -141,11 +141,6 @@ void Link::setRelativeY(std::optional value) m_relativeY = std::move(value); } -Link parseLink(pugi::xml_node el) -{ - return parseLink(el, ParseContext{}); -} - Link parseLink(pugi::xml_node el, const ParseContext &context) { Link out; @@ -223,11 +218,6 @@ Link parseLink(pugi::xml_node el, const ParseContext &context) return out; } -void parseLinkContent(Link &out, pugi::xml_node el) -{ - parseLinkContent(out, el, ParseContext{}); -} - void parseLinkContent(Link &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/Link.h b/src/private/mx/core/generated/Link.h index 54f5088d4..94db05a76 100644 --- a/src/private/mx/core/generated/Link.h +++ b/src/private/mx/core/generated/Link.h @@ -69,12 +69,8 @@ class Link final std::optional m_relativeY; }; -Link parseLink(pugi::xml_node el); - Link parseLink(pugi::xml_node el, const ParseContext &context); -void parseLinkContent(Link &out, pugi::xml_node el); - void parseLinkContent(Link &out, pugi::xml_node el, const ParseContext &context); void serializeLink(const Link &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Listen.cpp b/src/private/mx/core/generated/Listen.cpp index 57fcfe8bf..53dc307e5 100644 --- a/src/private/mx/core/generated/Listen.cpp +++ b/src/private/mx/core/generated/Listen.cpp @@ -26,11 +26,6 @@ void Listen::setChoice(OneOrMore value) m_choice = std::move(value); } -Listen parseListen(pugi::xml_node el) -{ - return parseListen(el, ParseContext{}); -} - Listen parseListen(pugi::xml_node el, const ParseContext &context) { Listen out; @@ -47,11 +42,6 @@ Listen parseListen(pugi::xml_node el, const ParseContext &context) return out; } -void parseListenContent(Listen &out, pugi::xml_node el) -{ - parseListenContent(out, el, ParseContext{}); -} - void parseListenContent(Listen &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Listen.h b/src/private/mx/core/generated/Listen.h index 6a876eb48..8fba504c4 100644 --- a/src/private/mx/core/generated/Listen.h +++ b/src/private/mx/core/generated/Listen.h @@ -38,12 +38,8 @@ class Listen final OneOrMore m_choice; }; -Listen parseListen(pugi::xml_node el); - Listen parseListen(pugi::xml_node el, const ParseContext &context); -void parseListenContent(Listen &out, pugi::xml_node el); - void parseListenContent(Listen &out, pugi::xml_node el, const ParseContext &context); void serializeListen(const Listen &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/ListenChoice.cpp b/src/private/mx/core/generated/ListenChoice.cpp index dbf2c0585..8b35c1288 100644 --- a/src/private/mx/core/generated/ListenChoice.cpp +++ b/src/private/mx/core/generated/ListenChoice.cpp @@ -31,11 +31,6 @@ ListenChoice ListenChoice::otherListen(OtherListening value) return ListenChoice{Storage{std::in_place_index<2>, std::move(value)}}; } -ListenChoice parseListenChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseListenChoice(el, cursor, ParseContext{}); -} - ListenChoice parseListenChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "assess"))) diff --git a/src/private/mx/core/generated/ListenChoice.h b/src/private/mx/core/generated/ListenChoice.h index cf367f768..2e7e87cf6 100644 --- a/src/private/mx/core/generated/ListenChoice.h +++ b/src/private/mx/core/generated/ListenChoice.h @@ -97,8 +97,6 @@ class ListenChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -ListenChoice parseListenChoice(pugi::xml_node el, pugi::xml_node &cursor); - ListenChoice parseListenChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeListenChoice(const ListenChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Listening.cpp b/src/private/mx/core/generated/Listening.cpp index 87e0c27eb..979a570c7 100644 --- a/src/private/mx/core/generated/Listening.cpp +++ b/src/private/mx/core/generated/Listening.cpp @@ -36,11 +36,6 @@ void Listening::setOffset(std::optional value) m_offset = std::move(value); } -Listening parseListening(pugi::xml_node el) -{ - return parseListening(el, ParseContext{}); -} - Listening parseListening(pugi::xml_node el, const ParseContext &context) { Listening out; @@ -57,11 +52,6 @@ Listening parseListening(pugi::xml_node el, const ParseContext &context) return out; } -void parseListeningContent(Listening &out, pugi::xml_node el) -{ - parseListeningContent(out, el, ParseContext{}); -} - void parseListeningContent(Listening &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Listening.h b/src/private/mx/core/generated/Listening.h index d25e32d6e..422038b54 100644 --- a/src/private/mx/core/generated/Listening.h +++ b/src/private/mx/core/generated/Listening.h @@ -48,12 +48,8 @@ class Listening final std::optional m_offset; }; -Listening parseListening(pugi::xml_node el); - Listening parseListening(pugi::xml_node el, const ParseContext &context); -void parseListeningContent(Listening &out, pugi::xml_node el); - void parseListeningContent(Listening &out, pugi::xml_node el, const ParseContext &context); void serializeListening(const Listening &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/ListeningChoice.cpp b/src/private/mx/core/generated/ListeningChoice.cpp index 10b88d183..c0f126136 100644 --- a/src/private/mx/core/generated/ListeningChoice.cpp +++ b/src/private/mx/core/generated/ListeningChoice.cpp @@ -26,11 +26,6 @@ ListeningChoice ListeningChoice::otherListening(OtherListening value) return ListeningChoice{Storage{std::in_place_index<1>, std::move(value)}}; } -ListeningChoice parseListeningChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseListeningChoice(el, cursor, ParseContext{}); -} - ListeningChoice parseListeningChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "sync"))) diff --git a/src/private/mx/core/generated/ListeningChoice.h b/src/private/mx/core/generated/ListeningChoice.h index dd871436f..683a20d72 100644 --- a/src/private/mx/core/generated/ListeningChoice.h +++ b/src/private/mx/core/generated/ListeningChoice.h @@ -82,8 +82,6 @@ class ListeningChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -ListeningChoice parseListeningChoice(pugi::xml_node el, pugi::xml_node &cursor); - ListeningChoice parseListeningChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeListeningChoice(const ListeningChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Lyric.cpp b/src/private/mx/core/generated/Lyric.cpp index 8403c3307..8253fe544 100644 --- a/src/private/mx/core/generated/Lyric.cpp +++ b/src/private/mx/core/generated/Lyric.cpp @@ -171,11 +171,6 @@ void Lyric::setEditorial(EditorialGroup value) m_editorial = std::move(value); } -Lyric parseLyric(pugi::xml_node el) -{ - return parseLyric(el, ParseContext{}); -} - Lyric parseLyric(pugi::xml_node el, const ParseContext &context) { Lyric out; @@ -243,11 +238,6 @@ Lyric parseLyric(pugi::xml_node el, const ParseContext &context) return out; } -void parseLyricContent(Lyric &out, pugi::xml_node el) -{ - parseLyricContent(out, el, ParseContext{}); -} - void parseLyricContent(Lyric &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Lyric.h b/src/private/mx/core/generated/Lyric.h index a1daec469..5d1716c85 100644 --- a/src/private/mx/core/generated/Lyric.h +++ b/src/private/mx/core/generated/Lyric.h @@ -97,12 +97,8 @@ class Lyric final EditorialGroup m_editorial{}; }; -Lyric parseLyric(pugi::xml_node el); - Lyric parseLyric(pugi::xml_node el, const ParseContext &context); -void parseLyricContent(Lyric &out, pugi::xml_node el); - void parseLyricContent(Lyric &out, pugi::xml_node el, const ParseContext &context); void serializeLyric(const Lyric &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/LyricChoice.cpp b/src/private/mx/core/generated/LyricChoice.cpp index f64d5a0f6..28a7eb120 100644 --- a/src/private/mx/core/generated/LyricChoice.cpp +++ b/src/private/mx/core/generated/LyricChoice.cpp @@ -36,11 +36,6 @@ LyricChoice LyricChoice::humming(Empty value) return LyricChoice{Storage{std::in_place_index<3>, std::move(value)}}; } -LyricChoice parseLyricChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseLyricChoice(el, cursor, ParseContext{}); -} - LyricChoice parseLyricChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "syllabic") || cursorIs(cursor, "text"))) diff --git a/src/private/mx/core/generated/LyricChoice.h b/src/private/mx/core/generated/LyricChoice.h index 914f1e652..03f25c7c7 100644 --- a/src/private/mx/core/generated/LyricChoice.h +++ b/src/private/mx/core/generated/LyricChoice.h @@ -111,8 +111,6 @@ class LyricChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -LyricChoice parseLyricChoice(pugi::xml_node el, pugi::xml_node &cursor); - LyricChoice parseLyricChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeLyricChoice(const LyricChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/LyricFont.cpp b/src/private/mx/core/generated/LyricFont.cpp index 954574977..bb44fa005 100644 --- a/src/private/mx/core/generated/LyricFont.cpp +++ b/src/private/mx/core/generated/LyricFont.cpp @@ -71,11 +71,6 @@ void LyricFont::setFontWeight(std::optional value) m_fontWeight = std::move(value); } -LyricFont parseLyricFont(pugi::xml_node el) -{ - return parseLyricFont(el, ParseContext{}); -} - LyricFont parseLyricFont(pugi::xml_node el, const ParseContext &context) { LyricFont out; @@ -119,11 +114,6 @@ LyricFont parseLyricFont(pugi::xml_node el, const ParseContext &context) return out; } -void parseLyricFontContent(LyricFont &out, pugi::xml_node el) -{ - parseLyricFontContent(out, el, ParseContext{}); -} - void parseLyricFontContent(LyricFont &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/LyricFont.h b/src/private/mx/core/generated/LyricFont.h index 66a97d08f..800226f79 100644 --- a/src/private/mx/core/generated/LyricFont.h +++ b/src/private/mx/core/generated/LyricFont.h @@ -49,12 +49,8 @@ class LyricFont final std::optional m_fontWeight; }; -LyricFont parseLyricFont(pugi::xml_node el); - LyricFont parseLyricFont(pugi::xml_node el, const ParseContext &context); -void parseLyricFontContent(LyricFont &out, pugi::xml_node el); - void parseLyricFontContent(LyricFont &out, pugi::xml_node el, const ParseContext &context); void serializeLyricFont(const LyricFont &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/LyricLanguage.cpp b/src/private/mx/core/generated/LyricLanguage.cpp index 7885e868d..7dc7e490f 100644 --- a/src/private/mx/core/generated/LyricLanguage.cpp +++ b/src/private/mx/core/generated/LyricLanguage.cpp @@ -41,11 +41,6 @@ void LyricLanguage::setXMLLang(std::string value) m_xmlLang = std::move(value); } -LyricLanguage parseLyricLanguage(pugi::xml_node el) -{ - return parseLyricLanguage(el, ParseContext{}); -} - LyricLanguage parseLyricLanguage(pugi::xml_node el, const ParseContext &context) { LyricLanguage out; @@ -85,11 +80,6 @@ LyricLanguage parseLyricLanguage(pugi::xml_node el, const ParseContext &context) return out; } -void parseLyricLanguageContent(LyricLanguage &out, pugi::xml_node el) -{ - parseLyricLanguageContent(out, el, ParseContext{}); -} - void parseLyricLanguageContent(LyricLanguage &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/LyricLanguage.h b/src/private/mx/core/generated/LyricLanguage.h index 97cc7740e..1fd1f968d 100644 --- a/src/private/mx/core/generated/LyricLanguage.h +++ b/src/private/mx/core/generated/LyricLanguage.h @@ -36,12 +36,8 @@ class LyricLanguage final std::string m_xmlLang{}; }; -LyricLanguage parseLyricLanguage(pugi::xml_node el); - LyricLanguage parseLyricLanguage(pugi::xml_node el, const ParseContext &context); -void parseLyricLanguageContent(LyricLanguage &out, pugi::xml_node el); - void parseLyricLanguageContent(LyricLanguage &out, pugi::xml_node el, const ParseContext &context); void serializeLyricLanguage(const LyricLanguage &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/LyricSyllableGroup.cpp b/src/private/mx/core/generated/LyricSyllableGroup.cpp index 405b6c64c..cadaeabbc 100644 --- a/src/private/mx/core/generated/LyricSyllableGroup.cpp +++ b/src/private/mx/core/generated/LyricSyllableGroup.cpp @@ -31,11 +31,6 @@ void LyricSyllableGroup::setText(TextElementData value) m_text = std::move(value); } -LyricSyllableGroup parseLyricSyllableGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseLyricSyllableGroup(el, cursor, ParseContext{}); -} - LyricSyllableGroup parseLyricSyllableGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { LyricSyllableGroup out; diff --git a/src/private/mx/core/generated/LyricSyllableGroup.h b/src/private/mx/core/generated/LyricSyllableGroup.h index 1d73b9799..24985c980 100644 --- a/src/private/mx/core/generated/LyricSyllableGroup.h +++ b/src/private/mx/core/generated/LyricSyllableGroup.h @@ -39,8 +39,6 @@ class LyricSyllableGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -LyricSyllableGroup parseLyricSyllableGroup(pugi::xml_node el, pugi::xml_node &cursor); - LyricSyllableGroup parseLyricSyllableGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeLyricSyllableGroup(const LyricSyllableGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/LyricTextGroup.cpp b/src/private/mx/core/generated/LyricTextGroup.cpp index 7e8563c4c..246df6377 100644 --- a/src/private/mx/core/generated/LyricTextGroup.cpp +++ b/src/private/mx/core/generated/LyricTextGroup.cpp @@ -56,11 +56,6 @@ void LyricTextGroup::setExtend(std::optional value) m_extend = std::move(value); } -LyricTextGroup parseLyricTextGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseLyricTextGroup(el, cursor, ParseContext{}); -} - LyricTextGroup parseLyricTextGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { LyricTextGroup out; diff --git a/src/private/mx/core/generated/LyricTextGroup.h b/src/private/mx/core/generated/LyricTextGroup.h index 23dc12b37..f8a8b8b70 100644 --- a/src/private/mx/core/generated/LyricTextGroup.h +++ b/src/private/mx/core/generated/LyricTextGroup.h @@ -48,8 +48,6 @@ class LyricTextGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -LyricTextGroup parseLyricTextGroup(pugi::xml_node el, pugi::xml_node &cursor); - LyricTextGroup parseLyricTextGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeLyricTextGroup(const LyricTextGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/MIDIDevice.cpp b/src/private/mx/core/generated/MIDIDevice.cpp index d99f1f3a2..f7e0f1d20 100644 --- a/src/private/mx/core/generated/MIDIDevice.cpp +++ b/src/private/mx/core/generated/MIDIDevice.cpp @@ -41,11 +41,6 @@ void MIDIDevice::setValue(std::string value) m_value = std::move(value); } -MIDIDevice parseMIDIDevice(pugi::xml_node el) -{ - return parseMIDIDevice(el, ParseContext{}); -} - MIDIDevice parseMIDIDevice(pugi::xml_node el, const ParseContext &context) { MIDIDevice out; @@ -73,11 +68,6 @@ MIDIDevice parseMIDIDevice(pugi::xml_node el, const ParseContext &context) return out; } -void parseMIDIDeviceContent(MIDIDevice &out, pugi::xml_node el) -{ - parseMIDIDeviceContent(out, el, ParseContext{}); -} - void parseMIDIDeviceContent(MIDIDevice &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/MIDIDevice.h b/src/private/mx/core/generated/MIDIDevice.h index f3a6a4e5c..b4999bd4a 100644 --- a/src/private/mx/core/generated/MIDIDevice.h +++ b/src/private/mx/core/generated/MIDIDevice.h @@ -42,12 +42,8 @@ class MIDIDevice final std::string m_value{}; }; -MIDIDevice parseMIDIDevice(pugi::xml_node el); - MIDIDevice parseMIDIDevice(pugi::xml_node el, const ParseContext &context); -void parseMIDIDeviceContent(MIDIDevice &out, pugi::xml_node el); - void parseMIDIDeviceContent(MIDIDevice &out, pugi::xml_node el, const ParseContext &context); void serializeMIDIDevice(const MIDIDevice &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/MIDIInstrument.cpp b/src/private/mx/core/generated/MIDIInstrument.cpp index a44e08501..a03464436 100644 --- a/src/private/mx/core/generated/MIDIInstrument.cpp +++ b/src/private/mx/core/generated/MIDIInstrument.cpp @@ -101,11 +101,6 @@ void MIDIInstrument::setElevation(std::optional value) m_elevation = std::move(value); } -MIDIInstrument parseMIDIInstrument(pugi::xml_node el) -{ - return parseMIDIInstrument(el, ParseContext{}); -} - MIDIInstrument parseMIDIInstrument(pugi::xml_node el, const ParseContext &context) { MIDIInstrument out; @@ -135,11 +130,6 @@ MIDIInstrument parseMIDIInstrument(pugi::xml_node el, const ParseContext &contex return out; } -void parseMIDIInstrumentContent(MIDIInstrument &out, pugi::xml_node el) -{ - parseMIDIInstrumentContent(out, el, ParseContext{}); -} - void parseMIDIInstrumentContent(MIDIInstrument &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/MIDIInstrument.h b/src/private/mx/core/generated/MIDIInstrument.h index 078ac95ff..4ff8d7089 100644 --- a/src/private/mx/core/generated/MIDIInstrument.h +++ b/src/private/mx/core/generated/MIDIInstrument.h @@ -65,12 +65,8 @@ class MIDIInstrument final std::optional m_elevation; }; -MIDIInstrument parseMIDIInstrument(pugi::xml_node el); - MIDIInstrument parseMIDIInstrument(pugi::xml_node el, const ParseContext &context); -void parseMIDIInstrumentContent(MIDIInstrument &out, pugi::xml_node el); - void parseMIDIInstrumentContent(MIDIInstrument &out, pugi::xml_node el, const ParseContext &context); void serializeMIDIInstrument(const MIDIInstrument &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/MeasureLayout.cpp b/src/private/mx/core/generated/MeasureLayout.cpp index c50aed215..afff0f444 100644 --- a/src/private/mx/core/generated/MeasureLayout.cpp +++ b/src/private/mx/core/generated/MeasureLayout.cpp @@ -21,11 +21,6 @@ void MeasureLayout::setMeasureDistance(std::optional value) m_measureDistance = std::move(value); } -MeasureLayout parseMeasureLayout(pugi::xml_node el) -{ - return parseMeasureLayout(el, ParseContext{}); -} - MeasureLayout parseMeasureLayout(pugi::xml_node el, const ParseContext &context) { MeasureLayout out; @@ -42,11 +37,6 @@ MeasureLayout parseMeasureLayout(pugi::xml_node el, const ParseContext &context) return out; } -void parseMeasureLayoutContent(MeasureLayout &out, pugi::xml_node el) -{ - parseMeasureLayoutContent(out, el, ParseContext{}); -} - void parseMeasureLayoutContent(MeasureLayout &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/MeasureLayout.h b/src/private/mx/core/generated/MeasureLayout.h index 600b4a73c..41d0d30d5 100644 --- a/src/private/mx/core/generated/MeasureLayout.h +++ b/src/private/mx/core/generated/MeasureLayout.h @@ -34,12 +34,8 @@ class MeasureLayout final std::optional m_measureDistance; }; -MeasureLayout parseMeasureLayout(pugi::xml_node el); - MeasureLayout parseMeasureLayout(pugi::xml_node el, const ParseContext &context); -void parseMeasureLayoutContent(MeasureLayout &out, pugi::xml_node el); - void parseMeasureLayoutContent(MeasureLayout &out, pugi::xml_node el, const ParseContext &context); void serializeMeasureLayout(const MeasureLayout &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/MeasureNumbering.cpp b/src/private/mx/core/generated/MeasureNumbering.cpp index bf7656a57..1e3af7d5c 100644 --- a/src/private/mx/core/generated/MeasureNumbering.cpp +++ b/src/private/mx/core/generated/MeasureNumbering.cpp @@ -171,11 +171,6 @@ void MeasureNumbering::setValue(MeasureNumberingValue value) m_value = std::move(value); } -MeasureNumbering parseMeasureNumbering(pugi::xml_node el) -{ - return parseMeasureNumbering(el, ParseContext{}); -} - MeasureNumbering parseMeasureNumbering(pugi::xml_node el, const ParseContext &context) { MeasureNumbering out; @@ -255,11 +250,6 @@ MeasureNumbering parseMeasureNumbering(pugi::xml_node el, const ParseContext &co return out; } -void parseMeasureNumberingContent(MeasureNumbering &out, pugi::xml_node el) -{ - parseMeasureNumberingContent(out, el, ParseContext{}); -} - void parseMeasureNumberingContent(MeasureNumbering &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/MeasureNumbering.h b/src/private/mx/core/generated/MeasureNumbering.h index 46f8a2683..55d8390a7 100644 --- a/src/private/mx/core/generated/MeasureNumbering.h +++ b/src/private/mx/core/generated/MeasureNumbering.h @@ -97,12 +97,8 @@ class MeasureNumbering final MeasureNumberingValue m_value{}; }; -MeasureNumbering parseMeasureNumbering(pugi::xml_node el); - MeasureNumbering parseMeasureNumbering(pugi::xml_node el, const ParseContext &context); -void parseMeasureNumberingContent(MeasureNumbering &out, pugi::xml_node el); - void parseMeasureNumberingContent(MeasureNumbering &out, pugi::xml_node el, const ParseContext &context); void serializeMeasureNumbering(const MeasureNumbering &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/MeasureRepeat.cpp b/src/private/mx/core/generated/MeasureRepeat.cpp index 5515ea3d4..83d3cd986 100644 --- a/src/private/mx/core/generated/MeasureRepeat.cpp +++ b/src/private/mx/core/generated/MeasureRepeat.cpp @@ -41,11 +41,6 @@ void MeasureRepeat::setValue(PositiveIntegerOrEmpty value) m_value = std::move(value); } -MeasureRepeat parseMeasureRepeat(pugi::xml_node el) -{ - return parseMeasureRepeat(el, ParseContext{}); -} - MeasureRepeat parseMeasureRepeat(pugi::xml_node el, const ParseContext &context) { MeasureRepeat out; @@ -79,11 +74,6 @@ MeasureRepeat parseMeasureRepeat(pugi::xml_node el, const ParseContext &context) return out; } -void parseMeasureRepeatContent(MeasureRepeat &out, pugi::xml_node el) -{ - parseMeasureRepeatContent(out, el, ParseContext{}); -} - void parseMeasureRepeatContent(MeasureRepeat &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/MeasureRepeat.h b/src/private/mx/core/generated/MeasureRepeat.h index 27bd66fd3..82ab24151 100644 --- a/src/private/mx/core/generated/MeasureRepeat.h +++ b/src/private/mx/core/generated/MeasureRepeat.h @@ -44,12 +44,8 @@ class MeasureRepeat final PositiveIntegerOrEmpty m_value{}; }; -MeasureRepeat parseMeasureRepeat(pugi::xml_node el); - MeasureRepeat parseMeasureRepeat(pugi::xml_node el, const ParseContext &context); -void parseMeasureRepeatContent(MeasureRepeat &out, pugi::xml_node el); - void parseMeasureRepeatContent(MeasureRepeat &out, pugi::xml_node el, const ParseContext &context); void serializeMeasureRepeat(const MeasureRepeat &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/MeasureStyle.cpp b/src/private/mx/core/generated/MeasureStyle.cpp index 2d51f6ecf..0d81eb26d 100644 --- a/src/private/mx/core/generated/MeasureStyle.cpp +++ b/src/private/mx/core/generated/MeasureStyle.cpp @@ -91,11 +91,6 @@ void MeasureStyle::setChoice(MeasureStyleChoice value) m_choice = std::move(value); } -MeasureStyle parseMeasureStyle(pugi::xml_node el) -{ - return parseMeasureStyle(el, ParseContext{}); -} - MeasureStyle parseMeasureStyle(pugi::xml_node el, const ParseContext &context) { MeasureStyle out; @@ -143,11 +138,6 @@ MeasureStyle parseMeasureStyle(pugi::xml_node el, const ParseContext &context) return out; } -void parseMeasureStyleContent(MeasureStyle &out, pugi::xml_node el) -{ - parseMeasureStyleContent(out, el, ParseContext{}); -} - void parseMeasureStyleContent(MeasureStyle &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/MeasureStyle.h b/src/private/mx/core/generated/MeasureStyle.h index be1662fbe..8c00ef9b1 100644 --- a/src/private/mx/core/generated/MeasureStyle.h +++ b/src/private/mx/core/generated/MeasureStyle.h @@ -68,12 +68,8 @@ class MeasureStyle final MeasureStyleChoice m_choice{}; }; -MeasureStyle parseMeasureStyle(pugi::xml_node el); - MeasureStyle parseMeasureStyle(pugi::xml_node el, const ParseContext &context); -void parseMeasureStyleContent(MeasureStyle &out, pugi::xml_node el); - void parseMeasureStyleContent(MeasureStyle &out, pugi::xml_node el, const ParseContext &context); void serializeMeasureStyle(const MeasureStyle &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/MeasureStyleChoice.cpp b/src/private/mx/core/generated/MeasureStyleChoice.cpp index 1f859e3bf..b7354aecd 100644 --- a/src/private/mx/core/generated/MeasureStyleChoice.cpp +++ b/src/private/mx/core/generated/MeasureStyleChoice.cpp @@ -36,11 +36,6 @@ MeasureStyleChoice MeasureStyleChoice::slash(Slash value) return MeasureStyleChoice{Storage{std::in_place_index<3>, std::move(value)}}; } -MeasureStyleChoice parseMeasureStyleChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseMeasureStyleChoice(el, cursor, ParseContext{}); -} - MeasureStyleChoice parseMeasureStyleChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "multiple-rest"))) diff --git a/src/private/mx/core/generated/MeasureStyleChoice.h b/src/private/mx/core/generated/MeasureStyleChoice.h index 40516f964..d33d3da19 100644 --- a/src/private/mx/core/generated/MeasureStyleChoice.h +++ b/src/private/mx/core/generated/MeasureStyleChoice.h @@ -112,8 +112,6 @@ class MeasureStyleChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -MeasureStyleChoice parseMeasureStyleChoice(pugi::xml_node el, pugi::xml_node &cursor); - MeasureStyleChoice parseMeasureStyleChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeMeasureStyleChoice(const MeasureStyleChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Membrane.cpp b/src/private/mx/core/generated/Membrane.cpp index 88f5dd671..314f24559 100644 --- a/src/private/mx/core/generated/Membrane.cpp +++ b/src/private/mx/core/generated/Membrane.cpp @@ -31,11 +31,6 @@ void Membrane::setValue(MembraneValue value) m_value = std::move(value); } -Membrane parseMembrane(pugi::xml_node el) -{ - return parseMembrane(el, ParseContext{}); -} - Membrane parseMembrane(pugi::xml_node el, const ParseContext &context) { Membrane out; @@ -59,11 +54,6 @@ Membrane parseMembrane(pugi::xml_node el, const ParseContext &context) return out; } -void parseMembraneContent(Membrane &out, pugi::xml_node el) -{ - parseMembraneContent(out, el, ParseContext{}); -} - void parseMembraneContent(Membrane &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/Membrane.h b/src/private/mx/core/generated/Membrane.h index d598141ee..682bb6492 100644 --- a/src/private/mx/core/generated/Membrane.h +++ b/src/private/mx/core/generated/Membrane.h @@ -34,12 +34,8 @@ class Membrane final MembraneValue m_value{}; }; -Membrane parseMembrane(pugi::xml_node el); - Membrane parseMembrane(pugi::xml_node el, const ParseContext &context); -void parseMembraneContent(Membrane &out, pugi::xml_node el); - void parseMembraneContent(Membrane &out, pugi::xml_node el, const ParseContext &context); void serializeMembrane(const Membrane &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Metal.cpp b/src/private/mx/core/generated/Metal.cpp index b7f0f5a3e..99089671d 100644 --- a/src/private/mx/core/generated/Metal.cpp +++ b/src/private/mx/core/generated/Metal.cpp @@ -31,11 +31,6 @@ void Metal::setValue(MetalValue value) m_value = std::move(value); } -Metal parseMetal(pugi::xml_node el) -{ - return parseMetal(el, ParseContext{}); -} - Metal parseMetal(pugi::xml_node el, const ParseContext &context) { Metal out; @@ -59,11 +54,6 @@ Metal parseMetal(pugi::xml_node el, const ParseContext &context) return out; } -void parseMetalContent(Metal &out, pugi::xml_node el) -{ - parseMetalContent(out, el, ParseContext{}); -} - void parseMetalContent(Metal &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/Metal.h b/src/private/mx/core/generated/Metal.h index 607a6d4f8..9d253dbed 100644 --- a/src/private/mx/core/generated/Metal.h +++ b/src/private/mx/core/generated/Metal.h @@ -34,12 +34,8 @@ class Metal final MetalValue m_value{}; }; -Metal parseMetal(pugi::xml_node el); - Metal parseMetal(pugi::xml_node el, const ParseContext &context); -void parseMetalContent(Metal &out, pugi::xml_node el); - void parseMetalContent(Metal &out, pugi::xml_node el, const ParseContext &context); void serializeMetal(const Metal &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Metronome.cpp b/src/private/mx/core/generated/Metronome.cpp index f1d45b105..1a53ff407 100644 --- a/src/private/mx/core/generated/Metronome.cpp +++ b/src/private/mx/core/generated/Metronome.cpp @@ -171,11 +171,6 @@ void Metronome::setChoice(MetronomeChoice value) m_choice = std::move(value); } -Metronome parseMetronome(pugi::xml_node el) -{ - return parseMetronome(el, ParseContext{}); -} - Metronome parseMetronome(pugi::xml_node el, const ParseContext &context) { Metronome out; @@ -255,11 +250,6 @@ Metronome parseMetronome(pugi::xml_node el, const ParseContext &context) return out; } -void parseMetronomeContent(Metronome &out, pugi::xml_node el) -{ - parseMetronomeContent(out, el, ParseContext{}); -} - void parseMetronomeContent(Metronome &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Metronome.h b/src/private/mx/core/generated/Metronome.h index e8bacdc8f..0515ae20f 100644 --- a/src/private/mx/core/generated/Metronome.h +++ b/src/private/mx/core/generated/Metronome.h @@ -97,12 +97,8 @@ class Metronome final MetronomeChoice m_choice{}; }; -Metronome parseMetronome(pugi::xml_node el); - Metronome parseMetronome(pugi::xml_node el, const ParseContext &context); -void parseMetronomeContent(Metronome &out, pugi::xml_node el); - void parseMetronomeContent(Metronome &out, pugi::xml_node el, const ParseContext &context); void serializeMetronome(const Metronome &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/MetronomeBeam.cpp b/src/private/mx/core/generated/MetronomeBeam.cpp index 5264d51ff..4ef6c6996 100644 --- a/src/private/mx/core/generated/MetronomeBeam.cpp +++ b/src/private/mx/core/generated/MetronomeBeam.cpp @@ -31,11 +31,6 @@ void MetronomeBeam::setValue(BeamValue value) m_value = std::move(value); } -MetronomeBeam parseMetronomeBeam(pugi::xml_node el) -{ - return parseMetronomeBeam(el, ParseContext{}); -} - MetronomeBeam parseMetronomeBeam(pugi::xml_node el, const ParseContext &context) { MetronomeBeam out; @@ -59,11 +54,6 @@ MetronomeBeam parseMetronomeBeam(pugi::xml_node el, const ParseContext &context) return out; } -void parseMetronomeBeamContent(MetronomeBeam &out, pugi::xml_node el) -{ - parseMetronomeBeamContent(out, el, ParseContext{}); -} - void parseMetronomeBeamContent(MetronomeBeam &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/MetronomeBeam.h b/src/private/mx/core/generated/MetronomeBeam.h index 29bdb8aaa..7c7cdcc88 100644 --- a/src/private/mx/core/generated/MetronomeBeam.h +++ b/src/private/mx/core/generated/MetronomeBeam.h @@ -34,12 +34,8 @@ class MetronomeBeam final BeamValue m_value{}; }; -MetronomeBeam parseMetronomeBeam(pugi::xml_node el); - MetronomeBeam parseMetronomeBeam(pugi::xml_node el, const ParseContext &context); -void parseMetronomeBeamContent(MetronomeBeam &out, pugi::xml_node el); - void parseMetronomeBeamContent(MetronomeBeam &out, pugi::xml_node el, const ParseContext &context); void serializeMetronomeBeam(const MetronomeBeam &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/MetronomeChoice.cpp b/src/private/mx/core/generated/MetronomeChoice.cpp index a1f87b7bb..09c89a8b1 100644 --- a/src/private/mx/core/generated/MetronomeChoice.cpp +++ b/src/private/mx/core/generated/MetronomeChoice.cpp @@ -26,11 +26,6 @@ MetronomeChoice MetronomeChoice::group2(MetronomeChoiceGroup2 value) return MetronomeChoice{Storage{std::in_place_index<1>, std::move(value)}}; } -MetronomeChoice parseMetronomeChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseMetronomeChoice(el, cursor, ParseContext{}); -} - MetronomeChoice parseMetronomeChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "beat-unit"))) diff --git a/src/private/mx/core/generated/MetronomeChoice.h b/src/private/mx/core/generated/MetronomeChoice.h index df699be80..699fe0c3b 100644 --- a/src/private/mx/core/generated/MetronomeChoice.h +++ b/src/private/mx/core/generated/MetronomeChoice.h @@ -82,8 +82,6 @@ class MetronomeChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -MetronomeChoice parseMetronomeChoice(pugi::xml_node el, pugi::xml_node &cursor); - MetronomeChoice parseMetronomeChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeMetronomeChoice(const MetronomeChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/MetronomeChoiceGroup.cpp b/src/private/mx/core/generated/MetronomeChoiceGroup.cpp index dfb524bc5..0a4c2d3c6 100644 --- a/src/private/mx/core/generated/MetronomeChoiceGroup.cpp +++ b/src/private/mx/core/generated/MetronomeChoiceGroup.cpp @@ -46,11 +46,6 @@ void MetronomeChoiceGroup::setChoice(MetronomeChoiceGroupChoice value) m_choice = std::move(value); } -MetronomeChoiceGroup parseMetronomeChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseMetronomeChoiceGroup(el, cursor, ParseContext{}); -} - MetronomeChoiceGroup parseMetronomeChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { MetronomeChoiceGroup out; diff --git a/src/private/mx/core/generated/MetronomeChoiceGroup.h b/src/private/mx/core/generated/MetronomeChoiceGroup.h index cc6789677..a60db3a14 100644 --- a/src/private/mx/core/generated/MetronomeChoiceGroup.h +++ b/src/private/mx/core/generated/MetronomeChoiceGroup.h @@ -44,8 +44,6 @@ class MetronomeChoiceGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -MetronomeChoiceGroup parseMetronomeChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor); - MetronomeChoiceGroup parseMetronomeChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeMetronomeChoiceGroup(const MetronomeChoiceGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/MetronomeChoiceGroup2.cpp b/src/private/mx/core/generated/MetronomeChoiceGroup2.cpp index 8c420a60f..4ac698f88 100644 --- a/src/private/mx/core/generated/MetronomeChoiceGroup2.cpp +++ b/src/private/mx/core/generated/MetronomeChoiceGroup2.cpp @@ -46,11 +46,6 @@ void MetronomeChoiceGroup2::setGroup(std::optional v m_group = std::move(value); } -MetronomeChoiceGroup2 parseMetronomeChoiceGroup2(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseMetronomeChoiceGroup2(el, cursor, ParseContext{}); -} - MetronomeChoiceGroup2 parseMetronomeChoiceGroup2(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { MetronomeChoiceGroup2 out; diff --git a/src/private/mx/core/generated/MetronomeChoiceGroup2.h b/src/private/mx/core/generated/MetronomeChoiceGroup2.h index e52cf13be..4805815a5 100644 --- a/src/private/mx/core/generated/MetronomeChoiceGroup2.h +++ b/src/private/mx/core/generated/MetronomeChoiceGroup2.h @@ -45,8 +45,6 @@ class MetronomeChoiceGroup2 final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -MetronomeChoiceGroup2 parseMetronomeChoiceGroup2(pugi::xml_node el, pugi::xml_node &cursor); - MetronomeChoiceGroup2 parseMetronomeChoiceGroup2(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); diff --git a/src/private/mx/core/generated/MetronomeChoiceGroup2Group.cpp b/src/private/mx/core/generated/MetronomeChoiceGroup2Group.cpp index 0035db016..76fa1b894 100644 --- a/src/private/mx/core/generated/MetronomeChoiceGroup2Group.cpp +++ b/src/private/mx/core/generated/MetronomeChoiceGroup2Group.cpp @@ -36,11 +36,6 @@ void MetronomeChoiceGroup2Group::setMetronomeNote(OneOrMore value m_metronomeNote = std::move(value); } -MetronomeChoiceGroup2Group parseMetronomeChoiceGroup2Group(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseMetronomeChoiceGroup2Group(el, cursor, ParseContext{}); -} - MetronomeChoiceGroup2Group parseMetronomeChoiceGroup2Group(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { diff --git a/src/private/mx/core/generated/MetronomeChoiceGroup2Group.h b/src/private/mx/core/generated/MetronomeChoiceGroup2Group.h index e388b9acb..e0aea6d92 100644 --- a/src/private/mx/core/generated/MetronomeChoiceGroup2Group.h +++ b/src/private/mx/core/generated/MetronomeChoiceGroup2Group.h @@ -40,8 +40,6 @@ class MetronomeChoiceGroup2Group final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -MetronomeChoiceGroup2Group parseMetronomeChoiceGroup2Group(pugi::xml_node el, pugi::xml_node &cursor); - MetronomeChoiceGroup2Group parseMetronomeChoiceGroup2Group(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); diff --git a/src/private/mx/core/generated/MetronomeChoiceGroupChoice.cpp b/src/private/mx/core/generated/MetronomeChoiceGroupChoice.cpp index e74c3ef42..2976d5975 100644 --- a/src/private/mx/core/generated/MetronomeChoiceGroupChoice.cpp +++ b/src/private/mx/core/generated/MetronomeChoiceGroupChoice.cpp @@ -26,11 +26,6 @@ MetronomeChoiceGroupChoice MetronomeChoiceGroupChoice::group(MetronomeChoiceGrou return MetronomeChoiceGroupChoice{Storage{std::in_place_index<1>, std::move(value)}}; } -MetronomeChoiceGroupChoice parseMetronomeChoiceGroupChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseMetronomeChoiceGroupChoice(el, cursor, ParseContext{}); -} - MetronomeChoiceGroupChoice parseMetronomeChoiceGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { diff --git a/src/private/mx/core/generated/MetronomeChoiceGroupChoice.h b/src/private/mx/core/generated/MetronomeChoiceGroupChoice.h index 60615b112..b8cdb7d3b 100644 --- a/src/private/mx/core/generated/MetronomeChoiceGroupChoice.h +++ b/src/private/mx/core/generated/MetronomeChoiceGroupChoice.h @@ -82,8 +82,6 @@ class MetronomeChoiceGroupChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -MetronomeChoiceGroupChoice parseMetronomeChoiceGroupChoice(pugi::xml_node el, pugi::xml_node &cursor); - MetronomeChoiceGroupChoice parseMetronomeChoiceGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); diff --git a/src/private/mx/core/generated/MetronomeChoiceGroupChoiceGroup.cpp b/src/private/mx/core/generated/MetronomeChoiceGroupChoiceGroup.cpp index 1e88f0c5e..7f748aae9 100644 --- a/src/private/mx/core/generated/MetronomeChoiceGroupChoiceGroup.cpp +++ b/src/private/mx/core/generated/MetronomeChoiceGroupChoiceGroup.cpp @@ -36,11 +36,6 @@ void MetronomeChoiceGroupChoiceGroup::setBeatUnitTied(std::vector m_beatUnitTied = std::move(value); } -MetronomeChoiceGroupChoiceGroup parseMetronomeChoiceGroupChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseMetronomeChoiceGroupChoiceGroup(el, cursor, ParseContext{}); -} - MetronomeChoiceGroupChoiceGroup parseMetronomeChoiceGroupChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { diff --git a/src/private/mx/core/generated/MetronomeChoiceGroupChoiceGroup.h b/src/private/mx/core/generated/MetronomeChoiceGroupChoiceGroup.h index 80325c517..36f201d18 100644 --- a/src/private/mx/core/generated/MetronomeChoiceGroupChoiceGroup.h +++ b/src/private/mx/core/generated/MetronomeChoiceGroupChoiceGroup.h @@ -40,8 +40,6 @@ class MetronomeChoiceGroupChoiceGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -MetronomeChoiceGroupChoiceGroup parseMetronomeChoiceGroupChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor); - MetronomeChoiceGroupChoiceGroup parseMetronomeChoiceGroupChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); diff --git a/src/private/mx/core/generated/MetronomeNote.cpp b/src/private/mx/core/generated/MetronomeNote.cpp index 340199f31..a1d53e174 100644 --- a/src/private/mx/core/generated/MetronomeNote.cpp +++ b/src/private/mx/core/generated/MetronomeNote.cpp @@ -71,11 +71,6 @@ void MetronomeNote::setMetronomeTuplet(std::optional value) m_metronomeTuplet = std::move(value); } -MetronomeNote parseMetronomeNote(pugi::xml_node el) -{ - return parseMetronomeNote(el, ParseContext{}); -} - MetronomeNote parseMetronomeNote(pugi::xml_node el, const ParseContext &context) { MetronomeNote out; @@ -92,11 +87,6 @@ MetronomeNote parseMetronomeNote(pugi::xml_node el, const ParseContext &context) return out; } -void parseMetronomeNoteContent(MetronomeNote &out, pugi::xml_node el) -{ - parseMetronomeNoteContent(out, el, ParseContext{}); -} - void parseMetronomeNoteContent(MetronomeNote &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/MetronomeNote.h b/src/private/mx/core/generated/MetronomeNote.h index 08de394af..344dc6a7c 100644 --- a/src/private/mx/core/generated/MetronomeNote.h +++ b/src/private/mx/core/generated/MetronomeNote.h @@ -51,12 +51,8 @@ class MetronomeNote final std::optional m_metronomeTuplet; }; -MetronomeNote parseMetronomeNote(pugi::xml_node el); - MetronomeNote parseMetronomeNote(pugi::xml_node el, const ParseContext &context); -void parseMetronomeNoteContent(MetronomeNote &out, pugi::xml_node el); - void parseMetronomeNoteContent(MetronomeNote &out, pugi::xml_node el, const ParseContext &context); void serializeMetronomeNote(const MetronomeNote &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/MetronomeTied.cpp b/src/private/mx/core/generated/MetronomeTied.cpp index c9ce0e358..8cb7458a0 100644 --- a/src/private/mx/core/generated/MetronomeTied.cpp +++ b/src/private/mx/core/generated/MetronomeTied.cpp @@ -21,11 +21,6 @@ void MetronomeTied::setType(StartStop value) m_type = std::move(value); } -MetronomeTied parseMetronomeTied(pugi::xml_node el) -{ - return parseMetronomeTied(el, ParseContext{}); -} - MetronomeTied parseMetronomeTied(pugi::xml_node el, const ParseContext &context) { MetronomeTied out; @@ -55,11 +50,6 @@ MetronomeTied parseMetronomeTied(pugi::xml_node el, const ParseContext &context) return out; } -void parseMetronomeTiedContent(MetronomeTied &out, pugi::xml_node el) -{ - parseMetronomeTiedContent(out, el, ParseContext{}); -} - void parseMetronomeTiedContent(MetronomeTied &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/MetronomeTied.h b/src/private/mx/core/generated/MetronomeTied.h index 81459817b..bafb2e79b 100644 --- a/src/private/mx/core/generated/MetronomeTied.h +++ b/src/private/mx/core/generated/MetronomeTied.h @@ -31,12 +31,8 @@ class MetronomeTied final StartStop m_type{}; }; -MetronomeTied parseMetronomeTied(pugi::xml_node el); - MetronomeTied parseMetronomeTied(pugi::xml_node el, const ParseContext &context); -void parseMetronomeTiedContent(MetronomeTied &out, pugi::xml_node el); - void parseMetronomeTiedContent(MetronomeTied &out, pugi::xml_node el, const ParseContext &context); void serializeMetronomeTied(const MetronomeTied &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/MetronomeTuplet.cpp b/src/private/mx/core/generated/MetronomeTuplet.cpp index 3447d92e4..d99e0caca 100644 --- a/src/private/mx/core/generated/MetronomeTuplet.cpp +++ b/src/private/mx/core/generated/MetronomeTuplet.cpp @@ -41,11 +41,6 @@ void MetronomeTuplet::setShowNumber(std::optional value) m_showNumber = std::move(value); } -MetronomeTuplet parseMetronomeTuplet(pugi::xml_node el) -{ - return parseMetronomeTuplet(el, ParseContext{}); -} - MetronomeTuplet parseMetronomeTuplet(pugi::xml_node el, const ParseContext &context) { MetronomeTuplet out; diff --git a/src/private/mx/core/generated/MetronomeTuplet.h b/src/private/mx/core/generated/MetronomeTuplet.h index c352496ed..c5ebcf6ff 100644 --- a/src/private/mx/core/generated/MetronomeTuplet.h +++ b/src/private/mx/core/generated/MetronomeTuplet.h @@ -41,8 +41,6 @@ class MetronomeTuplet : public TimeModification std::optional m_showNumber; }; -MetronomeTuplet parseMetronomeTuplet(pugi::xml_node el); - MetronomeTuplet parseMetronomeTuplet(pugi::xml_node el, const ParseContext &context); void serializeMetronomeTuplet(const MetronomeTuplet &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Miscellaneous.cpp b/src/private/mx/core/generated/Miscellaneous.cpp index 6a79acc7c..f11673b92 100644 --- a/src/private/mx/core/generated/Miscellaneous.cpp +++ b/src/private/mx/core/generated/Miscellaneous.cpp @@ -26,11 +26,6 @@ void Miscellaneous::setMiscellaneousField(std::vector value) m_miscellaneousField = std::move(value); } -Miscellaneous parseMiscellaneous(pugi::xml_node el) -{ - return parseMiscellaneous(el, ParseContext{}); -} - Miscellaneous parseMiscellaneous(pugi::xml_node el, const ParseContext &context) { Miscellaneous out; @@ -47,11 +42,6 @@ Miscellaneous parseMiscellaneous(pugi::xml_node el, const ParseContext &context) return out; } -void parseMiscellaneousContent(Miscellaneous &out, pugi::xml_node el) -{ - parseMiscellaneousContent(out, el, ParseContext{}); -} - void parseMiscellaneousContent(Miscellaneous &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Miscellaneous.h b/src/private/mx/core/generated/Miscellaneous.h index d4d00d4c0..d7bc41756 100644 --- a/src/private/mx/core/generated/Miscellaneous.h +++ b/src/private/mx/core/generated/Miscellaneous.h @@ -36,12 +36,8 @@ class Miscellaneous final std::vector m_miscellaneousField; }; -Miscellaneous parseMiscellaneous(pugi::xml_node el); - Miscellaneous parseMiscellaneous(pugi::xml_node el, const ParseContext &context); -void parseMiscellaneousContent(Miscellaneous &out, pugi::xml_node el); - void parseMiscellaneousContent(Miscellaneous &out, pugi::xml_node el, const ParseContext &context); void serializeMiscellaneous(const Miscellaneous &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/MiscellaneousField.cpp b/src/private/mx/core/generated/MiscellaneousField.cpp index 781053262..7c648e710 100644 --- a/src/private/mx/core/generated/MiscellaneousField.cpp +++ b/src/private/mx/core/generated/MiscellaneousField.cpp @@ -31,11 +31,6 @@ void MiscellaneousField::setValue(std::string value) m_value = std::move(value); } -MiscellaneousField parseMiscellaneousField(pugi::xml_node el) -{ - return parseMiscellaneousField(el, ParseContext{}); -} - MiscellaneousField parseMiscellaneousField(pugi::xml_node el, const ParseContext &context) { MiscellaneousField out; @@ -65,11 +60,6 @@ MiscellaneousField parseMiscellaneousField(pugi::xml_node el, const ParseContext return out; } -void parseMiscellaneousFieldContent(MiscellaneousField &out, pugi::xml_node el) -{ - parseMiscellaneousFieldContent(out, el, ParseContext{}); -} - void parseMiscellaneousFieldContent(MiscellaneousField &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/MiscellaneousField.h b/src/private/mx/core/generated/MiscellaneousField.h index a70884daa..78dc6aee2 100644 --- a/src/private/mx/core/generated/MiscellaneousField.h +++ b/src/private/mx/core/generated/MiscellaneousField.h @@ -32,12 +32,8 @@ class MiscellaneousField final std::string m_value{}; }; -MiscellaneousField parseMiscellaneousField(pugi::xml_node el); - MiscellaneousField parseMiscellaneousField(pugi::xml_node el, const ParseContext &context); -void parseMiscellaneousFieldContent(MiscellaneousField &out, pugi::xml_node el); - void parseMiscellaneousFieldContent(MiscellaneousField &out, pugi::xml_node el, const ParseContext &context); void serializeMiscellaneousField(const MiscellaneousField &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Mordent.cpp b/src/private/mx/core/generated/Mordent.cpp index 87fa333ee..d9f7322e0 100644 --- a/src/private/mx/core/generated/Mordent.cpp +++ b/src/private/mx/core/generated/Mordent.cpp @@ -41,11 +41,6 @@ void Mordent::setDeparture(std::optional value) m_departure = std::move(value); } -Mordent parseMordent(pugi::xml_node el) -{ - return parseMordent(el, ParseContext{}); -} - Mordent parseMordent(pugi::xml_node el, const ParseContext &context) { Mordent out; diff --git a/src/private/mx/core/generated/Mordent.h b/src/private/mx/core/generated/Mordent.h index e9f30647f..6b5b501fb 100644 --- a/src/private/mx/core/generated/Mordent.h +++ b/src/private/mx/core/generated/Mordent.h @@ -42,8 +42,6 @@ class Mordent : public EmptyTrillSound std::optional m_departure; }; -Mordent parseMordent(pugi::xml_node el); - Mordent parseMordent(pugi::xml_node el, const ParseContext &context); void serializeMordent(const Mordent &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/MultipleRest.cpp b/src/private/mx/core/generated/MultipleRest.cpp index ecfaa0487..ad542e8c9 100644 --- a/src/private/mx/core/generated/MultipleRest.cpp +++ b/src/private/mx/core/generated/MultipleRest.cpp @@ -31,11 +31,6 @@ void MultipleRest::setValue(int value) m_value = std::move(value); } -MultipleRest parseMultipleRest(pugi::xml_node el) -{ - return parseMultipleRest(el, ParseContext{}); -} - MultipleRest parseMultipleRest(pugi::xml_node el, const ParseContext &context) { MultipleRest out; @@ -59,11 +54,6 @@ MultipleRest parseMultipleRest(pugi::xml_node el, const ParseContext &context) return out; } -void parseMultipleRestContent(MultipleRest &out, pugi::xml_node el) -{ - parseMultipleRestContent(out, el, ParseContext{}); -} - void parseMultipleRestContent(MultipleRest &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseIntegerValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/MultipleRest.h b/src/private/mx/core/generated/MultipleRest.h index 04e900f1e..bc7016ef4 100644 --- a/src/private/mx/core/generated/MultipleRest.h +++ b/src/private/mx/core/generated/MultipleRest.h @@ -34,12 +34,8 @@ class MultipleRest final int m_value{}; }; -MultipleRest parseMultipleRest(pugi::xml_node el); - MultipleRest parseMultipleRest(pugi::xml_node el, const ParseContext &context); -void parseMultipleRestContent(MultipleRest &out, pugi::xml_node el); - void parseMultipleRestContent(MultipleRest &out, pugi::xml_node el, const ParseContext &context); void serializeMultipleRest(const MultipleRest &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/MusicDataChoice.cpp b/src/private/mx/core/generated/MusicDataChoice.cpp index 71bf96993..53cfedcaf 100644 --- a/src/private/mx/core/generated/MusicDataChoice.cpp +++ b/src/private/mx/core/generated/MusicDataChoice.cpp @@ -179,11 +179,6 @@ MusicDataChoice MusicDataChoice::bookmark(Bookmark value) return MusicDataChoice{Storage{std::in_place_index<13>, std::make_unique(std::move(value))}}; } -MusicDataChoice parseMusicDataChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseMusicDataChoice(el, cursor, ParseContext{}); -} - MusicDataChoice parseMusicDataChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursorIs(cursor, "note")) diff --git a/src/private/mx/core/generated/MusicDataChoice.h b/src/private/mx/core/generated/MusicDataChoice.h index a80a4e68f..8d709ab23 100644 --- a/src/private/mx/core/generated/MusicDataChoice.h +++ b/src/private/mx/core/generated/MusicDataChoice.h @@ -277,8 +277,6 @@ class MusicDataChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -MusicDataChoice parseMusicDataChoice(pugi::xml_node el, pugi::xml_node &cursor); - MusicDataChoice parseMusicDataChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeMusicDataChoice(const MusicDataChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/NameDisplay.cpp b/src/private/mx/core/generated/NameDisplay.cpp index 029b8e402..31d612127 100644 --- a/src/private/mx/core/generated/NameDisplay.cpp +++ b/src/private/mx/core/generated/NameDisplay.cpp @@ -36,11 +36,6 @@ void NameDisplay::setChoice(std::vector value) m_choice = std::move(value); } -NameDisplay parseNameDisplay(pugi::xml_node el) -{ - return parseNameDisplay(el, ParseContext{}); -} - NameDisplay parseNameDisplay(pugi::xml_node el, const ParseContext &context) { NameDisplay out; @@ -64,11 +59,6 @@ NameDisplay parseNameDisplay(pugi::xml_node el, const ParseContext &context) return out; } -void parseNameDisplayContent(NameDisplay &out, pugi::xml_node el) -{ - parseNameDisplayContent(out, el, ParseContext{}); -} - void parseNameDisplayContent(NameDisplay &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/NameDisplay.h b/src/private/mx/core/generated/NameDisplay.h index 7d4101e00..d495b9dd8 100644 --- a/src/private/mx/core/generated/NameDisplay.h +++ b/src/private/mx/core/generated/NameDisplay.h @@ -41,12 +41,8 @@ class NameDisplay final std::vector m_choice; }; -NameDisplay parseNameDisplay(pugi::xml_node el); - NameDisplay parseNameDisplay(pugi::xml_node el, const ParseContext &context); -void parseNameDisplayContent(NameDisplay &out, pugi::xml_node el); - void parseNameDisplayContent(NameDisplay &out, pugi::xml_node el, const ParseContext &context); void serializeNameDisplay(const NameDisplay &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/NameDisplayChoice.cpp b/src/private/mx/core/generated/NameDisplayChoice.cpp index f10145b50..a779859f5 100644 --- a/src/private/mx/core/generated/NameDisplayChoice.cpp +++ b/src/private/mx/core/generated/NameDisplayChoice.cpp @@ -26,11 +26,6 @@ NameDisplayChoice NameDisplayChoice::accidentalText(AccidentalText value) return NameDisplayChoice{Storage{std::in_place_index<1>, std::move(value)}}; } -NameDisplayChoice parseNameDisplayChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseNameDisplayChoice(el, cursor, ParseContext{}); -} - NameDisplayChoice parseNameDisplayChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "display-text"))) diff --git a/src/private/mx/core/generated/NameDisplayChoice.h b/src/private/mx/core/generated/NameDisplayChoice.h index e9b7d0947..006273fa2 100644 --- a/src/private/mx/core/generated/NameDisplayChoice.h +++ b/src/private/mx/core/generated/NameDisplayChoice.h @@ -82,8 +82,6 @@ class NameDisplayChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -NameDisplayChoice parseNameDisplayChoice(pugi::xml_node el, pugi::xml_node &cursor); - NameDisplayChoice parseNameDisplayChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeNameDisplayChoice(const NameDisplayChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/NonArpeggiate.cpp b/src/private/mx/core/generated/NonArpeggiate.cpp index 7344afe0a..d5ffff2cd 100644 --- a/src/private/mx/core/generated/NonArpeggiate.cpp +++ b/src/private/mx/core/generated/NonArpeggiate.cpp @@ -101,11 +101,6 @@ void NonArpeggiate::setID(std::optional value) m_id = std::move(value); } -NonArpeggiate parseNonArpeggiate(pugi::xml_node el) -{ - return parseNonArpeggiate(el, ParseContext{}); -} - NonArpeggiate parseNonArpeggiate(pugi::xml_node el, const ParseContext &context) { NonArpeggiate out; @@ -167,11 +162,6 @@ NonArpeggiate parseNonArpeggiate(pugi::xml_node el, const ParseContext &context) return out; } -void parseNonArpeggiateContent(NonArpeggiate &out, pugi::xml_node el) -{ - parseNonArpeggiateContent(out, el, ParseContext{}); -} - void parseNonArpeggiateContent(NonArpeggiate &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/NonArpeggiate.h b/src/private/mx/core/generated/NonArpeggiate.h index 438c0f5a8..535e12c52 100644 --- a/src/private/mx/core/generated/NonArpeggiate.h +++ b/src/private/mx/core/generated/NonArpeggiate.h @@ -61,12 +61,8 @@ class NonArpeggiate final std::optional m_id; }; -NonArpeggiate parseNonArpeggiate(pugi::xml_node el); - NonArpeggiate parseNonArpeggiate(pugi::xml_node el, const ParseContext &context); -void parseNonArpeggiateContent(NonArpeggiate &out, pugi::xml_node el); - void parseNonArpeggiateContent(NonArpeggiate &out, pugi::xml_node el, const ParseContext &context); void serializeNonArpeggiate(const NonArpeggiate &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/NonTraditionalKeyGroup.cpp b/src/private/mx/core/generated/NonTraditionalKeyGroup.cpp index d9c8c2d19..3c27407ee 100644 --- a/src/private/mx/core/generated/NonTraditionalKeyGroup.cpp +++ b/src/private/mx/core/generated/NonTraditionalKeyGroup.cpp @@ -41,11 +41,6 @@ void NonTraditionalKeyGroup::setKeyAccidental(std::optional value m_keyAccidental = std::move(value); } -NonTraditionalKeyGroup parseNonTraditionalKeyGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseNonTraditionalKeyGroup(el, cursor, ParseContext{}); -} - NonTraditionalKeyGroup parseNonTraditionalKeyGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { diff --git a/src/private/mx/core/generated/NonTraditionalKeyGroup.h b/src/private/mx/core/generated/NonTraditionalKeyGroup.h index 50b5591df..520923771 100644 --- a/src/private/mx/core/generated/NonTraditionalKeyGroup.h +++ b/src/private/mx/core/generated/NonTraditionalKeyGroup.h @@ -44,8 +44,6 @@ class NonTraditionalKeyGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -NonTraditionalKeyGroup parseNonTraditionalKeyGroup(pugi::xml_node el, pugi::xml_node &cursor); - NonTraditionalKeyGroup parseNonTraditionalKeyGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); diff --git a/src/private/mx/core/generated/NormalNoteGroup.cpp b/src/private/mx/core/generated/NormalNoteGroup.cpp index 281333072..7d25040d5 100644 --- a/src/private/mx/core/generated/NormalNoteGroup.cpp +++ b/src/private/mx/core/generated/NormalNoteGroup.cpp @@ -51,11 +51,6 @@ void NormalNoteGroup::clearTie() noexcept m_tie.clear(); } -NormalNoteGroup parseNormalNoteGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseNormalNoteGroup(el, cursor, ParseContext{}); -} - NormalNoteGroup parseNormalNoteGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { NormalNoteGroup out; diff --git a/src/private/mx/core/generated/NormalNoteGroup.h b/src/private/mx/core/generated/NormalNoteGroup.h index 5a4b48dcf..8f8a98a44 100644 --- a/src/private/mx/core/generated/NormalNoteGroup.h +++ b/src/private/mx/core/generated/NormalNoteGroup.h @@ -47,8 +47,6 @@ class NormalNoteGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -NormalNoteGroup parseNormalNoteGroup(pugi::xml_node el, pugi::xml_node &cursor); - NormalNoteGroup parseNormalNoteGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeNormalNoteGroup(const NormalNoteGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Notations.cpp b/src/private/mx/core/generated/Notations.cpp index b934c6ad4..82f29111b 100644 --- a/src/private/mx/core/generated/Notations.cpp +++ b/src/private/mx/core/generated/Notations.cpp @@ -56,11 +56,6 @@ void Notations::setChoice(std::vector value) m_choice = std::move(value); } -Notations parseNotations(pugi::xml_node el) -{ - return parseNotations(el, ParseContext{}); -} - Notations parseNotations(pugi::xml_node el, const ParseContext &context) { Notations out; @@ -88,11 +83,6 @@ Notations parseNotations(pugi::xml_node el, const ParseContext &context) return out; } -void parseNotationsContent(Notations &out, pugi::xml_node el) -{ - parseNotationsContent(out, el, ParseContext{}); -} - void parseNotationsContent(Notations &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Notations.h b/src/private/mx/core/generated/Notations.h index ce7012dea..3d3405fd3 100644 --- a/src/private/mx/core/generated/Notations.h +++ b/src/private/mx/core/generated/Notations.h @@ -50,12 +50,8 @@ class Notations final std::vector m_choice; }; -Notations parseNotations(pugi::xml_node el); - Notations parseNotations(pugi::xml_node el, const ParseContext &context); -void parseNotationsContent(Notations &out, pugi::xml_node el); - void parseNotationsContent(Notations &out, pugi::xml_node el, const ParseContext &context); void serializeNotations(const Notations &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/NotationsChoice.cpp b/src/private/mx/core/generated/NotationsChoice.cpp index 10a01a14d..5a17727a4 100644 --- a/src/private/mx/core/generated/NotationsChoice.cpp +++ b/src/private/mx/core/generated/NotationsChoice.cpp @@ -86,11 +86,6 @@ NotationsChoice NotationsChoice::otherNotation(OtherNotation value) return NotationsChoice{Storage{std::in_place_index<13>, std::move(value)}}; } -NotationsChoice parseNotationsChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseNotationsChoice(el, cursor, ParseContext{}); -} - NotationsChoice parseNotationsChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "tied"))) diff --git a/src/private/mx/core/generated/NotationsChoice.h b/src/private/mx/core/generated/NotationsChoice.h index bb934b34b..b5a24e8d9 100644 --- a/src/private/mx/core/generated/NotationsChoice.h +++ b/src/private/mx/core/generated/NotationsChoice.h @@ -263,8 +263,6 @@ class NotationsChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -NotationsChoice parseNotationsChoice(pugi::xml_node el, pugi::xml_node &cursor); - NotationsChoice parseNotationsChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeNotationsChoice(const NotationsChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Note.cpp b/src/private/mx/core/generated/Note.cpp index ea7c5aa96..39d3850d0 100644 --- a/src/private/mx/core/generated/Note.cpp +++ b/src/private/mx/core/generated/Note.cpp @@ -411,11 +411,6 @@ void Note::setListen(std::optional value) m_listen = std::move(value); } -Note parseNote(pugi::xml_node el) -{ - return parseNote(el, ParseContext{}); -} - Note parseNote(pugi::xml_node el, const ParseContext &context) { Note out; @@ -519,11 +514,6 @@ Note parseNote(pugi::xml_node el, const ParseContext &context) return out; } -void parseNoteContent(Note &out, pugi::xml_node el) -{ - parseNoteContent(out, el, ParseContext{}); -} - void parseNoteContent(Note &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Note.h b/src/private/mx/core/generated/Note.h index af7c869f6..dd080c6f8 100644 --- a/src/private/mx/core/generated/Note.h +++ b/src/private/mx/core/generated/Note.h @@ -195,12 +195,8 @@ class Note final std::optional m_listen; }; -Note parseNote(pugi::xml_node el); - Note parseNote(pugi::xml_node el, const ParseContext &context); -void parseNoteContent(Note &out, pugi::xml_node el); - void parseNoteContent(Note &out, pugi::xml_node el, const ParseContext &context); void serializeNote(const Note &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/NoteChoice.cpp b/src/private/mx/core/generated/NoteChoice.cpp index d4d59413e..468c6513a 100644 --- a/src/private/mx/core/generated/NoteChoice.cpp +++ b/src/private/mx/core/generated/NoteChoice.cpp @@ -31,11 +31,6 @@ NoteChoice NoteChoice::normalNoteGroup(NormalNoteGroup value) return NoteChoice{Storage{std::in_place_index<2>, std::move(value)}}; } -NoteChoice parseNoteChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseNoteChoice(el, cursor, ParseContext{}); -} - NoteChoice parseNoteChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "grace"))) diff --git a/src/private/mx/core/generated/NoteChoice.h b/src/private/mx/core/generated/NoteChoice.h index a9fe4d6c2..98d824ccd 100644 --- a/src/private/mx/core/generated/NoteChoice.h +++ b/src/private/mx/core/generated/NoteChoice.h @@ -97,8 +97,6 @@ class NoteChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -NoteChoice parseNoteChoice(pugi::xml_node el, pugi::xml_node &cursor); - NoteChoice parseNoteChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeNoteChoice(const NoteChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/NoteSize.cpp b/src/private/mx/core/generated/NoteSize.cpp index 3e9c6ba05..7488a507f 100644 --- a/src/private/mx/core/generated/NoteSize.cpp +++ b/src/private/mx/core/generated/NoteSize.cpp @@ -31,11 +31,6 @@ void NoteSize::setValue(NonNegativeDecimal value) m_value = std::move(value); } -NoteSize parseNoteSize(pugi::xml_node el) -{ - return parseNoteSize(el, ParseContext{}); -} - NoteSize parseNoteSize(pugi::xml_node el, const ParseContext &context) { NoteSize out; @@ -65,11 +60,6 @@ NoteSize parseNoteSize(pugi::xml_node el, const ParseContext &context) return out; } -void parseNoteSizeContent(NoteSize &out, pugi::xml_node el) -{ - parseNoteSizeContent(out, el, ParseContext{}); -} - void parseNoteSizeContent(NoteSize &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/NoteSize.h b/src/private/mx/core/generated/NoteSize.h index 1c853308e..542b1d9df 100644 --- a/src/private/mx/core/generated/NoteSize.h +++ b/src/private/mx/core/generated/NoteSize.h @@ -38,12 +38,8 @@ class NoteSize final NonNegativeDecimal m_value{}; }; -NoteSize parseNoteSize(pugi::xml_node el); - NoteSize parseNoteSize(pugi::xml_node el, const ParseContext &context); -void parseNoteSizeContent(NoteSize &out, pugi::xml_node el); - void parseNoteSizeContent(NoteSize &out, pugi::xml_node el, const ParseContext &context); void serializeNoteSize(const NoteSize &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/NoteType.cpp b/src/private/mx/core/generated/NoteType.cpp index 622f37ab9..342e737d5 100644 --- a/src/private/mx/core/generated/NoteType.cpp +++ b/src/private/mx/core/generated/NoteType.cpp @@ -31,11 +31,6 @@ void NoteType::setValue(NoteTypeValue value) m_value = std::move(value); } -NoteType parseNoteType(pugi::xml_node el) -{ - return parseNoteType(el, ParseContext{}); -} - NoteType parseNoteType(pugi::xml_node el, const ParseContext &context) { NoteType out; @@ -59,11 +54,6 @@ NoteType parseNoteType(pugi::xml_node el, const ParseContext &context) return out; } -void parseNoteTypeContent(NoteType &out, pugi::xml_node el) -{ - parseNoteTypeContent(out, el, ParseContext{}); -} - void parseNoteTypeContent(NoteType &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/NoteType.h b/src/private/mx/core/generated/NoteType.h index 8ebb9cb91..065f4452b 100644 --- a/src/private/mx/core/generated/NoteType.h +++ b/src/private/mx/core/generated/NoteType.h @@ -36,12 +36,8 @@ class NoteType final NoteTypeValue m_value{}; }; -NoteType parseNoteType(pugi::xml_node el); - NoteType parseNoteType(pugi::xml_node el, const ParseContext &context); -void parseNoteTypeContent(NoteType &out, pugi::xml_node el); - void parseNoteTypeContent(NoteType &out, pugi::xml_node el, const ParseContext &context); void serializeNoteType(const NoteType &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Notehead.cpp b/src/private/mx/core/generated/Notehead.cpp index 92f35e2e0..67bd12a65 100644 --- a/src/private/mx/core/generated/Notehead.cpp +++ b/src/private/mx/core/generated/Notehead.cpp @@ -101,11 +101,6 @@ void Notehead::setValue(NoteheadValue value) m_value = std::move(value); } -Notehead parseNotehead(pugi::xml_node el) -{ - return parseNotehead(el, ParseContext{}); -} - Notehead parseNotehead(pugi::xml_node el, const ParseContext &context) { Notehead out; @@ -157,11 +152,6 @@ Notehead parseNotehead(pugi::xml_node el, const ParseContext &context) return out; } -void parseNoteheadContent(Notehead &out, pugi::xml_node el) -{ - parseNoteheadContent(out, el, ParseContext{}); -} - void parseNoteheadContent(Notehead &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/Notehead.h b/src/private/mx/core/generated/Notehead.h index 6fc30f9b0..ce748b29d 100644 --- a/src/private/mx/core/generated/Notehead.h +++ b/src/private/mx/core/generated/Notehead.h @@ -69,12 +69,8 @@ class Notehead final NoteheadValue m_value{}; }; -Notehead parseNotehead(pugi::xml_node el); - Notehead parseNotehead(pugi::xml_node el, const ParseContext &context); -void parseNoteheadContent(Notehead &out, pugi::xml_node el); - void parseNoteheadContent(Notehead &out, pugi::xml_node el, const ParseContext &context); void serializeNotehead(const Notehead &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/NoteheadText.cpp b/src/private/mx/core/generated/NoteheadText.cpp index d294a41a5..6e585d89e 100644 --- a/src/private/mx/core/generated/NoteheadText.cpp +++ b/src/private/mx/core/generated/NoteheadText.cpp @@ -26,11 +26,6 @@ void NoteheadText::setChoice(OneOrMore value) m_choice = std::move(value); } -NoteheadText parseNoteheadText(pugi::xml_node el) -{ - return parseNoteheadText(el, ParseContext{}); -} - NoteheadText parseNoteheadText(pugi::xml_node el, const ParseContext &context) { NoteheadText out; @@ -47,11 +42,6 @@ NoteheadText parseNoteheadText(pugi::xml_node el, const ParseContext &context) return out; } -void parseNoteheadTextContent(NoteheadText &out, pugi::xml_node el) -{ - parseNoteheadTextContent(out, el, ParseContext{}); -} - void parseNoteheadTextContent(NoteheadText &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/NoteheadText.h b/src/private/mx/core/generated/NoteheadText.h index 588797f83..da763dc61 100644 --- a/src/private/mx/core/generated/NoteheadText.h +++ b/src/private/mx/core/generated/NoteheadText.h @@ -38,12 +38,8 @@ class NoteheadText final OneOrMore m_choice; }; -NoteheadText parseNoteheadText(pugi::xml_node el); - NoteheadText parseNoteheadText(pugi::xml_node el, const ParseContext &context); -void parseNoteheadTextContent(NoteheadText &out, pugi::xml_node el); - void parseNoteheadTextContent(NoteheadText &out, pugi::xml_node el, const ParseContext &context); void serializeNoteheadText(const NoteheadText &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/NoteheadTextChoice.cpp b/src/private/mx/core/generated/NoteheadTextChoice.cpp index 3884f46f2..41860403a 100644 --- a/src/private/mx/core/generated/NoteheadTextChoice.cpp +++ b/src/private/mx/core/generated/NoteheadTextChoice.cpp @@ -26,11 +26,6 @@ NoteheadTextChoice NoteheadTextChoice::accidentalText(AccidentalText value) return NoteheadTextChoice{Storage{std::in_place_index<1>, std::move(value)}}; } -NoteheadTextChoice parseNoteheadTextChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseNoteheadTextChoice(el, cursor, ParseContext{}); -} - NoteheadTextChoice parseNoteheadTextChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "display-text"))) diff --git a/src/private/mx/core/generated/NoteheadTextChoice.h b/src/private/mx/core/generated/NoteheadTextChoice.h index 2de216caa..d7e44e641 100644 --- a/src/private/mx/core/generated/NoteheadTextChoice.h +++ b/src/private/mx/core/generated/NoteheadTextChoice.h @@ -82,8 +82,6 @@ class NoteheadTextChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -NoteheadTextChoice parseNoteheadTextChoice(pugi::xml_node el, pugi::xml_node &cursor); - NoteheadTextChoice parseNoteheadTextChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeNoteheadTextChoice(const NoteheadTextChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Numeral.cpp b/src/private/mx/core/generated/Numeral.cpp index b97317b04..3d9fb5df0 100644 --- a/src/private/mx/core/generated/Numeral.cpp +++ b/src/private/mx/core/generated/Numeral.cpp @@ -41,11 +41,6 @@ void Numeral::setNumeralKey(std::optional value) m_numeralKey = std::move(value); } -Numeral parseNumeral(pugi::xml_node el) -{ - return parseNumeral(el, ParseContext{}); -} - Numeral parseNumeral(pugi::xml_node el, const ParseContext &context) { Numeral out; @@ -62,11 +57,6 @@ Numeral parseNumeral(pugi::xml_node el, const ParseContext &context) return out; } -void parseNumeralContent(Numeral &out, pugi::xml_node el) -{ - parseNumeralContent(out, el, ParseContext{}); -} - void parseNumeralContent(Numeral &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Numeral.h b/src/private/mx/core/generated/Numeral.h index 1b0b4475c..27895a0a1 100644 --- a/src/private/mx/core/generated/Numeral.h +++ b/src/private/mx/core/generated/Numeral.h @@ -42,12 +42,8 @@ class Numeral final std::optional m_numeralKey; }; -Numeral parseNumeral(pugi::xml_node el); - Numeral parseNumeral(pugi::xml_node el, const ParseContext &context); -void parseNumeralContent(Numeral &out, pugi::xml_node el); - void parseNumeralContent(Numeral &out, pugi::xml_node el, const ParseContext &context); void serializeNumeral(const Numeral &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/NumeralKey.cpp b/src/private/mx/core/generated/NumeralKey.cpp index 7895796fa..1d00d400c 100644 --- a/src/private/mx/core/generated/NumeralKey.cpp +++ b/src/private/mx/core/generated/NumeralKey.cpp @@ -41,11 +41,6 @@ void NumeralKey::setNumeralMode(NumeralMode value) m_numeralMode = std::move(value); } -NumeralKey parseNumeralKey(pugi::xml_node el) -{ - return parseNumeralKey(el, ParseContext{}); -} - NumeralKey parseNumeralKey(pugi::xml_node el, const ParseContext &context) { NumeralKey out; @@ -69,11 +64,6 @@ NumeralKey parseNumeralKey(pugi::xml_node el, const ParseContext &context) return out; } -void parseNumeralKeyContent(NumeralKey &out, pugi::xml_node el) -{ - parseNumeralKeyContent(out, el, ParseContext{}); -} - void parseNumeralKeyContent(NumeralKey &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/NumeralKey.h b/src/private/mx/core/generated/NumeralKey.h index 08bd02a4b..8751da2da 100644 --- a/src/private/mx/core/generated/NumeralKey.h +++ b/src/private/mx/core/generated/NumeralKey.h @@ -44,12 +44,8 @@ class NumeralKey final NumeralMode m_numeralMode{}; }; -NumeralKey parseNumeralKey(pugi::xml_node el); - NumeralKey parseNumeralKey(pugi::xml_node el, const ParseContext &context); -void parseNumeralKeyContent(NumeralKey &out, pugi::xml_node el); - void parseNumeralKeyContent(NumeralKey &out, pugi::xml_node el, const ParseContext &context); void serializeNumeralKey(const NumeralKey &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/NumeralRoot.cpp b/src/private/mx/core/generated/NumeralRoot.cpp index 74f95e76e..66a291176 100644 --- a/src/private/mx/core/generated/NumeralRoot.cpp +++ b/src/private/mx/core/generated/NumeralRoot.cpp @@ -121,11 +121,6 @@ void NumeralRoot::setValue(NumeralValue value) m_value = std::move(value); } -NumeralRoot parseNumeralRoot(pugi::xml_node el) -{ - return parseNumeralRoot(el, ParseContext{}); -} - NumeralRoot parseNumeralRoot(pugi::xml_node el, const ParseContext &context) { NumeralRoot out; @@ -185,11 +180,6 @@ NumeralRoot parseNumeralRoot(pugi::xml_node el, const ParseContext &context) return out; } -void parseNumeralRootContent(NumeralRoot &out, pugi::xml_node el) -{ - parseNumeralRootContent(out, el, ParseContext{}); -} - void parseNumeralRootContent(NumeralRoot &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/NumeralRoot.h b/src/private/mx/core/generated/NumeralRoot.h index 2e28ff007..15ae787fb 100644 --- a/src/private/mx/core/generated/NumeralRoot.h +++ b/src/private/mx/core/generated/NumeralRoot.h @@ -69,12 +69,8 @@ class NumeralRoot final NumeralValue m_value{}; }; -NumeralRoot parseNumeralRoot(pugi::xml_node el); - NumeralRoot parseNumeralRoot(pugi::xml_node el, const ParseContext &context); -void parseNumeralRootContent(NumeralRoot &out, pugi::xml_node el); - void parseNumeralRootContent(NumeralRoot &out, pugi::xml_node el, const ParseContext &context); void serializeNumeralRoot(const NumeralRoot &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/OctaveShift.cpp b/src/private/mx/core/generated/OctaveShift.cpp index 60dd371b7..e631528dd 100644 --- a/src/private/mx/core/generated/OctaveShift.cpp +++ b/src/private/mx/core/generated/OctaveShift.cpp @@ -161,11 +161,6 @@ void OctaveShift::setID(std::optional value) m_id = std::move(value); } -OctaveShift parseOctaveShift(pugi::xml_node el) -{ - return parseOctaveShift(el, ParseContext{}); -} - OctaveShift parseOctaveShift(pugi::xml_node el, const ParseContext &context) { OctaveShift out; @@ -251,11 +246,6 @@ OctaveShift parseOctaveShift(pugi::xml_node el, const ParseContext &context) return out; } -void parseOctaveShiftContent(OctaveShift &out, pugi::xml_node el) -{ - parseOctaveShiftContent(out, el, ParseContext{}); -} - void parseOctaveShiftContent(OctaveShift &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/OctaveShift.h b/src/private/mx/core/generated/OctaveShift.h index d5ac32833..ab876f5e0 100644 --- a/src/private/mx/core/generated/OctaveShift.h +++ b/src/private/mx/core/generated/OctaveShift.h @@ -83,12 +83,8 @@ class OctaveShift final std::optional m_id; }; -OctaveShift parseOctaveShift(pugi::xml_node el); - OctaveShift parseOctaveShift(pugi::xml_node el, const ParseContext &context); -void parseOctaveShiftContent(OctaveShift &out, pugi::xml_node el); - void parseOctaveShiftContent(OctaveShift &out, pugi::xml_node el, const ParseContext &context); void serializeOctaveShift(const OctaveShift &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Offset.cpp b/src/private/mx/core/generated/Offset.cpp index e5cdea0dc..3c6652bf7 100644 --- a/src/private/mx/core/generated/Offset.cpp +++ b/src/private/mx/core/generated/Offset.cpp @@ -31,11 +31,6 @@ void Offset::setValue(Divisions value) m_value = std::move(value); } -Offset parseOffset(pugi::xml_node el) -{ - return parseOffset(el, ParseContext{}); -} - Offset parseOffset(pugi::xml_node el, const ParseContext &context) { Offset out; @@ -59,11 +54,6 @@ Offset parseOffset(pugi::xml_node el, const ParseContext &context) return out; } -void parseOffsetContent(Offset &out, pugi::xml_node el) -{ - parseOffsetContent(out, el, ParseContext{}); -} - void parseOffsetContent(Offset &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/Offset.h b/src/private/mx/core/generated/Offset.h index ffa7a53b4..d7714e79b 100644 --- a/src/private/mx/core/generated/Offset.h +++ b/src/private/mx/core/generated/Offset.h @@ -40,12 +40,8 @@ class Offset final Divisions m_value{}; }; -Offset parseOffset(pugi::xml_node el); - Offset parseOffset(pugi::xml_node el, const ParseContext &context); -void parseOffsetContent(Offset &out, pugi::xml_node el); - void parseOffsetContent(Offset &out, pugi::xml_node el, const ParseContext &context); void serializeOffset(const Offset &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Opus.cpp b/src/private/mx/core/generated/Opus.cpp index 611850bc7..2f331312e 100644 --- a/src/private/mx/core/generated/Opus.cpp +++ b/src/private/mx/core/generated/Opus.cpp @@ -71,11 +71,6 @@ void Opus::setXlinkActuate(std::optional value) m_xlinkActuate = std::move(value); } -Opus parseOpus(pugi::xml_node el) -{ - return parseOpus(el, ParseContext{}); -} - Opus parseOpus(pugi::xml_node el, const ParseContext &context) { Opus out; @@ -125,11 +120,6 @@ Opus parseOpus(pugi::xml_node el, const ParseContext &context) return out; } -void parseOpusContent(Opus &out, pugi::xml_node el) -{ - parseOpusContent(out, el, ParseContext{}); -} - void parseOpusContent(Opus &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/Opus.h b/src/private/mx/core/generated/Opus.h index f1b1fb9bd..f0d909290 100644 --- a/src/private/mx/core/generated/Opus.h +++ b/src/private/mx/core/generated/Opus.h @@ -43,12 +43,8 @@ class Opus final std::optional m_xlinkActuate; }; -Opus parseOpus(pugi::xml_node el); - Opus parseOpus(pugi::xml_node el, const ParseContext &context); -void parseOpusContent(Opus &out, pugi::xml_node el); - void parseOpusContent(Opus &out, pugi::xml_node el, const ParseContext &context); void serializeOpus(const Opus &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Ornaments.cpp b/src/private/mx/core/generated/Ornaments.cpp index 3902e154b..f65ec1d7c 100644 --- a/src/private/mx/core/generated/Ornaments.cpp +++ b/src/private/mx/core/generated/Ornaments.cpp @@ -36,11 +36,6 @@ void Ornaments::setGroup(std::vector value) m_group = std::move(value); } -Ornaments parseOrnaments(pugi::xml_node el) -{ - return parseOrnaments(el, ParseContext{}); -} - Ornaments parseOrnaments(pugi::xml_node el, const ParseContext &context) { Ornaments out; @@ -64,11 +59,6 @@ Ornaments parseOrnaments(pugi::xml_node el, const ParseContext &context) return out; } -void parseOrnamentsContent(Ornaments &out, pugi::xml_node el) -{ - parseOrnamentsContent(out, el, ParseContext{}); -} - void parseOrnamentsContent(Ornaments &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Ornaments.h b/src/private/mx/core/generated/Ornaments.h index 8d5246f0b..2dc2aad7d 100644 --- a/src/private/mx/core/generated/Ornaments.h +++ b/src/private/mx/core/generated/Ornaments.h @@ -41,12 +41,8 @@ class Ornaments final std::vector m_group; }; -Ornaments parseOrnaments(pugi::xml_node el); - Ornaments parseOrnaments(pugi::xml_node el, const ParseContext &context); -void parseOrnamentsContent(Ornaments &out, pugi::xml_node el); - void parseOrnamentsContent(Ornaments &out, pugi::xml_node el, const ParseContext &context); void serializeOrnaments(const Ornaments &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/OrnamentsGroup.cpp b/src/private/mx/core/generated/OrnamentsGroup.cpp index d732dc5a7..4109d63c1 100644 --- a/src/private/mx/core/generated/OrnamentsGroup.cpp +++ b/src/private/mx/core/generated/OrnamentsGroup.cpp @@ -36,11 +36,6 @@ void OrnamentsGroup::setAccidentalMark(std::vector value) m_accidentalMark = std::move(value); } -OrnamentsGroup parseOrnamentsGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseOrnamentsGroup(el, cursor, ParseContext{}); -} - OrnamentsGroup parseOrnamentsGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { OrnamentsGroup out; diff --git a/src/private/mx/core/generated/OrnamentsGroup.h b/src/private/mx/core/generated/OrnamentsGroup.h index 202d09a02..143cd90c7 100644 --- a/src/private/mx/core/generated/OrnamentsGroup.h +++ b/src/private/mx/core/generated/OrnamentsGroup.h @@ -40,8 +40,6 @@ class OrnamentsGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -OrnamentsGroup parseOrnamentsGroup(pugi::xml_node el, pugi::xml_node &cursor); - OrnamentsGroup parseOrnamentsGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeOrnamentsGroup(const OrnamentsGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/OrnamentsGroupChoice.cpp b/src/private/mx/core/generated/OrnamentsGroupChoice.cpp index e72220c8b..0aad7046e 100644 --- a/src/private/mx/core/generated/OrnamentsGroupChoice.cpp +++ b/src/private/mx/core/generated/OrnamentsGroupChoice.cpp @@ -91,11 +91,6 @@ OrnamentsGroupChoice OrnamentsGroupChoice::otherOrnament(OtherPlacementText valu return OrnamentsGroupChoice{Storage{std::in_place_index<14>, std::move(value)}}; } -OrnamentsGroupChoice parseOrnamentsGroupChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseOrnamentsGroupChoice(el, cursor, ParseContext{}); -} - OrnamentsGroupChoice parseOrnamentsGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "trill-mark"))) diff --git a/src/private/mx/core/generated/OrnamentsGroupChoice.h b/src/private/mx/core/generated/OrnamentsGroupChoice.h index d003f6b8c..a88570880 100644 --- a/src/private/mx/core/generated/OrnamentsGroupChoice.h +++ b/src/private/mx/core/generated/OrnamentsGroupChoice.h @@ -271,8 +271,6 @@ class OrnamentsGroupChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -OrnamentsGroupChoice parseOrnamentsGroupChoice(pugi::xml_node el, pugi::xml_node &cursor); - OrnamentsGroupChoice parseOrnamentsGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeOrnamentsGroupChoice(const OrnamentsGroupChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/OtherAppearance.cpp b/src/private/mx/core/generated/OtherAppearance.cpp index ef3bbbc06..0768ac546 100644 --- a/src/private/mx/core/generated/OtherAppearance.cpp +++ b/src/private/mx/core/generated/OtherAppearance.cpp @@ -31,11 +31,6 @@ void OtherAppearance::setValue(std::string value) m_value = std::move(value); } -OtherAppearance parseOtherAppearance(pugi::xml_node el) -{ - return parseOtherAppearance(el, ParseContext{}); -} - OtherAppearance parseOtherAppearance(pugi::xml_node el, const ParseContext &context) { OtherAppearance out; @@ -65,11 +60,6 @@ OtherAppearance parseOtherAppearance(pugi::xml_node el, const ParseContext &cont return out; } -void parseOtherAppearanceContent(OtherAppearance &out, pugi::xml_node el) -{ - parseOtherAppearanceContent(out, el, ParseContext{}); -} - void parseOtherAppearanceContent(OtherAppearance &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/OtherAppearance.h b/src/private/mx/core/generated/OtherAppearance.h index bf266f212..d29ce5a36 100644 --- a/src/private/mx/core/generated/OtherAppearance.h +++ b/src/private/mx/core/generated/OtherAppearance.h @@ -32,12 +32,8 @@ class OtherAppearance final std::string m_value{}; }; -OtherAppearance parseOtherAppearance(pugi::xml_node el); - OtherAppearance parseOtherAppearance(pugi::xml_node el, const ParseContext &context); -void parseOtherAppearanceContent(OtherAppearance &out, pugi::xml_node el); - void parseOtherAppearanceContent(OtherAppearance &out, pugi::xml_node el, const ParseContext &context); void serializeOtherAppearance(const OtherAppearance &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/OtherDirection.cpp b/src/private/mx/core/generated/OtherDirection.cpp index 8edcd06ad..1d4e0e971 100644 --- a/src/private/mx/core/generated/OtherDirection.cpp +++ b/src/private/mx/core/generated/OtherDirection.cpp @@ -161,11 +161,6 @@ void OtherDirection::setValue(std::string value) m_value = std::move(value); } -OtherDirection parseOtherDirection(pugi::xml_node el) -{ - return parseOtherDirection(el, ParseContext{}); -} - OtherDirection parseOtherDirection(pugi::xml_node el, const ParseContext &context) { OtherDirection out; @@ -241,11 +236,6 @@ OtherDirection parseOtherDirection(pugi::xml_node el, const ParseContext &contex return out; } -void parseOtherDirectionContent(OtherDirection &out, pugi::xml_node el) -{ - parseOtherDirectionContent(out, el, ParseContext{}); -} - void parseOtherDirectionContent(OtherDirection &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/OtherDirection.h b/src/private/mx/core/generated/OtherDirection.h index d82ab4a6b..94cad53a2 100644 --- a/src/private/mx/core/generated/OtherDirection.h +++ b/src/private/mx/core/generated/OtherDirection.h @@ -86,12 +86,8 @@ class OtherDirection final std::string m_value{}; }; -OtherDirection parseOtherDirection(pugi::xml_node el); - OtherDirection parseOtherDirection(pugi::xml_node el, const ParseContext &context); -void parseOtherDirectionContent(OtherDirection &out, pugi::xml_node el); - void parseOtherDirectionContent(OtherDirection &out, pugi::xml_node el, const ParseContext &context); void serializeOtherDirection(const OtherDirection &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/OtherListening.cpp b/src/private/mx/core/generated/OtherListening.cpp index 35be37198..79db3c92f 100644 --- a/src/private/mx/core/generated/OtherListening.cpp +++ b/src/private/mx/core/generated/OtherListening.cpp @@ -51,11 +51,6 @@ void OtherListening::setValue(std::string value) m_value = std::move(value); } -OtherListening parseOtherListening(pugi::xml_node el) -{ - return parseOtherListening(el, ParseContext{}); -} - OtherListening parseOtherListening(pugi::xml_node el, const ParseContext &context) { OtherListening out; @@ -93,11 +88,6 @@ OtherListening parseOtherListening(pugi::xml_node el, const ParseContext &contex return out; } -void parseOtherListeningContent(OtherListening &out, pugi::xml_node el) -{ - parseOtherListeningContent(out, el, ParseContext{}); -} - void parseOtherListeningContent(OtherListening &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/OtherListening.h b/src/private/mx/core/generated/OtherListening.h index a12dc0047..7756bd516 100644 --- a/src/private/mx/core/generated/OtherListening.h +++ b/src/private/mx/core/generated/OtherListening.h @@ -43,12 +43,8 @@ class OtherListening final std::string m_value{}; }; -OtherListening parseOtherListening(pugi::xml_node el); - OtherListening parseOtherListening(pugi::xml_node el, const ParseContext &context); -void parseOtherListeningContent(OtherListening &out, pugi::xml_node el); - void parseOtherListeningContent(OtherListening &out, pugi::xml_node el, const ParseContext &context); void serializeOtherListening(const OtherListening &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/OtherNotation.cpp b/src/private/mx/core/generated/OtherNotation.cpp index 1cdf7ca7b..3879c0774 100644 --- a/src/private/mx/core/generated/OtherNotation.cpp +++ b/src/private/mx/core/generated/OtherNotation.cpp @@ -171,11 +171,6 @@ void OtherNotation::setValue(std::string value) m_value = std::move(value); } -OtherNotation parseOtherNotation(pugi::xml_node el) -{ - return parseOtherNotation(el, ParseContext{}); -} - OtherNotation parseOtherNotation(pugi::xml_node el, const ParseContext &context) { OtherNotation out; @@ -261,11 +256,6 @@ OtherNotation parseOtherNotation(pugi::xml_node el, const ParseContext &context) return out; } -void parseOtherNotationContent(OtherNotation &out, pugi::xml_node el) -{ - parseOtherNotationContent(out, el, ParseContext{}); -} - void parseOtherNotationContent(OtherNotation &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/OtherNotation.h b/src/private/mx/core/generated/OtherNotation.h index bdc47c9c9..a81d26f1a 100644 --- a/src/private/mx/core/generated/OtherNotation.h +++ b/src/private/mx/core/generated/OtherNotation.h @@ -91,12 +91,8 @@ class OtherNotation final std::string m_value{}; }; -OtherNotation parseOtherNotation(pugi::xml_node el); - OtherNotation parseOtherNotation(pugi::xml_node el, const ParseContext &context); -void parseOtherNotationContent(OtherNotation &out, pugi::xml_node el); - void parseOtherNotationContent(OtherNotation &out, pugi::xml_node el, const ParseContext &context); void serializeOtherNotation(const OtherNotation &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/OtherPlacementText.cpp b/src/private/mx/core/generated/OtherPlacementText.cpp index 31a898008..2d9a3b383 100644 --- a/src/private/mx/core/generated/OtherPlacementText.cpp +++ b/src/private/mx/core/generated/OtherPlacementText.cpp @@ -131,11 +131,6 @@ void OtherPlacementText::setValue(std::string value) m_value = std::move(value); } -OtherPlacementText parseOtherPlacementText(pugi::xml_node el) -{ - return parseOtherPlacementText(el, ParseContext{}); -} - OtherPlacementText parseOtherPlacementText(pugi::xml_node el, const ParseContext &context) { OtherPlacementText out; @@ -199,11 +194,6 @@ OtherPlacementText parseOtherPlacementText(pugi::xml_node el, const ParseContext return out; } -void parseOtherPlacementTextContent(OtherPlacementText &out, pugi::xml_node el) -{ - parseOtherPlacementTextContent(out, el, ParseContext{}); -} - void parseOtherPlacementTextContent(OtherPlacementText &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/OtherPlacementText.h b/src/private/mx/core/generated/OtherPlacementText.h index 265b9a1c1..6ade71f62 100644 --- a/src/private/mx/core/generated/OtherPlacementText.h +++ b/src/private/mx/core/generated/OtherPlacementText.h @@ -71,12 +71,8 @@ class OtherPlacementText final std::string m_value{}; }; -OtherPlacementText parseOtherPlacementText(pugi::xml_node el); - OtherPlacementText parseOtherPlacementText(pugi::xml_node el, const ParseContext &context); -void parseOtherPlacementTextContent(OtherPlacementText &out, pugi::xml_node el); - void parseOtherPlacementTextContent(OtherPlacementText &out, pugi::xml_node el, const ParseContext &context); void serializeOtherPlacementText(const OtherPlacementText &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/OtherPlay.cpp b/src/private/mx/core/generated/OtherPlay.cpp index 8a2c2f320..09170e3b2 100644 --- a/src/private/mx/core/generated/OtherPlay.cpp +++ b/src/private/mx/core/generated/OtherPlay.cpp @@ -31,11 +31,6 @@ void OtherPlay::setValue(std::string value) m_value = std::move(value); } -OtherPlay parseOtherPlay(pugi::xml_node el) -{ - return parseOtherPlay(el, ParseContext{}); -} - OtherPlay parseOtherPlay(pugi::xml_node el, const ParseContext &context) { OtherPlay out; @@ -65,11 +60,6 @@ OtherPlay parseOtherPlay(pugi::xml_node el, const ParseContext &context) return out; } -void parseOtherPlayContent(OtherPlay &out, pugi::xml_node el) -{ - parseOtherPlayContent(out, el, ParseContext{}); -} - void parseOtherPlayContent(OtherPlay &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/OtherPlay.h b/src/private/mx/core/generated/OtherPlay.h index 574af0c71..2d6dfb796 100644 --- a/src/private/mx/core/generated/OtherPlay.h +++ b/src/private/mx/core/generated/OtherPlay.h @@ -31,12 +31,8 @@ class OtherPlay final std::string m_value{}; }; -OtherPlay parseOtherPlay(pugi::xml_node el); - OtherPlay parseOtherPlay(pugi::xml_node el, const ParseContext &context); -void parseOtherPlayContent(OtherPlay &out, pugi::xml_node el); - void parseOtherPlayContent(OtherPlay &out, pugi::xml_node el, const ParseContext &context); void serializeOtherPlay(const OtherPlay &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/OtherText.cpp b/src/private/mx/core/generated/OtherText.cpp index 17076e729..b4a23f24a 100644 --- a/src/private/mx/core/generated/OtherText.cpp +++ b/src/private/mx/core/generated/OtherText.cpp @@ -31,11 +31,6 @@ void OtherText::setValue(std::string value) m_value = std::move(value); } -OtherText parseOtherText(pugi::xml_node el) -{ - return parseOtherText(el, ParseContext{}); -} - OtherText parseOtherText(pugi::xml_node el, const ParseContext &context) { OtherText out; @@ -59,11 +54,6 @@ OtherText parseOtherText(pugi::xml_node el, const ParseContext &context) return out; } -void parseOtherTextContent(OtherText &out, pugi::xml_node el) -{ - parseOtherTextContent(out, el, ParseContext{}); -} - void parseOtherTextContent(OtherText &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/OtherText.h b/src/private/mx/core/generated/OtherText.h index 00f2e627d..801638e79 100644 --- a/src/private/mx/core/generated/OtherText.h +++ b/src/private/mx/core/generated/OtherText.h @@ -34,12 +34,8 @@ class OtherText final std::string m_value{}; }; -OtherText parseOtherText(pugi::xml_node el); - OtherText parseOtherText(pugi::xml_node el, const ParseContext &context); -void parseOtherTextContent(OtherText &out, pugi::xml_node el); - void parseOtherTextContent(OtherText &out, pugi::xml_node el, const ParseContext &context); void serializeOtherText(const OtherText &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/PageLayout.cpp b/src/private/mx/core/generated/PageLayout.cpp index 1637d6cce..de9037b83 100644 --- a/src/private/mx/core/generated/PageLayout.cpp +++ b/src/private/mx/core/generated/PageLayout.cpp @@ -41,11 +41,6 @@ void PageLayout::clearPageMargins() noexcept m_pageMargins.clear(); } -PageLayout parsePageLayout(pugi::xml_node el) -{ - return parsePageLayout(el, ParseContext{}); -} - PageLayout parsePageLayout(pugi::xml_node el, const ParseContext &context) { PageLayout out; @@ -62,11 +57,6 @@ PageLayout parsePageLayout(pugi::xml_node el, const ParseContext &context) return out; } -void parsePageLayoutContent(PageLayout &out, pugi::xml_node el) -{ - parsePageLayoutContent(out, el, ParseContext{}); -} - void parsePageLayoutContent(PageLayout &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/PageLayout.h b/src/private/mx/core/generated/PageLayout.h index 2d669c0a3..152a04bbf 100644 --- a/src/private/mx/core/generated/PageLayout.h +++ b/src/private/mx/core/generated/PageLayout.h @@ -49,12 +49,8 @@ class PageLayout final std::vector m_pageMargins; }; -PageLayout parsePageLayout(pugi::xml_node el); - PageLayout parsePageLayout(pugi::xml_node el, const ParseContext &context); -void parsePageLayoutContent(PageLayout &out, pugi::xml_node el); - void parsePageLayoutContent(PageLayout &out, pugi::xml_node el, const ParseContext &context); void serializePageLayout(const PageLayout &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/PageLayoutGroup.cpp b/src/private/mx/core/generated/PageLayoutGroup.cpp index d9ae8c776..e5d6639dd 100644 --- a/src/private/mx/core/generated/PageLayoutGroup.cpp +++ b/src/private/mx/core/generated/PageLayoutGroup.cpp @@ -31,11 +31,6 @@ void PageLayoutGroup::setPageWidth(Tenths value) m_pageWidth = std::move(value); } -PageLayoutGroup parsePageLayoutGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parsePageLayoutGroup(el, cursor, ParseContext{}); -} - PageLayoutGroup parsePageLayoutGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { PageLayoutGroup out; diff --git a/src/private/mx/core/generated/PageLayoutGroup.h b/src/private/mx/core/generated/PageLayoutGroup.h index 3c8438325..ac19e680e 100644 --- a/src/private/mx/core/generated/PageLayoutGroup.h +++ b/src/private/mx/core/generated/PageLayoutGroup.h @@ -38,8 +38,6 @@ class PageLayoutGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -PageLayoutGroup parsePageLayoutGroup(pugi::xml_node el, pugi::xml_node &cursor); - PageLayoutGroup parsePageLayoutGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializePageLayoutGroup(const PageLayoutGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/PageMargins.cpp b/src/private/mx/core/generated/PageMargins.cpp index 7f13b4905..0990ab028 100644 --- a/src/private/mx/core/generated/PageMargins.cpp +++ b/src/private/mx/core/generated/PageMargins.cpp @@ -31,11 +31,6 @@ void PageMargins::setAllMargins(AllMarginsGroup value) m_allMargins = std::move(value); } -PageMargins parsePageMargins(pugi::xml_node el) -{ - return parsePageMargins(el, ParseContext{}); -} - PageMargins parsePageMargins(pugi::xml_node el, const ParseContext &context) { PageMargins out; @@ -59,11 +54,6 @@ PageMargins parsePageMargins(pugi::xml_node el, const ParseContext &context) return out; } -void parsePageMarginsContent(PageMargins &out, pugi::xml_node el) -{ - parsePageMarginsContent(out, el, ParseContext{}); -} - void parsePageMarginsContent(PageMargins &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/PageMargins.h b/src/private/mx/core/generated/PageMargins.h index e1417f17d..d5ab1da36 100644 --- a/src/private/mx/core/generated/PageMargins.h +++ b/src/private/mx/core/generated/PageMargins.h @@ -39,12 +39,8 @@ class PageMargins final AllMarginsGroup m_allMargins{}; }; -PageMargins parsePageMargins(pugi::xml_node el); - PageMargins parsePageMargins(pugi::xml_node el, const ParseContext &context); -void parsePageMarginsContent(PageMargins &out, pugi::xml_node el); - void parsePageMarginsContent(PageMargins &out, pugi::xml_node el, const ParseContext &context); void serializePageMargins(const PageMargins &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/PartClef.cpp b/src/private/mx/core/generated/PartClef.cpp index 022532edd..99aa74e4c 100644 --- a/src/private/mx/core/generated/PartClef.cpp +++ b/src/private/mx/core/generated/PartClef.cpp @@ -21,11 +21,6 @@ void PartClef::setClef(ClefGroup value) m_clef = std::move(value); } -PartClef parsePartClef(pugi::xml_node el) -{ - return parsePartClef(el, ParseContext{}); -} - PartClef parsePartClef(pugi::xml_node el, const ParseContext &context) { PartClef out; @@ -42,11 +37,6 @@ PartClef parsePartClef(pugi::xml_node el, const ParseContext &context) return out; } -void parsePartClefContent(PartClef &out, pugi::xml_node el) -{ - parsePartClefContent(out, el, ParseContext{}); -} - void parsePartClefContent(PartClef &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/PartClef.h b/src/private/mx/core/generated/PartClef.h index 6503eefc4..854fbdd45 100644 --- a/src/private/mx/core/generated/PartClef.h +++ b/src/private/mx/core/generated/PartClef.h @@ -34,12 +34,8 @@ class PartClef final ClefGroup m_clef{}; }; -PartClef parsePartClef(pugi::xml_node el); - PartClef parsePartClef(pugi::xml_node el, const ParseContext &context); -void parsePartClefContent(PartClef &out, pugi::xml_node el); - void parsePartClefContent(PartClef &out, pugi::xml_node el, const ParseContext &context); void serializePartClef(const PartClef &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/PartGroup.cpp b/src/private/mx/core/generated/PartGroup.cpp index 26c6df2fe..1b847372d 100644 --- a/src/private/mx/core/generated/PartGroup.cpp +++ b/src/private/mx/core/generated/PartGroup.cpp @@ -111,11 +111,6 @@ void PartGroup::setEditorial(EditorialGroup value) m_editorial = std::move(value); } -PartGroup parsePartGroup(pugi::xml_node el) -{ - return parsePartGroup(el, ParseContext{}); -} - PartGroup parsePartGroup(pugi::xml_node el, const ParseContext &context) { PartGroup out; @@ -149,11 +144,6 @@ PartGroup parsePartGroup(pugi::xml_node el, const ParseContext &context) return out; } -void parsePartGroupContent(PartGroup &out, pugi::xml_node el) -{ - parsePartGroupContent(out, el, ParseContext{}); -} - void parsePartGroupContent(PartGroup &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/PartGroup.h b/src/private/mx/core/generated/PartGroup.h index 9b729f10c..66415983d 100644 --- a/src/private/mx/core/generated/PartGroup.h +++ b/src/private/mx/core/generated/PartGroup.h @@ -75,12 +75,8 @@ class PartGroup final EditorialGroup m_editorial{}; }; -PartGroup parsePartGroup(pugi::xml_node el); - PartGroup parsePartGroup(pugi::xml_node el, const ParseContext &context); -void parsePartGroupContent(PartGroup &out, pugi::xml_node el); - void parsePartGroupContent(PartGroup &out, pugi::xml_node el, const ParseContext &context); void serializePartGroup(const PartGroup &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/PartLink.cpp b/src/private/mx/core/generated/PartLink.cpp index 6c733a3d4..be001b290 100644 --- a/src/private/mx/core/generated/PartLink.cpp +++ b/src/private/mx/core/generated/PartLink.cpp @@ -101,11 +101,6 @@ void PartLink::setGroupLink(std::vector value) m_groupLink = std::move(value); } -PartLink parsePartLink(pugi::xml_node el) -{ - return parsePartLink(el, ParseContext{}); -} - PartLink parsePartLink(pugi::xml_node el, const ParseContext &context) { PartLink out; @@ -155,11 +150,6 @@ PartLink parsePartLink(pugi::xml_node el, const ParseContext &context) return out; } -void parsePartLinkContent(PartLink &out, pugi::xml_node el) -{ - parsePartLinkContent(out, el, ParseContext{}); -} - void parsePartLinkContent(PartLink &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/PartLink.h b/src/private/mx/core/generated/PartLink.h index a864a915b..3b87682db 100644 --- a/src/private/mx/core/generated/PartLink.h +++ b/src/private/mx/core/generated/PartLink.h @@ -59,12 +59,8 @@ class PartLink final std::vector m_groupLink; }; -PartLink parsePartLink(pugi::xml_node el); - PartLink parsePartLink(pugi::xml_node el, const ParseContext &context); -void parsePartLinkContent(PartLink &out, pugi::xml_node el); - void parsePartLinkContent(PartLink &out, pugi::xml_node el, const ParseContext &context); void serializePartLink(const PartLink &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/PartList.cpp b/src/private/mx/core/generated/PartList.cpp index 48f14320d..d783dcd3f 100644 --- a/src/private/mx/core/generated/PartList.cpp +++ b/src/private/mx/core/generated/PartList.cpp @@ -51,11 +51,6 @@ void PartList::setChoice(std::vector value) m_choice = std::move(value); } -PartList parsePartList(pugi::xml_node el) -{ - return parsePartList(el, ParseContext{}); -} - PartList parsePartList(pugi::xml_node el, const ParseContext &context) { PartList out; @@ -72,11 +67,6 @@ PartList parsePartList(pugi::xml_node el, const ParseContext &context) return out; } -void parsePartListContent(PartList &out, pugi::xml_node el) -{ - parsePartListContent(out, el, ParseContext{}); -} - void parsePartListContent(PartList &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/PartList.h b/src/private/mx/core/generated/PartList.h index 360c58bc4..4276e9936 100644 --- a/src/private/mx/core/generated/PartList.h +++ b/src/private/mx/core/generated/PartList.h @@ -48,12 +48,8 @@ class PartList final std::vector m_choice; }; -PartList parsePartList(pugi::xml_node el); - PartList parsePartList(pugi::xml_node el, const ParseContext &context); -void parsePartListContent(PartList &out, pugi::xml_node el); - void parsePartListContent(PartList &out, pugi::xml_node el, const ParseContext &context); void serializePartList(const PartList &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/PartListChoice.cpp b/src/private/mx/core/generated/PartListChoice.cpp index fe25275b2..d2776c30c 100644 --- a/src/private/mx/core/generated/PartListChoice.cpp +++ b/src/private/mx/core/generated/PartListChoice.cpp @@ -26,11 +26,6 @@ PartListChoice PartListChoice::scorePart(ScorePart value) return PartListChoice{Storage{std::in_place_index<1>, std::move(value)}}; } -PartListChoice parsePartListChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parsePartListChoice(el, cursor, ParseContext{}); -} - PartListChoice parsePartListChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "part-group"))) diff --git a/src/private/mx/core/generated/PartListChoice.h b/src/private/mx/core/generated/PartListChoice.h index d29dd0e71..3132a6e66 100644 --- a/src/private/mx/core/generated/PartListChoice.h +++ b/src/private/mx/core/generated/PartListChoice.h @@ -82,8 +82,6 @@ class PartListChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -PartListChoice parsePartListChoice(pugi::xml_node el, pugi::xml_node &cursor); - PartListChoice parsePartListChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializePartListChoice(const PartListChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/PartName.cpp b/src/private/mx/core/generated/PartName.cpp index 8e5696195..1ef2ccde8 100644 --- a/src/private/mx/core/generated/PartName.cpp +++ b/src/private/mx/core/generated/PartName.cpp @@ -131,11 +131,6 @@ void PartName::setValue(std::string value) m_value = std::move(value); } -PartName parsePartName(pugi::xml_node el) -{ - return parsePartName(el, ParseContext{}); -} - PartName parsePartName(pugi::xml_node el, const ParseContext &context) { PartName out; @@ -199,11 +194,6 @@ PartName parsePartName(pugi::xml_node el, const ParseContext &context) return out; } -void parsePartNameContent(PartName &out, pugi::xml_node el) -{ - parsePartNameContent(out, el, ParseContext{}); -} - void parsePartNameContent(PartName &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/PartName.h b/src/private/mx/core/generated/PartName.h index ad64eab2c..84f4be279 100644 --- a/src/private/mx/core/generated/PartName.h +++ b/src/private/mx/core/generated/PartName.h @@ -71,12 +71,8 @@ class PartName final std::string m_value{}; }; -PartName parsePartName(pugi::xml_node el); - PartName parsePartName(pugi::xml_node el, const ParseContext &context); -void parsePartNameContent(PartName &out, pugi::xml_node el); - void parsePartNameContent(PartName &out, pugi::xml_node el, const ParseContext &context); void serializePartName(const PartName &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/PartSymbol.cpp b/src/private/mx/core/generated/PartSymbol.cpp index db44f742b..dd3fed80f 100644 --- a/src/private/mx/core/generated/PartSymbol.cpp +++ b/src/private/mx/core/generated/PartSymbol.cpp @@ -91,11 +91,6 @@ void PartSymbol::setValue(GroupSymbolValue value) m_value = std::move(value); } -PartSymbol parsePartSymbol(pugi::xml_node el) -{ - return parsePartSymbol(el, ParseContext{}); -} - PartSymbol parsePartSymbol(pugi::xml_node el, const ParseContext &context) { PartSymbol out; @@ -143,11 +138,6 @@ PartSymbol parsePartSymbol(pugi::xml_node el, const ParseContext &context) return out; } -void parsePartSymbolContent(PartSymbol &out, pugi::xml_node el) -{ - parsePartSymbolContent(out, el, ParseContext{}); -} - void parsePartSymbolContent(PartSymbol &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/PartSymbol.h b/src/private/mx/core/generated/PartSymbol.h index 8f967d43e..177c5dac6 100644 --- a/src/private/mx/core/generated/PartSymbol.h +++ b/src/private/mx/core/generated/PartSymbol.h @@ -59,12 +59,8 @@ class PartSymbol final GroupSymbolValue m_value{}; }; -PartSymbol parsePartSymbol(pugi::xml_node el); - PartSymbol parsePartSymbol(pugi::xml_node el, const ParseContext &context); -void parsePartSymbolContent(PartSymbol &out, pugi::xml_node el); - void parsePartSymbolContent(PartSymbol &out, pugi::xml_node el, const ParseContext &context); void serializePartSymbol(const PartSymbol &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/PartTranspose.cpp b/src/private/mx/core/generated/PartTranspose.cpp index ac3250d98..0d2c3fdba 100644 --- a/src/private/mx/core/generated/PartTranspose.cpp +++ b/src/private/mx/core/generated/PartTranspose.cpp @@ -21,11 +21,6 @@ void PartTranspose::setTranspose(TransposeGroup value) m_transpose = std::move(value); } -PartTranspose parsePartTranspose(pugi::xml_node el) -{ - return parsePartTranspose(el, ParseContext{}); -} - PartTranspose parsePartTranspose(pugi::xml_node el, const ParseContext &context) { PartTranspose out; @@ -42,11 +37,6 @@ PartTranspose parsePartTranspose(pugi::xml_node el, const ParseContext &context) return out; } -void parsePartTransposeContent(PartTranspose &out, pugi::xml_node el) -{ - parsePartTransposeContent(out, el, ParseContext{}); -} - void parsePartTransposeContent(PartTranspose &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/PartTranspose.h b/src/private/mx/core/generated/PartTranspose.h index 06efe6354..d7af3fb8d 100644 --- a/src/private/mx/core/generated/PartTranspose.h +++ b/src/private/mx/core/generated/PartTranspose.h @@ -34,12 +34,8 @@ class PartTranspose final TransposeGroup m_transpose{}; }; -PartTranspose parsePartTranspose(pugi::xml_node el); - PartTranspose parsePartTranspose(pugi::xml_node el, const ParseContext &context); -void parsePartTransposeContent(PartTranspose &out, pugi::xml_node el); - void parsePartTransposeContent(PartTranspose &out, pugi::xml_node el, const ParseContext &context); void serializePartTranspose(const PartTranspose &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/PartwiseMeasure.cpp b/src/private/mx/core/generated/PartwiseMeasure.cpp index b97160e18..0adbee573 100644 --- a/src/private/mx/core/generated/PartwiseMeasure.cpp +++ b/src/private/mx/core/generated/PartwiseMeasure.cpp @@ -86,11 +86,6 @@ void PartwiseMeasure::setMusicData(std::vector value) m_musicData = std::move(value); } -PartwiseMeasure parsePartwiseMeasure(pugi::xml_node el) -{ - return parsePartwiseMeasure(el, ParseContext{}); -} - PartwiseMeasure parsePartwiseMeasure(pugi::xml_node el, const ParseContext &context) { PartwiseMeasure out; @@ -140,11 +135,6 @@ PartwiseMeasure parsePartwiseMeasure(pugi::xml_node el, const ParseContext &cont return out; } -void parsePartwiseMeasureContent(PartwiseMeasure &out, pugi::xml_node el) -{ - parsePartwiseMeasureContent(out, el, ParseContext{}); -} - void parsePartwiseMeasureContent(PartwiseMeasure &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/PartwiseMeasure.h b/src/private/mx/core/generated/PartwiseMeasure.h index b81f83b2a..151b593f6 100644 --- a/src/private/mx/core/generated/PartwiseMeasure.h +++ b/src/private/mx/core/generated/PartwiseMeasure.h @@ -56,12 +56,8 @@ class PartwiseMeasure final std::vector m_musicData; }; -PartwiseMeasure parsePartwiseMeasure(pugi::xml_node el); - PartwiseMeasure parsePartwiseMeasure(pugi::xml_node el, const ParseContext &context); -void parsePartwiseMeasureContent(PartwiseMeasure &out, pugi::xml_node el); - void parsePartwiseMeasureContent(PartwiseMeasure &out, pugi::xml_node el, const ParseContext &context); void serializePartwiseMeasure(const PartwiseMeasure &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/PartwisePart.cpp b/src/private/mx/core/generated/PartwisePart.cpp index 237104200..409424363 100644 --- a/src/private/mx/core/generated/PartwisePart.cpp +++ b/src/private/mx/core/generated/PartwisePart.cpp @@ -36,11 +36,6 @@ void PartwisePart::setMeasure(OneOrMore value) m_measure = std::move(value); } -PartwisePart parsePartwisePart(pugi::xml_node el) -{ - return parsePartwisePart(el, ParseContext{}); -} - PartwisePart parsePartwisePart(pugi::xml_node el, const ParseContext &context) { PartwisePart out; @@ -70,11 +65,6 @@ PartwisePart parsePartwisePart(pugi::xml_node el, const ParseContext &context) return out; } -void parsePartwisePartContent(PartwisePart &out, pugi::xml_node el) -{ - parsePartwisePartContent(out, el, ParseContext{}); -} - void parsePartwisePartContent(PartwisePart &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/PartwisePart.h b/src/private/mx/core/generated/PartwisePart.h index 6ebb27b7d..ec9ad4d5d 100644 --- a/src/private/mx/core/generated/PartwisePart.h +++ b/src/private/mx/core/generated/PartwisePart.h @@ -39,12 +39,8 @@ class PartwisePart final OneOrMore m_measure; }; -PartwisePart parsePartwisePart(pugi::xml_node el); - PartwisePart parsePartwisePart(pugi::xml_node el, const ParseContext &context); -void parsePartwisePartContent(PartwisePart &out, pugi::xml_node el); - void parsePartwisePartContent(PartwisePart &out, pugi::xml_node el, const ParseContext &context); void serializePartwisePart(const PartwisePart &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Pedal.cpp b/src/private/mx/core/generated/Pedal.cpp index 24632fa81..e80e72b77 100644 --- a/src/private/mx/core/generated/Pedal.cpp +++ b/src/private/mx/core/generated/Pedal.cpp @@ -181,11 +181,6 @@ void Pedal::setID(std::optional value) m_id = std::move(value); } -Pedal parsePedal(pugi::xml_node el) -{ - return parsePedal(el, ParseContext{}); -} - Pedal parsePedal(pugi::xml_node el, const ParseContext &context) { Pedal out; @@ -279,11 +274,6 @@ Pedal parsePedal(pugi::xml_node el, const ParseContext &context) return out; } -void parsePedalContent(Pedal &out, pugi::xml_node el) -{ - parsePedalContent(out, el, ParseContext{}); -} - void parsePedalContent(Pedal &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/Pedal.h b/src/private/mx/core/generated/Pedal.h index 9d813aeae..4444fb490 100644 --- a/src/private/mx/core/generated/Pedal.h +++ b/src/private/mx/core/generated/Pedal.h @@ -96,12 +96,8 @@ class Pedal final std::optional m_id; }; -Pedal parsePedal(pugi::xml_node el); - Pedal parsePedal(pugi::xml_node el, const ParseContext &context); -void parsePedalContent(Pedal &out, pugi::xml_node el); - void parsePedalContent(Pedal &out, pugi::xml_node el, const ParseContext &context); void serializePedal(const Pedal &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/PedalTuning.cpp b/src/private/mx/core/generated/PedalTuning.cpp index c228e8294..216981f08 100644 --- a/src/private/mx/core/generated/PedalTuning.cpp +++ b/src/private/mx/core/generated/PedalTuning.cpp @@ -31,11 +31,6 @@ void PedalTuning::setPedalAlter(Semitones value) m_pedalAlter = std::move(value); } -PedalTuning parsePedalTuning(pugi::xml_node el) -{ - return parsePedalTuning(el, ParseContext{}); -} - PedalTuning parsePedalTuning(pugi::xml_node el, const ParseContext &context) { PedalTuning out; @@ -52,11 +47,6 @@ PedalTuning parsePedalTuning(pugi::xml_node el, const ParseContext &context) return out; } -void parsePedalTuningContent(PedalTuning &out, pugi::xml_node el) -{ - parsePedalTuningContent(out, el, ParseContext{}); -} - void parsePedalTuningContent(PedalTuning &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/PedalTuning.h b/src/private/mx/core/generated/PedalTuning.h index 079c10b59..9f2e07d83 100644 --- a/src/private/mx/core/generated/PedalTuning.h +++ b/src/private/mx/core/generated/PedalTuning.h @@ -37,12 +37,8 @@ class PedalTuning final Semitones m_pedalAlter{}; }; -PedalTuning parsePedalTuning(pugi::xml_node el); - PedalTuning parsePedalTuning(pugi::xml_node el, const ParseContext &context); -void parsePedalTuningContent(PedalTuning &out, pugi::xml_node el); - void parsePedalTuningContent(PedalTuning &out, pugi::xml_node el, const ParseContext &context); void serializePedalTuning(const PedalTuning &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/PerMinute.cpp b/src/private/mx/core/generated/PerMinute.cpp index fd0249e3d..1a677bc1f 100644 --- a/src/private/mx/core/generated/PerMinute.cpp +++ b/src/private/mx/core/generated/PerMinute.cpp @@ -61,11 +61,6 @@ void PerMinute::setValue(std::string value) m_value = std::move(value); } -PerMinute parsePerMinute(pugi::xml_node el) -{ - return parsePerMinute(el, ParseContext{}); -} - PerMinute parsePerMinute(pugi::xml_node el, const ParseContext &context) { PerMinute out; @@ -101,11 +96,6 @@ PerMinute parsePerMinute(pugi::xml_node el, const ParseContext &context) return out; } -void parsePerMinuteContent(PerMinute &out, pugi::xml_node el) -{ - parsePerMinuteContent(out, el, ParseContext{}); -} - void parsePerMinuteContent(PerMinute &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/PerMinute.h b/src/private/mx/core/generated/PerMinute.h index 4cc57c6d2..9efda68e9 100644 --- a/src/private/mx/core/generated/PerMinute.h +++ b/src/private/mx/core/generated/PerMinute.h @@ -47,12 +47,8 @@ class PerMinute final std::string m_value{}; }; -PerMinute parsePerMinute(pugi::xml_node el); - PerMinute parsePerMinute(pugi::xml_node el, const ParseContext &context); -void parsePerMinuteContent(PerMinute &out, pugi::xml_node el); - void parsePerMinuteContent(PerMinute &out, pugi::xml_node el, const ParseContext &context); void serializePerMinute(const PerMinute &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Percussion.cpp b/src/private/mx/core/generated/Percussion.cpp index 53af7fcf7..b28ce4a73 100644 --- a/src/private/mx/core/generated/Percussion.cpp +++ b/src/private/mx/core/generated/Percussion.cpp @@ -151,11 +151,6 @@ void Percussion::setChoice(PercussionChoice value) m_choice = std::move(value); } -Percussion parsePercussion(pugi::xml_node el) -{ - return parsePercussion(el, ParseContext{}); -} - Percussion parsePercussion(pugi::xml_node el, const ParseContext &context) { Percussion out; @@ -227,11 +222,6 @@ Percussion parsePercussion(pugi::xml_node el, const ParseContext &context) return out; } -void parsePercussionContent(Percussion &out, pugi::xml_node el) -{ - parsePercussionContent(out, el, ParseContext{}); -} - void parsePercussionContent(Percussion &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Percussion.h b/src/private/mx/core/generated/Percussion.h index cfc480a92..833b6f0ba 100644 --- a/src/private/mx/core/generated/Percussion.h +++ b/src/private/mx/core/generated/Percussion.h @@ -86,12 +86,8 @@ class Percussion final PercussionChoice m_choice{}; }; -Percussion parsePercussion(pugi::xml_node el); - Percussion parsePercussion(pugi::xml_node el, const ParseContext &context); -void parsePercussionContent(Percussion &out, pugi::xml_node el); - void parsePercussionContent(Percussion &out, pugi::xml_node el, const ParseContext &context); void serializePercussion(const Percussion &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/PercussionChoice.cpp b/src/private/mx/core/generated/PercussionChoice.cpp index 792073f77..c1b47379e 100644 --- a/src/private/mx/core/generated/PercussionChoice.cpp +++ b/src/private/mx/core/generated/PercussionChoice.cpp @@ -71,11 +71,6 @@ PercussionChoice PercussionChoice::otherPercussion(OtherText value) return PercussionChoice{Storage{std::in_place_index<10>, std::move(value)}}; } -PercussionChoice parsePercussionChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parsePercussionChoice(el, cursor, ParseContext{}); -} - PercussionChoice parsePercussionChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "glass"))) diff --git a/src/private/mx/core/generated/PercussionChoice.h b/src/private/mx/core/generated/PercussionChoice.h index f1b8b3079..d05797253 100644 --- a/src/private/mx/core/generated/PercussionChoice.h +++ b/src/private/mx/core/generated/PercussionChoice.h @@ -218,8 +218,6 @@ class PercussionChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -PercussionChoice parsePercussionChoice(pugi::xml_node el, pugi::xml_node &cursor); - PercussionChoice parsePercussionChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializePercussionChoice(const PercussionChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Pitch.cpp b/src/private/mx/core/generated/Pitch.cpp index fde8c26d4..bc92fe254 100644 --- a/src/private/mx/core/generated/Pitch.cpp +++ b/src/private/mx/core/generated/Pitch.cpp @@ -41,11 +41,6 @@ void Pitch::setOctave(Octave value) m_octave = std::move(value); } -Pitch parsePitch(pugi::xml_node el) -{ - return parsePitch(el, ParseContext{}); -} - Pitch parsePitch(pugi::xml_node el, const ParseContext &context) { Pitch out; @@ -62,11 +57,6 @@ Pitch parsePitch(pugi::xml_node el, const ParseContext &context) return out; } -void parsePitchContent(Pitch &out, pugi::xml_node el) -{ - parsePitchContent(out, el, ParseContext{}); -} - void parsePitchContent(Pitch &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Pitch.h b/src/private/mx/core/generated/Pitch.h index 8929b2594..85282e037 100644 --- a/src/private/mx/core/generated/Pitch.h +++ b/src/private/mx/core/generated/Pitch.h @@ -42,12 +42,8 @@ class Pitch final Octave m_octave{}; }; -Pitch parsePitch(pugi::xml_node el); - Pitch parsePitch(pugi::xml_node el, const ParseContext &context); -void parsePitchContent(Pitch &out, pugi::xml_node el); - void parsePitchContent(Pitch &out, pugi::xml_node el, const ParseContext &context); void serializePitch(const Pitch &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Pitched.cpp b/src/private/mx/core/generated/Pitched.cpp index cc515049c..7bf231f2f 100644 --- a/src/private/mx/core/generated/Pitched.cpp +++ b/src/private/mx/core/generated/Pitched.cpp @@ -31,11 +31,6 @@ void Pitched::setValue(PitchedValue value) m_value = std::move(value); } -Pitched parsePitched(pugi::xml_node el) -{ - return parsePitched(el, ParseContext{}); -} - Pitched parsePitched(pugi::xml_node el, const ParseContext &context) { Pitched out; @@ -59,11 +54,6 @@ Pitched parsePitched(pugi::xml_node el, const ParseContext &context) return out; } -void parsePitchedContent(Pitched &out, pugi::xml_node el) -{ - parsePitchedContent(out, el, ParseContext{}); -} - void parsePitchedContent(Pitched &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/Pitched.h b/src/private/mx/core/generated/Pitched.h index 532e04841..0ad68baa2 100644 --- a/src/private/mx/core/generated/Pitched.h +++ b/src/private/mx/core/generated/Pitched.h @@ -35,12 +35,8 @@ class Pitched final PitchedValue m_value{}; }; -Pitched parsePitched(pugi::xml_node el); - Pitched parsePitched(pugi::xml_node el, const ParseContext &context); -void parsePitchedContent(Pitched &out, pugi::xml_node el); - void parsePitchedContent(Pitched &out, pugi::xml_node el, const ParseContext &context); void serializePitched(const Pitched &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/PlacementText.cpp b/src/private/mx/core/generated/PlacementText.cpp index e2a257c88..4c9c3cb04 100644 --- a/src/private/mx/core/generated/PlacementText.cpp +++ b/src/private/mx/core/generated/PlacementText.cpp @@ -121,11 +121,6 @@ void PlacementText::setValue(std::string value) m_value = std::move(value); } -PlacementText parsePlacementText(pugi::xml_node el) -{ - return parsePlacementText(el, ParseContext{}); -} - PlacementText parsePlacementText(pugi::xml_node el, const ParseContext &context) { PlacementText out; @@ -185,11 +180,6 @@ PlacementText parsePlacementText(pugi::xml_node el, const ParseContext &context) return out; } -void parsePlacementTextContent(PlacementText &out, pugi::xml_node el) -{ - parsePlacementTextContent(out, el, ParseContext{}); -} - void parsePlacementTextContent(PlacementText &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/PlacementText.h b/src/private/mx/core/generated/PlacementText.h index 39fed3d24..f85dbb8be 100644 --- a/src/private/mx/core/generated/PlacementText.h +++ b/src/private/mx/core/generated/PlacementText.h @@ -66,12 +66,8 @@ class PlacementText final std::string m_value{}; }; -PlacementText parsePlacementText(pugi::xml_node el); - PlacementText parsePlacementText(pugi::xml_node el, const ParseContext &context); -void parsePlacementTextContent(PlacementText &out, pugi::xml_node el); - void parsePlacementTextContent(PlacementText &out, pugi::xml_node el, const ParseContext &context); void serializePlacementText(const PlacementText &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Play.cpp b/src/private/mx/core/generated/Play.cpp index 8a881c3f6..4a4547b1c 100644 --- a/src/private/mx/core/generated/Play.cpp +++ b/src/private/mx/core/generated/Play.cpp @@ -36,11 +36,6 @@ void Play::setChoice(std::vector value) m_choice = std::move(value); } -Play parsePlay(pugi::xml_node el) -{ - return parsePlay(el, ParseContext{}); -} - Play parsePlay(pugi::xml_node el, const ParseContext &context) { Play out; @@ -64,11 +59,6 @@ Play parsePlay(pugi::xml_node el, const ParseContext &context) return out; } -void parsePlayContent(Play &out, pugi::xml_node el) -{ - parsePlayContent(out, el, ParseContext{}); -} - void parsePlayContent(Play &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Play.h b/src/private/mx/core/generated/Play.h index c3e3623d4..50e941e31 100644 --- a/src/private/mx/core/generated/Play.h +++ b/src/private/mx/core/generated/Play.h @@ -42,12 +42,8 @@ class Play final std::vector m_choice; }; -Play parsePlay(pugi::xml_node el); - Play parsePlay(pugi::xml_node el, const ParseContext &context); -void parsePlayContent(Play &out, pugi::xml_node el); - void parsePlayContent(Play &out, pugi::xml_node el, const ParseContext &context); void serializePlay(const Play &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/PlayChoice.cpp b/src/private/mx/core/generated/PlayChoice.cpp index 1b27dada0..c07ad4f2b 100644 --- a/src/private/mx/core/generated/PlayChoice.cpp +++ b/src/private/mx/core/generated/PlayChoice.cpp @@ -36,11 +36,6 @@ PlayChoice PlayChoice::otherPlay(OtherPlay value) return PlayChoice{Storage{std::in_place_index<3>, std::move(value)}}; } -PlayChoice parsePlayChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parsePlayChoice(el, cursor, ParseContext{}); -} - PlayChoice parsePlayChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "ipa"))) diff --git a/src/private/mx/core/generated/PlayChoice.h b/src/private/mx/core/generated/PlayChoice.h index c1f104200..a713ef622 100644 --- a/src/private/mx/core/generated/PlayChoice.h +++ b/src/private/mx/core/generated/PlayChoice.h @@ -111,8 +111,6 @@ class PlayChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -PlayChoice parsePlayChoice(pugi::xml_node el, pugi::xml_node &cursor); - PlayChoice parsePlayChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializePlayChoice(const PlayChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Player.cpp b/src/private/mx/core/generated/Player.cpp index 1718151a8..d5235385b 100644 --- a/src/private/mx/core/generated/Player.cpp +++ b/src/private/mx/core/generated/Player.cpp @@ -31,11 +31,6 @@ void Player::setPlayerName(std::string value) m_playerName = std::move(value); } -Player parsePlayer(pugi::xml_node el) -{ - return parsePlayer(el, ParseContext{}); -} - Player parsePlayer(pugi::xml_node el, const ParseContext &context) { Player out; @@ -65,11 +60,6 @@ Player parsePlayer(pugi::xml_node el, const ParseContext &context) return out; } -void parsePlayerContent(Player &out, pugi::xml_node el) -{ - parsePlayerContent(out, el, ParseContext{}); -} - void parsePlayerContent(Player &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Player.h b/src/private/mx/core/generated/Player.h index 9cdfb478b..ba447b70e 100644 --- a/src/private/mx/core/generated/Player.h +++ b/src/private/mx/core/generated/Player.h @@ -39,12 +39,8 @@ class Player final std::string m_playerName{}; }; -Player parsePlayer(pugi::xml_node el); - Player parsePlayer(pugi::xml_node el, const ParseContext &context); -void parsePlayerContent(Player &out, pugi::xml_node el); - void parsePlayerContent(Player &out, pugi::xml_node el, const ParseContext &context); void serializePlayer(const Player &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/PrincipalVoice.cpp b/src/private/mx/core/generated/PrincipalVoice.cpp index bb96c62d7..db4f33fc9 100644 --- a/src/private/mx/core/generated/PrincipalVoice.cpp +++ b/src/private/mx/core/generated/PrincipalVoice.cpp @@ -161,11 +161,6 @@ void PrincipalVoice::setValue(std::string value) m_value = std::move(value); } -PrincipalVoice parsePrincipalVoice(pugi::xml_node el) -{ - return parsePrincipalVoice(el, ParseContext{}); -} - PrincipalVoice parsePrincipalVoice(pugi::xml_node el, const ParseContext &context) { PrincipalVoice out; @@ -253,11 +248,6 @@ PrincipalVoice parsePrincipalVoice(pugi::xml_node el, const ParseContext &contex return out; } -void parsePrincipalVoiceContent(PrincipalVoice &out, pugi::xml_node el) -{ - parsePrincipalVoiceContent(out, el, ParseContext{}); -} - void parsePrincipalVoiceContent(PrincipalVoice &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/PrincipalVoice.h b/src/private/mx/core/generated/PrincipalVoice.h index daeb5c185..46b3c72ea 100644 --- a/src/private/mx/core/generated/PrincipalVoice.h +++ b/src/private/mx/core/generated/PrincipalVoice.h @@ -86,12 +86,8 @@ class PrincipalVoice final std::string m_value{}; }; -PrincipalVoice parsePrincipalVoice(pugi::xml_node el); - PrincipalVoice parsePrincipalVoice(pugi::xml_node el, const ParseContext &context); -void parsePrincipalVoiceContent(PrincipalVoice &out, pugi::xml_node el); - void parsePrincipalVoiceContent(PrincipalVoice &out, pugi::xml_node el, const ParseContext &context); void serializePrincipalVoice(const PrincipalVoice &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Print.cpp b/src/private/mx/core/generated/Print.cpp index 65a1ee3ff..2da075be0 100644 --- a/src/private/mx/core/generated/Print.cpp +++ b/src/private/mx/core/generated/Print.cpp @@ -121,11 +121,6 @@ void Print::setPartAbbreviationDisplay(std::optional value) m_partAbbreviationDisplay = std::move(value); } -Print parsePrint(pugi::xml_node el) -{ - return parsePrint(el, ParseContext{}); -} - Print parsePrint(pugi::xml_node el, const ParseContext &context) { Print out; @@ -169,11 +164,6 @@ Print parsePrint(pugi::xml_node el, const ParseContext &context) return out; } -void parsePrintContent(Print &out, pugi::xml_node el) -{ - parsePrintContent(out, el, ParseContext{}); -} - void parsePrintContent(Print &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Print.h b/src/private/mx/core/generated/Print.h index 3899831e3..f076d5f3e 100644 --- a/src/private/mx/core/generated/Print.h +++ b/src/private/mx/core/generated/Print.h @@ -75,12 +75,8 @@ class Print final std::optional m_partAbbreviationDisplay; }; -Print parsePrint(pugi::xml_node el); - Print parsePrint(pugi::xml_node el, const ParseContext &context); -void parsePrintContent(Print &out, pugi::xml_node el); - void parsePrintContent(Print &out, pugi::xml_node el, const ParseContext &context); void serializePrint(const Print &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Release.cpp b/src/private/mx/core/generated/Release.cpp index daef7ed38..e86256650 100644 --- a/src/private/mx/core/generated/Release.cpp +++ b/src/private/mx/core/generated/Release.cpp @@ -21,11 +21,6 @@ void Release::setOffset(std::optional value) m_offset = std::move(value); } -Release parseRelease(pugi::xml_node el) -{ - return parseRelease(el, ParseContext{}); -} - Release parseRelease(pugi::xml_node el, const ParseContext &context) { Release out; diff --git a/src/private/mx/core/generated/Release.h b/src/private/mx/core/generated/Release.h index 4c38a8a5b..5e53a6670 100644 --- a/src/private/mx/core/generated/Release.h +++ b/src/private/mx/core/generated/Release.h @@ -35,8 +35,6 @@ class Release : public Empty std::optional m_offset; }; -Release parseRelease(pugi::xml_node el); - Release parseRelease(pugi::xml_node el, const ParseContext &context); void serializeRelease(const Release &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Repeat.cpp b/src/private/mx/core/generated/Repeat.cpp index 6e3ab7cbd..d8a188ab8 100644 --- a/src/private/mx/core/generated/Repeat.cpp +++ b/src/private/mx/core/generated/Repeat.cpp @@ -51,11 +51,6 @@ void Repeat::setWinged(std::optional value) m_winged = std::move(value); } -Repeat parseRepeat(pugi::xml_node el) -{ - return parseRepeat(el, ParseContext{}); -} - Repeat parseRepeat(pugi::xml_node el, const ParseContext &context) { Repeat out; @@ -97,11 +92,6 @@ Repeat parseRepeat(pugi::xml_node el, const ParseContext &context) return out; } -void parseRepeatContent(Repeat &out, pugi::xml_node el) -{ - parseRepeatContent(out, el, ParseContext{}); -} - void parseRepeatContent(Repeat &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/Repeat.h b/src/private/mx/core/generated/Repeat.h index ce3f360cc..d20c14124 100644 --- a/src/private/mx/core/generated/Repeat.h +++ b/src/private/mx/core/generated/Repeat.h @@ -44,12 +44,8 @@ class Repeat final std::optional m_winged; }; -Repeat parseRepeat(pugi::xml_node el); - Repeat parseRepeat(pugi::xml_node el, const ParseContext &context); -void parseRepeatContent(Repeat &out, pugi::xml_node el); - void parseRepeatContent(Repeat &out, pugi::xml_node el, const ParseContext &context); void serializeRepeat(const Repeat &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Rest.cpp b/src/private/mx/core/generated/Rest.cpp index 2f87e248d..3db1d4786 100644 --- a/src/private/mx/core/generated/Rest.cpp +++ b/src/private/mx/core/generated/Rest.cpp @@ -31,11 +31,6 @@ void Rest::setDisplayStepOctave(std::optional value) m_displayStepOctave = std::move(value); } -Rest parseRest(pugi::xml_node el) -{ - return parseRest(el, ParseContext{}); -} - Rest parseRest(pugi::xml_node el, const ParseContext &context) { Rest out; @@ -59,11 +54,6 @@ Rest parseRest(pugi::xml_node el, const ParseContext &context) return out; } -void parseRestContent(Rest &out, pugi::xml_node el) -{ - parseRestContent(out, el, ParseContext{}); -} - void parseRestContent(Rest &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Rest.h b/src/private/mx/core/generated/Rest.h index 8154e8571..ab49ec4d3 100644 --- a/src/private/mx/core/generated/Rest.h +++ b/src/private/mx/core/generated/Rest.h @@ -39,12 +39,8 @@ class Rest final std::optional m_displayStepOctave; }; -Rest parseRest(pugi::xml_node el); - Rest parseRest(pugi::xml_node el, const ParseContext &context); -void parseRestContent(Rest &out, pugi::xml_node el); - void parseRestContent(Rest &out, pugi::xml_node el, const ParseContext &context); void serializeRest(const Rest &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Root.cpp b/src/private/mx/core/generated/Root.cpp index 2098acddf..a5a67bf72 100644 --- a/src/private/mx/core/generated/Root.cpp +++ b/src/private/mx/core/generated/Root.cpp @@ -31,11 +31,6 @@ void Root::setRootAlter(std::optional value) m_rootAlter = std::move(value); } -Root parseRoot(pugi::xml_node el) -{ - return parseRoot(el, ParseContext{}); -} - Root parseRoot(pugi::xml_node el, const ParseContext &context) { Root out; @@ -52,11 +47,6 @@ Root parseRoot(pugi::xml_node el, const ParseContext &context) return out; } -void parseRootContent(Root &out, pugi::xml_node el) -{ - parseRootContent(out, el, ParseContext{}); -} - void parseRootContent(Root &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Root.h b/src/private/mx/core/generated/Root.h index 580fdb7d6..3d9cd849d 100644 --- a/src/private/mx/core/generated/Root.h +++ b/src/private/mx/core/generated/Root.h @@ -40,12 +40,8 @@ class Root final std::optional m_rootAlter; }; -Root parseRoot(pugi::xml_node el); - Root parseRoot(pugi::xml_node el, const ParseContext &context); -void parseRootContent(Root &out, pugi::xml_node el); - void parseRootContent(Root &out, pugi::xml_node el, const ParseContext &context); void serializeRoot(const Root &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/RootStep.cpp b/src/private/mx/core/generated/RootStep.cpp index e7113dd4a..59e52d1d2 100644 --- a/src/private/mx/core/generated/RootStep.cpp +++ b/src/private/mx/core/generated/RootStep.cpp @@ -121,11 +121,6 @@ void RootStep::setValue(Step value) m_value = std::move(value); } -RootStep parseRootStep(pugi::xml_node el) -{ - return parseRootStep(el, ParseContext{}); -} - RootStep parseRootStep(pugi::xml_node el, const ParseContext &context) { RootStep out; @@ -185,11 +180,6 @@ RootStep parseRootStep(pugi::xml_node el, const ParseContext &context) return out; } -void parseRootStepContent(RootStep &out, pugi::xml_node el) -{ - parseRootStepContent(out, el, ParseContext{}); -} - void parseRootStepContent(RootStep &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/RootStep.h b/src/private/mx/core/generated/RootStep.h index cf0f2deb1..508bf630f 100644 --- a/src/private/mx/core/generated/RootStep.h +++ b/src/private/mx/core/generated/RootStep.h @@ -67,12 +67,8 @@ class RootStep final Step m_value{}; }; -RootStep parseRootStep(pugi::xml_node el); - RootStep parseRootStep(pugi::xml_node el, const ParseContext &context); -void parseRootStepContent(RootStep &out, pugi::xml_node el); - void parseRootStepContent(RootStep &out, pugi::xml_node el, const ParseContext &context); void serializeRootStep(const RootStep &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Scaling.cpp b/src/private/mx/core/generated/Scaling.cpp index 31428e416..e1285000c 100644 --- a/src/private/mx/core/generated/Scaling.cpp +++ b/src/private/mx/core/generated/Scaling.cpp @@ -31,11 +31,6 @@ void Scaling::setTenths(Tenths value) m_tenths = std::move(value); } -Scaling parseScaling(pugi::xml_node el) -{ - return parseScaling(el, ParseContext{}); -} - Scaling parseScaling(pugi::xml_node el, const ParseContext &context) { Scaling out; @@ -52,11 +47,6 @@ Scaling parseScaling(pugi::xml_node el, const ParseContext &context) return out; } -void parseScalingContent(Scaling &out, pugi::xml_node el) -{ - parseScalingContent(out, el, ParseContext{}); -} - void parseScalingContent(Scaling &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Scaling.h b/src/private/mx/core/generated/Scaling.h index cea1f27a0..7fe193445 100644 --- a/src/private/mx/core/generated/Scaling.h +++ b/src/private/mx/core/generated/Scaling.h @@ -41,12 +41,8 @@ class Scaling final Tenths m_tenths{}; }; -Scaling parseScaling(pugi::xml_node el); - Scaling parseScaling(pugi::xml_node el, const ParseContext &context); -void parseScalingContent(Scaling &out, pugi::xml_node el); - void parseScalingContent(Scaling &out, pugi::xml_node el, const ParseContext &context); void serializeScaling(const Scaling &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Scordatura.cpp b/src/private/mx/core/generated/Scordatura.cpp index fac988b3b..14b24b99e 100644 --- a/src/private/mx/core/generated/Scordatura.cpp +++ b/src/private/mx/core/generated/Scordatura.cpp @@ -36,11 +36,6 @@ void Scordatura::setAccord(OneOrMore value) m_accord = std::move(value); } -Scordatura parseScordatura(pugi::xml_node el) -{ - return parseScordatura(el, ParseContext{}); -} - Scordatura parseScordatura(pugi::xml_node el, const ParseContext &context) { Scordatura out; @@ -64,11 +59,6 @@ Scordatura parseScordatura(pugi::xml_node el, const ParseContext &context) return out; } -void parseScordaturaContent(Scordatura &out, pugi::xml_node el) -{ - parseScordaturaContent(out, el, ParseContext{}); -} - void parseScordaturaContent(Scordatura &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Scordatura.h b/src/private/mx/core/generated/Scordatura.h index 17f09cecb..15cb28c09 100644 --- a/src/private/mx/core/generated/Scordatura.h +++ b/src/private/mx/core/generated/Scordatura.h @@ -41,12 +41,8 @@ class Scordatura final OneOrMore m_accord; }; -Scordatura parseScordatura(pugi::xml_node el); - Scordatura parseScordatura(pugi::xml_node el, const ParseContext &context); -void parseScordaturaContent(Scordatura &out, pugi::xml_node el); - void parseScordaturaContent(Scordatura &out, pugi::xml_node el, const ParseContext &context); void serializeScordatura(const Scordatura &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/ScoreHeaderGroup.cpp b/src/private/mx/core/generated/ScoreHeaderGroup.cpp index 244099846..01533bfbf 100644 --- a/src/private/mx/core/generated/ScoreHeaderGroup.cpp +++ b/src/private/mx/core/generated/ScoreHeaderGroup.cpp @@ -86,11 +86,6 @@ void ScoreHeaderGroup::setPartList(PartList value) m_partList = std::move(value); } -ScoreHeaderGroup parseScoreHeaderGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseScoreHeaderGroup(el, cursor, ParseContext{}); -} - ScoreHeaderGroup parseScoreHeaderGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { ScoreHeaderGroup out; diff --git a/src/private/mx/core/generated/ScoreHeaderGroup.h b/src/private/mx/core/generated/ScoreHeaderGroup.h index 15a405274..4a0cae8d1 100644 --- a/src/private/mx/core/generated/ScoreHeaderGroup.h +++ b/src/private/mx/core/generated/ScoreHeaderGroup.h @@ -60,8 +60,6 @@ class ScoreHeaderGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -ScoreHeaderGroup parseScoreHeaderGroup(pugi::xml_node el, pugi::xml_node &cursor); - ScoreHeaderGroup parseScoreHeaderGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeScoreHeaderGroup(const ScoreHeaderGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/ScoreInstrument.cpp b/src/private/mx/core/generated/ScoreInstrument.cpp index 3e0630ae1..6b9dd9e78 100644 --- a/src/private/mx/core/generated/ScoreInstrument.cpp +++ b/src/private/mx/core/generated/ScoreInstrument.cpp @@ -51,11 +51,6 @@ void ScoreInstrument::setVirtualInstrumentData(VirtualInstrumentDataGroup value) m_virtualInstrumentData = std::move(value); } -ScoreInstrument parseScoreInstrument(pugi::xml_node el) -{ - return parseScoreInstrument(el, ParseContext{}); -} - ScoreInstrument parseScoreInstrument(pugi::xml_node el, const ParseContext &context) { ScoreInstrument out; @@ -85,11 +80,6 @@ ScoreInstrument parseScoreInstrument(pugi::xml_node el, const ParseContext &cont return out; } -void parseScoreInstrumentContent(ScoreInstrument &out, pugi::xml_node el) -{ - parseScoreInstrumentContent(out, el, ParseContext{}); -} - void parseScoreInstrumentContent(ScoreInstrument &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/ScoreInstrument.h b/src/private/mx/core/generated/ScoreInstrument.h index 11bee93b7..dc3c72466 100644 --- a/src/private/mx/core/generated/ScoreInstrument.h +++ b/src/private/mx/core/generated/ScoreInstrument.h @@ -51,12 +51,8 @@ class ScoreInstrument final VirtualInstrumentDataGroup m_virtualInstrumentData{}; }; -ScoreInstrument parseScoreInstrument(pugi::xml_node el); - ScoreInstrument parseScoreInstrument(pugi::xml_node el, const ParseContext &context); -void parseScoreInstrumentContent(ScoreInstrument &out, pugi::xml_node el); - void parseScoreInstrumentContent(ScoreInstrument &out, pugi::xml_node el, const ParseContext &context); void serializeScoreInstrument(const ScoreInstrument &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/ScorePart.cpp b/src/private/mx/core/generated/ScorePart.cpp index 0107e4537..4e891e6cd 100644 --- a/src/private/mx/core/generated/ScorePart.cpp +++ b/src/private/mx/core/generated/ScorePart.cpp @@ -146,11 +146,6 @@ void ScorePart::setMIDIGroup(std::vector value) m_midiGroup = std::move(value); } -ScorePart parseScorePart(pugi::xml_node el) -{ - return parseScorePart(el, ParseContext{}); -} - ScorePart parseScorePart(pugi::xml_node el, const ParseContext &context) { ScorePart out; @@ -180,11 +175,6 @@ ScorePart parseScorePart(pugi::xml_node el, const ParseContext &context) return out; } -void parseScorePartContent(ScorePart &out, pugi::xml_node el) -{ - parseScorePartContent(out, el, ParseContext{}); -} - void parseScorePartContent(ScorePart &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/ScorePart.h b/src/private/mx/core/generated/ScorePart.h index ee6d3796e..56685db30 100644 --- a/src/private/mx/core/generated/ScorePart.h +++ b/src/private/mx/core/generated/ScorePart.h @@ -80,12 +80,8 @@ class ScorePart final std::vector m_midiGroup; }; -ScorePart parseScorePart(pugi::xml_node el); - ScorePart parseScorePart(pugi::xml_node el, const ParseContext &context); -void parseScorePartContent(ScorePart &out, pugi::xml_node el); - void parseScorePartContent(ScorePart &out, pugi::xml_node el, const ParseContext &context); void serializeScorePart(const ScorePart &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/ScorePartMIDIGroup.cpp b/src/private/mx/core/generated/ScorePartMIDIGroup.cpp index 963afab40..df45569ca 100644 --- a/src/private/mx/core/generated/ScorePartMIDIGroup.cpp +++ b/src/private/mx/core/generated/ScorePartMIDIGroup.cpp @@ -31,11 +31,6 @@ void ScorePartMIDIGroup::setMIDIInstrument(std::optional value) m_midiInstrument = std::move(value); } -ScorePartMIDIGroup parseScorePartMIDIGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseScorePartMIDIGroup(el, cursor, ParseContext{}); -} - ScorePartMIDIGroup parseScorePartMIDIGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { ScorePartMIDIGroup out; diff --git a/src/private/mx/core/generated/ScorePartMIDIGroup.h b/src/private/mx/core/generated/ScorePartMIDIGroup.h index 2c7ff73e8..0f1822547 100644 --- a/src/private/mx/core/generated/ScorePartMIDIGroup.h +++ b/src/private/mx/core/generated/ScorePartMIDIGroup.h @@ -39,8 +39,6 @@ class ScorePartMIDIGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -ScorePartMIDIGroup parseScorePartMIDIGroup(pugi::xml_node el, pugi::xml_node &cursor); - ScorePartMIDIGroup parseScorePartMIDIGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeScorePartMIDIGroup(const ScorePartMIDIGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/ScorePartwise.cpp b/src/private/mx/core/generated/ScorePartwise.cpp index c16af5fc9..5e50307a1 100644 --- a/src/private/mx/core/generated/ScorePartwise.cpp +++ b/src/private/mx/core/generated/ScorePartwise.cpp @@ -46,11 +46,6 @@ void ScorePartwise::setPart(OneOrMore value) m_part = std::move(value); } -ScorePartwise parseScorePartwise(pugi::xml_node el) -{ - return parseScorePartwise(el, ParseContext{}); -} - ScorePartwise parseScorePartwise(pugi::xml_node el, const ParseContext &context) { ScorePartwise out; @@ -74,11 +69,6 @@ ScorePartwise parseScorePartwise(pugi::xml_node el, const ParseContext &context) return out; } -void parseScorePartwiseContent(ScorePartwise &out, pugi::xml_node el) -{ - parseScorePartwiseContent(out, el, ParseContext{}); -} - void parseScorePartwiseContent(ScorePartwise &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/ScorePartwise.h b/src/private/mx/core/generated/ScorePartwise.h index b3bb9002e..e26be3f0f 100644 --- a/src/private/mx/core/generated/ScorePartwise.h +++ b/src/private/mx/core/generated/ScorePartwise.h @@ -41,12 +41,8 @@ class ScorePartwise final OneOrMore m_part; }; -ScorePartwise parseScorePartwise(pugi::xml_node el); - ScorePartwise parseScorePartwise(pugi::xml_node el, const ParseContext &context); -void parseScorePartwiseContent(ScorePartwise &out, pugi::xml_node el); - void parseScorePartwiseContent(ScorePartwise &out, pugi::xml_node el, const ParseContext &context); void serializeScorePartwise(const ScorePartwise &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/ScoreTimewise.cpp b/src/private/mx/core/generated/ScoreTimewise.cpp index feee89a52..3c58c5bca 100644 --- a/src/private/mx/core/generated/ScoreTimewise.cpp +++ b/src/private/mx/core/generated/ScoreTimewise.cpp @@ -46,11 +46,6 @@ void ScoreTimewise::setMeasure(OneOrMore value) m_measure = std::move(value); } -ScoreTimewise parseScoreTimewise(pugi::xml_node el) -{ - return parseScoreTimewise(el, ParseContext{}); -} - ScoreTimewise parseScoreTimewise(pugi::xml_node el, const ParseContext &context) { ScoreTimewise out; @@ -74,11 +69,6 @@ ScoreTimewise parseScoreTimewise(pugi::xml_node el, const ParseContext &context) return out; } -void parseScoreTimewiseContent(ScoreTimewise &out, pugi::xml_node el) -{ - parseScoreTimewiseContent(out, el, ParseContext{}); -} - void parseScoreTimewiseContent(ScoreTimewise &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/ScoreTimewise.h b/src/private/mx/core/generated/ScoreTimewise.h index 13936241d..647cecfa6 100644 --- a/src/private/mx/core/generated/ScoreTimewise.h +++ b/src/private/mx/core/generated/ScoreTimewise.h @@ -41,12 +41,8 @@ class ScoreTimewise final OneOrMore m_measure; }; -ScoreTimewise parseScoreTimewise(pugi::xml_node el); - ScoreTimewise parseScoreTimewise(pugi::xml_node el, const ParseContext &context); -void parseScoreTimewiseContent(ScoreTimewise &out, pugi::xml_node el); - void parseScoreTimewiseContent(ScoreTimewise &out, pugi::xml_node el, const ParseContext &context); void serializeScoreTimewise(const ScoreTimewise &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Segno.cpp b/src/private/mx/core/generated/Segno.cpp index be9519efb..a4f84033d 100644 --- a/src/private/mx/core/generated/Segno.cpp +++ b/src/private/mx/core/generated/Segno.cpp @@ -141,11 +141,6 @@ void Segno::setID(std::optional value) m_id = std::move(value); } -Segno parseSegno(pugi::xml_node el) -{ - return parseSegno(el, ParseContext{}); -} - Segno parseSegno(pugi::xml_node el, const ParseContext &context) { Segno out; @@ -217,11 +212,6 @@ Segno parseSegno(pugi::xml_node el, const ParseContext &context) return out; } -void parseSegnoContent(Segno &out, pugi::xml_node el) -{ - parseSegnoContent(out, el, ParseContext{}); -} - void parseSegnoContent(Segno &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/Segno.h b/src/private/mx/core/generated/Segno.h index 179ed4502..99c4d4953 100644 --- a/src/private/mx/core/generated/Segno.h +++ b/src/private/mx/core/generated/Segno.h @@ -76,12 +76,8 @@ class Segno final std::optional m_id; }; -Segno parseSegno(pugi::xml_node el); - Segno parseSegno(pugi::xml_node el, const ParseContext &context); -void parseSegnoContent(Segno &out, pugi::xml_node el); - void parseSegnoContent(Segno &out, pugi::xml_node el, const ParseContext &context); void serializeSegno(const Segno &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Slash.cpp b/src/private/mx/core/generated/Slash.cpp index 51b43e82c..bc511fe1c 100644 --- a/src/private/mx/core/generated/Slash.cpp +++ b/src/private/mx/core/generated/Slash.cpp @@ -51,11 +51,6 @@ void Slash::setSlash(std::optional value) m_slash = std::move(value); } -Slash parseSlash(pugi::xml_node el) -{ - return parseSlash(el, ParseContext{}); -} - Slash parseSlash(pugi::xml_node el, const ParseContext &context) { Slash out; @@ -93,11 +88,6 @@ Slash parseSlash(pugi::xml_node el, const ParseContext &context) return out; } -void parseSlashContent(Slash &out, pugi::xml_node el) -{ - parseSlashContent(out, el, ParseContext{}); -} - void parseSlashContent(Slash &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Slash.h b/src/private/mx/core/generated/Slash.h index 32cb59911..927a15493 100644 --- a/src/private/mx/core/generated/Slash.h +++ b/src/private/mx/core/generated/Slash.h @@ -48,12 +48,8 @@ class Slash final std::optional m_slash; }; -Slash parseSlash(pugi::xml_node el); - Slash parseSlash(pugi::xml_node el, const ParseContext &context); -void parseSlashContent(Slash &out, pugi::xml_node el); - void parseSlashContent(Slash &out, pugi::xml_node el, const ParseContext &context); void serializeSlash(const Slash &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/SlashGroup.cpp b/src/private/mx/core/generated/SlashGroup.cpp index 0618fcc56..f21e60b23 100644 --- a/src/private/mx/core/generated/SlashGroup.cpp +++ b/src/private/mx/core/generated/SlashGroup.cpp @@ -36,11 +36,6 @@ void SlashGroup::setExceptVoice(std::vector value) m_exceptVoice = std::move(value); } -SlashGroup parseSlashGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseSlashGroup(el, cursor, ParseContext{}); -} - SlashGroup parseSlashGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { SlashGroup out; diff --git a/src/private/mx/core/generated/SlashGroup.h b/src/private/mx/core/generated/SlashGroup.h index 8ff186115..cb1882e6d 100644 --- a/src/private/mx/core/generated/SlashGroup.h +++ b/src/private/mx/core/generated/SlashGroup.h @@ -42,8 +42,6 @@ class SlashGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -SlashGroup parseSlashGroup(pugi::xml_node el, pugi::xml_node &cursor); - SlashGroup parseSlashGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeSlashGroup(const SlashGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/SlashGroupGroup.cpp b/src/private/mx/core/generated/SlashGroupGroup.cpp index 70a9b5ce0..26876b24a 100644 --- a/src/private/mx/core/generated/SlashGroupGroup.cpp +++ b/src/private/mx/core/generated/SlashGroupGroup.cpp @@ -36,11 +36,6 @@ void SlashGroupGroup::setSlashDot(std::vector value) m_slashDot = std::move(value); } -SlashGroupGroup parseSlashGroupGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseSlashGroupGroup(el, cursor, ParseContext{}); -} - SlashGroupGroup parseSlashGroupGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { SlashGroupGroup out; diff --git a/src/private/mx/core/generated/SlashGroupGroup.h b/src/private/mx/core/generated/SlashGroupGroup.h index 120e98944..a500a3600 100644 --- a/src/private/mx/core/generated/SlashGroupGroup.h +++ b/src/private/mx/core/generated/SlashGroupGroup.h @@ -40,8 +40,6 @@ class SlashGroupGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -SlashGroupGroup parseSlashGroupGroup(pugi::xml_node el, pugi::xml_node &cursor); - SlashGroupGroup parseSlashGroupGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeSlashGroupGroup(const SlashGroupGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Slide.cpp b/src/private/mx/core/generated/Slide.cpp index 4dc5225ee..dbb50443c 100644 --- a/src/private/mx/core/generated/Slide.cpp +++ b/src/private/mx/core/generated/Slide.cpp @@ -211,11 +211,6 @@ void Slide::setValue(std::string value) m_value = std::move(value); } -Slide parseSlide(pugi::xml_node el) -{ - return parseSlide(el, ParseContext{}); -} - Slide parseSlide(pugi::xml_node el, const ParseContext &context) { Slide out; @@ -317,11 +312,6 @@ Slide parseSlide(pugi::xml_node el, const ParseContext &context) return out; } -void parseSlideContent(Slide &out, pugi::xml_node el) -{ - parseSlideContent(out, el, ParseContext{}); -} - void parseSlideContent(Slide &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/Slide.h b/src/private/mx/core/generated/Slide.h index 78198164e..8c5398480 100644 --- a/src/private/mx/core/generated/Slide.h +++ b/src/private/mx/core/generated/Slide.h @@ -101,12 +101,8 @@ class Slide final std::string m_value{}; }; -Slide parseSlide(pugi::xml_node el); - Slide parseSlide(pugi::xml_node el, const ParseContext &context); -void parseSlideContent(Slide &out, pugi::xml_node el); - void parseSlideContent(Slide &out, pugi::xml_node el, const ParseContext &context); void serializeSlide(const Slide &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Slur.cpp b/src/private/mx/core/generated/Slur.cpp index b5a5d6977..db96d41f1 100644 --- a/src/private/mx/core/generated/Slur.cpp +++ b/src/private/mx/core/generated/Slur.cpp @@ -201,11 +201,6 @@ void Slur::setID(std::optional value) m_id = std::move(value); } -Slur parseSlur(pugi::xml_node el) -{ - return parseSlur(el, ParseContext{}); -} - Slur parseSlur(pugi::xml_node el, const ParseContext &context) { Slur out; @@ -307,11 +302,6 @@ Slur parseSlur(pugi::xml_node el, const ParseContext &context) return out; } -void parseSlurContent(Slur &out, pugi::xml_node el) -{ - parseSlurContent(out, el, ParseContext{}); -} - void parseSlurContent(Slur &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/Slur.h b/src/private/mx/core/generated/Slur.h index 10d22acec..193489040 100644 --- a/src/private/mx/core/generated/Slur.h +++ b/src/private/mx/core/generated/Slur.h @@ -94,12 +94,8 @@ class Slur final std::optional m_id; }; -Slur parseSlur(pugi::xml_node el); - Slur parseSlur(pugi::xml_node el, const ParseContext &context); -void parseSlurContent(Slur &out, pugi::xml_node el); - void parseSlurContent(Slur &out, pugi::xml_node el, const ParseContext &context); void serializeSlur(const Slur &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Sound.cpp b/src/private/mx/core/generated/Sound.cpp index 3c7103c29..54a48fda7 100644 --- a/src/private/mx/core/generated/Sound.cpp +++ b/src/private/mx/core/generated/Sound.cpp @@ -226,11 +226,6 @@ void Sound::setOffset(std::optional value) m_offset = std::move(value); } -Sound parseSound(pugi::xml_node el) -{ - return parseSound(el, ParseContext{}); -} - Sound parseSound(pugi::xml_node el, const ParseContext &context) { Sound out; @@ -322,11 +317,6 @@ Sound parseSound(pugi::xml_node el, const ParseContext &context) return out; } -void parseSoundContent(Sound &out, pugi::xml_node el) -{ - parseSoundContent(out, el, ParseContext{}); -} - void parseSoundContent(Sound &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Sound.h b/src/private/mx/core/generated/Sound.h index ee007c533..e09321dc6 100644 --- a/src/private/mx/core/generated/Sound.h +++ b/src/private/mx/core/generated/Sound.h @@ -141,12 +141,8 @@ class Sound final std::optional m_offset; }; -Sound parseSound(pugi::xml_node el); - Sound parseSound(pugi::xml_node el, const ParseContext &context); -void parseSoundContent(Sound &out, pugi::xml_node el); - void parseSoundContent(Sound &out, pugi::xml_node el, const ParseContext &context); void serializeSound(const Sound &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/SoundGroup.cpp b/src/private/mx/core/generated/SoundGroup.cpp index 4af19a78f..91881a5c9 100644 --- a/src/private/mx/core/generated/SoundGroup.cpp +++ b/src/private/mx/core/generated/SoundGroup.cpp @@ -51,11 +51,6 @@ void SoundGroup::setPlay(std::optional value) m_play = std::move(value); } -SoundGroup parseSoundGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseSoundGroup(el, cursor, ParseContext{}); -} - SoundGroup parseSoundGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { SoundGroup out; diff --git a/src/private/mx/core/generated/SoundGroup.h b/src/private/mx/core/generated/SoundGroup.h index 68a98a637..9f345397e 100644 --- a/src/private/mx/core/generated/SoundGroup.h +++ b/src/private/mx/core/generated/SoundGroup.h @@ -47,8 +47,6 @@ class SoundGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -SoundGroup parseSoundGroup(pugi::xml_node el, pugi::xml_node &cursor); - SoundGroup parseSoundGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeSoundGroup(const SoundGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/StaffDetails.cpp b/src/private/mx/core/generated/StaffDetails.cpp index 6c4ac9b13..0b4541f56 100644 --- a/src/private/mx/core/generated/StaffDetails.cpp +++ b/src/private/mx/core/generated/StaffDetails.cpp @@ -106,11 +106,6 @@ void StaffDetails::setStaffSize(std::optional value) m_staffSize = std::move(value); } -StaffDetails parseStaffDetails(pugi::xml_node el) -{ - return parseStaffDetails(el, ParseContext{}); -} - StaffDetails parseStaffDetails(pugi::xml_node el, const ParseContext &context) { StaffDetails out; @@ -146,11 +141,6 @@ StaffDetails parseStaffDetails(pugi::xml_node el, const ParseContext &context) return out; } -void parseStaffDetailsContent(StaffDetails &out, pugi::xml_node el) -{ - parseStaffDetailsContent(out, el, ParseContext{}); -} - void parseStaffDetailsContent(StaffDetails &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/StaffDetails.h b/src/private/mx/core/generated/StaffDetails.h index f5015866e..e03a42cb4 100644 --- a/src/private/mx/core/generated/StaffDetails.h +++ b/src/private/mx/core/generated/StaffDetails.h @@ -69,12 +69,8 @@ class StaffDetails final std::optional m_staffSize; }; -StaffDetails parseStaffDetails(pugi::xml_node el); - StaffDetails parseStaffDetails(pugi::xml_node el, const ParseContext &context); -void parseStaffDetailsContent(StaffDetails &out, pugi::xml_node el); - void parseStaffDetailsContent(StaffDetails &out, pugi::xml_node el, const ParseContext &context); void serializeStaffDetails(const StaffDetails &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/StaffDetailsGroup.cpp b/src/private/mx/core/generated/StaffDetailsGroup.cpp index 6cef32925..49852e90f 100644 --- a/src/private/mx/core/generated/StaffDetailsGroup.cpp +++ b/src/private/mx/core/generated/StaffDetailsGroup.cpp @@ -36,11 +36,6 @@ void StaffDetailsGroup::setLineDetail(std::vector value) m_lineDetail = std::move(value); } -StaffDetailsGroup parseStaffDetailsGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseStaffDetailsGroup(el, cursor, ParseContext{}); -} - StaffDetailsGroup parseStaffDetailsGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { StaffDetailsGroup out; diff --git a/src/private/mx/core/generated/StaffDetailsGroup.h b/src/private/mx/core/generated/StaffDetailsGroup.h index a354bc89c..cbf3fd08e 100644 --- a/src/private/mx/core/generated/StaffDetailsGroup.h +++ b/src/private/mx/core/generated/StaffDetailsGroup.h @@ -39,8 +39,6 @@ class StaffDetailsGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -StaffDetailsGroup parseStaffDetailsGroup(pugi::xml_node el, pugi::xml_node &cursor); - StaffDetailsGroup parseStaffDetailsGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeStaffDetailsGroup(const StaffDetailsGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/StaffDivide.cpp b/src/private/mx/core/generated/StaffDivide.cpp index 3cd1ef034..0f0b0dd8c 100644 --- a/src/private/mx/core/generated/StaffDivide.cpp +++ b/src/private/mx/core/generated/StaffDivide.cpp @@ -141,11 +141,6 @@ void StaffDivide::setID(std::optional value) m_id = std::move(value); } -StaffDivide parseStaffDivide(pugi::xml_node el) -{ - return parseStaffDivide(el, ParseContext{}); -} - StaffDivide parseStaffDivide(pugi::xml_node el, const ParseContext &context) { StaffDivide out; @@ -223,11 +218,6 @@ StaffDivide parseStaffDivide(pugi::xml_node el, const ParseContext &context) return out; } -void parseStaffDivideContent(StaffDivide &out, pugi::xml_node el) -{ - parseStaffDivideContent(out, el, ParseContext{}); -} - void parseStaffDivideContent(StaffDivide &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/StaffDivide.h b/src/private/mx/core/generated/StaffDivide.h index 442f3052f..988ed2e95 100644 --- a/src/private/mx/core/generated/StaffDivide.h +++ b/src/private/mx/core/generated/StaffDivide.h @@ -76,12 +76,8 @@ class StaffDivide final std::optional m_id; }; -StaffDivide parseStaffDivide(pugi::xml_node el); - StaffDivide parseStaffDivide(pugi::xml_node el, const ParseContext &context); -void parseStaffDivideContent(StaffDivide &out, pugi::xml_node el); - void parseStaffDivideContent(StaffDivide &out, pugi::xml_node el, const ParseContext &context); void serializeStaffDivide(const StaffDivide &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/StaffLayout.cpp b/src/private/mx/core/generated/StaffLayout.cpp index 3c69e05e5..021968aad 100644 --- a/src/private/mx/core/generated/StaffLayout.cpp +++ b/src/private/mx/core/generated/StaffLayout.cpp @@ -31,11 +31,6 @@ void StaffLayout::setStaffDistance(std::optional value) m_staffDistance = std::move(value); } -StaffLayout parseStaffLayout(pugi::xml_node el) -{ - return parseStaffLayout(el, ParseContext{}); -} - StaffLayout parseStaffLayout(pugi::xml_node el, const ParseContext &context) { StaffLayout out; @@ -59,11 +54,6 @@ StaffLayout parseStaffLayout(pugi::xml_node el, const ParseContext &context) return out; } -void parseStaffLayoutContent(StaffLayout &out, pugi::xml_node el) -{ - parseStaffLayoutContent(out, el, ParseContext{}); -} - void parseStaffLayoutContent(StaffLayout &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/StaffLayout.h b/src/private/mx/core/generated/StaffLayout.h index bbd050ab4..963b4e6c7 100644 --- a/src/private/mx/core/generated/StaffLayout.h +++ b/src/private/mx/core/generated/StaffLayout.h @@ -42,12 +42,8 @@ class StaffLayout final std::optional m_staffDistance; }; -StaffLayout parseStaffLayout(pugi::xml_node el); - StaffLayout parseStaffLayout(pugi::xml_node el, const ParseContext &context); -void parseStaffLayoutContent(StaffLayout &out, pugi::xml_node el); - void parseStaffLayoutContent(StaffLayout &out, pugi::xml_node el, const ParseContext &context); void serializeStaffLayout(const StaffLayout &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/StaffSize.cpp b/src/private/mx/core/generated/StaffSize.cpp index cab958238..701df9641 100644 --- a/src/private/mx/core/generated/StaffSize.cpp +++ b/src/private/mx/core/generated/StaffSize.cpp @@ -31,11 +31,6 @@ void StaffSize::setValue(NonNegativeDecimal value) m_value = std::move(value); } -StaffSize parseStaffSize(pugi::xml_node el) -{ - return parseStaffSize(el, ParseContext{}); -} - StaffSize parseStaffSize(pugi::xml_node el, const ParseContext &context) { StaffSize out; @@ -59,11 +54,6 @@ StaffSize parseStaffSize(pugi::xml_node el, const ParseContext &context) return out; } -void parseStaffSizeContent(StaffSize &out, pugi::xml_node el) -{ - parseStaffSizeContent(out, el, ParseContext{}); -} - void parseStaffSizeContent(StaffSize &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/StaffSize.h b/src/private/mx/core/generated/StaffSize.h index 67fe47283..2a4b1accc 100644 --- a/src/private/mx/core/generated/StaffSize.h +++ b/src/private/mx/core/generated/StaffSize.h @@ -42,12 +42,8 @@ class StaffSize final NonNegativeDecimal m_value{}; }; -StaffSize parseStaffSize(pugi::xml_node el); - StaffSize parseStaffSize(pugi::xml_node el, const ParseContext &context); -void parseStaffSizeContent(StaffSize &out, pugi::xml_node el); - void parseStaffSizeContent(StaffSize &out, pugi::xml_node el, const ParseContext &context); void serializeStaffSize(const StaffSize &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/StaffTuning.cpp b/src/private/mx/core/generated/StaffTuning.cpp index 64bd32a66..7accd9cc8 100644 --- a/src/private/mx/core/generated/StaffTuning.cpp +++ b/src/private/mx/core/generated/StaffTuning.cpp @@ -31,11 +31,6 @@ void StaffTuning::setTuning(TuningGroup value) m_tuning = std::move(value); } -StaffTuning parseStaffTuning(pugi::xml_node el) -{ - return parseStaffTuning(el, ParseContext{}); -} - StaffTuning parseStaffTuning(pugi::xml_node el, const ParseContext &context) { StaffTuning out; @@ -65,11 +60,6 @@ StaffTuning parseStaffTuning(pugi::xml_node el, const ParseContext &context) return out; } -void parseStaffTuningContent(StaffTuning &out, pugi::xml_node el) -{ - parseStaffTuningContent(out, el, ParseContext{}); -} - void parseStaffTuningContent(StaffTuning &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/StaffTuning.h b/src/private/mx/core/generated/StaffTuning.h index 0670771bd..3bb1ba431 100644 --- a/src/private/mx/core/generated/StaffTuning.h +++ b/src/private/mx/core/generated/StaffTuning.h @@ -37,12 +37,8 @@ class StaffTuning final TuningGroup m_tuning{}; }; -StaffTuning parseStaffTuning(pugi::xml_node el); - StaffTuning parseStaffTuning(pugi::xml_node el, const ParseContext &context); -void parseStaffTuningContent(StaffTuning &out, pugi::xml_node el); - void parseStaffTuningContent(StaffTuning &out, pugi::xml_node el, const ParseContext &context); void serializeStaffTuning(const StaffTuning &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Stem.cpp b/src/private/mx/core/generated/Stem.cpp index 85dea47de..d7042fb00 100644 --- a/src/private/mx/core/generated/Stem.cpp +++ b/src/private/mx/core/generated/Stem.cpp @@ -71,11 +71,6 @@ void Stem::setValue(StemValue value) m_value = std::move(value); } -Stem parseStem(pugi::xml_node el) -{ - return parseStem(el, ParseContext{}); -} - Stem parseStem(pugi::xml_node el, const ParseContext &context) { Stem out; @@ -115,11 +110,6 @@ Stem parseStem(pugi::xml_node el, const ParseContext &context) return out; } -void parseStemContent(Stem &out, pugi::xml_node el) -{ - parseStemContent(out, el, ParseContext{}); -} - void parseStemContent(Stem &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/Stem.h b/src/private/mx/core/generated/Stem.h index c31d58bf9..66c25bcdc 100644 --- a/src/private/mx/core/generated/Stem.h +++ b/src/private/mx/core/generated/Stem.h @@ -50,12 +50,8 @@ class Stem final StemValue m_value{}; }; -Stem parseStem(pugi::xml_node el); - Stem parseStem(pugi::xml_node el, const ParseContext &context); -void parseStemContent(Stem &out, pugi::xml_node el); - void parseStemContent(Stem &out, pugi::xml_node el, const ParseContext &context); void serializeStem(const Stem &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Stick.cpp b/src/private/mx/core/generated/Stick.cpp index 09fa51504..8a95ec6c9 100644 --- a/src/private/mx/core/generated/Stick.cpp +++ b/src/private/mx/core/generated/Stick.cpp @@ -61,11 +61,6 @@ void Stick::setStickMaterial(StickMaterial value) m_stickMaterial = std::move(value); } -Stick parseStick(pugi::xml_node el) -{ - return parseStick(el, ParseContext{}); -} - Stick parseStick(pugi::xml_node el, const ParseContext &context) { Stick out; @@ -97,11 +92,6 @@ Stick parseStick(pugi::xml_node el, const ParseContext &context) return out; } -void parseStickContent(Stick &out, pugi::xml_node el) -{ - parseStickContent(out, el, ParseContext{}); -} - void parseStickContent(Stick &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Stick.h b/src/private/mx/core/generated/Stick.h index e4cadbaba..fe9e1a0cf 100644 --- a/src/private/mx/core/generated/Stick.h +++ b/src/private/mx/core/generated/Stick.h @@ -50,12 +50,8 @@ class Stick final StickMaterial m_stickMaterial{}; }; -Stick parseStick(pugi::xml_node el); - Stick parseStick(pugi::xml_node el, const ParseContext &context); -void parseStickContent(Stick &out, pugi::xml_node el); - void parseStickContent(Stick &out, pugi::xml_node el, const ParseContext &context); void serializeStick(const Stick &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/String.cpp b/src/private/mx/core/generated/String.cpp index 279e6f9f9..3013162a4 100644 --- a/src/private/mx/core/generated/String.cpp +++ b/src/private/mx/core/generated/String.cpp @@ -121,11 +121,6 @@ void String::setValue(StringNumber value) m_value = std::move(value); } -String parseString(pugi::xml_node el) -{ - return parseString(el, ParseContext{}); -} - String parseString(pugi::xml_node el, const ParseContext &context) { String out; @@ -185,11 +180,6 @@ String parseString(pugi::xml_node el, const ParseContext &context) return out; } -void parseStringContent(String &out, pugi::xml_node el) -{ - parseStringContent(out, el, ParseContext{}); -} - void parseStringContent(String &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/String.h b/src/private/mx/core/generated/String.h index 1925e8a59..301cc8c7b 100644 --- a/src/private/mx/core/generated/String.h +++ b/src/private/mx/core/generated/String.h @@ -67,12 +67,8 @@ class String final StringNumber m_value{}; }; -String parseString(pugi::xml_node el); - String parseString(pugi::xml_node el, const ParseContext &context); -void parseStringContent(String &out, pugi::xml_node el); - void parseStringContent(String &out, pugi::xml_node el, const ParseContext &context); void serializeString(const String &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/StringMute.cpp b/src/private/mx/core/generated/StringMute.cpp index 4fb5da5f6..1fd60c0e6 100644 --- a/src/private/mx/core/generated/StringMute.cpp +++ b/src/private/mx/core/generated/StringMute.cpp @@ -141,11 +141,6 @@ void StringMute::setID(std::optional value) m_id = std::move(value); } -StringMute parseStringMute(pugi::xml_node el) -{ - return parseStringMute(el, ParseContext{}); -} - StringMute parseStringMute(pugi::xml_node el, const ParseContext &context) { StringMute out; @@ -223,11 +218,6 @@ StringMute parseStringMute(pugi::xml_node el, const ParseContext &context) return out; } -void parseStringMuteContent(StringMute &out, pugi::xml_node el) -{ - parseStringMuteContent(out, el, ParseContext{}); -} - void parseStringMuteContent(StringMute &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/StringMute.h b/src/private/mx/core/generated/StringMute.h index 8166d0871..01a9278a5 100644 --- a/src/private/mx/core/generated/StringMute.h +++ b/src/private/mx/core/generated/StringMute.h @@ -75,12 +75,8 @@ class StringMute final std::optional m_id; }; -StringMute parseStringMute(pugi::xml_node el); - StringMute parseStringMute(pugi::xml_node el, const ParseContext &context); -void parseStringMuteContent(StringMute &out, pugi::xml_node el); - void parseStringMuteContent(StringMute &out, pugi::xml_node el, const ParseContext &context); void serializeStringMute(const StringMute &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/StrongAccent.cpp b/src/private/mx/core/generated/StrongAccent.cpp index 961133e2b..6e820722c 100644 --- a/src/private/mx/core/generated/StrongAccent.cpp +++ b/src/private/mx/core/generated/StrongAccent.cpp @@ -21,11 +21,6 @@ void StrongAccent::setType(std::optional value) m_type = std::move(value); } -StrongAccent parseStrongAccent(pugi::xml_node el) -{ - return parseStrongAccent(el, ParseContext{}); -} - StrongAccent parseStrongAccent(pugi::xml_node el, const ParseContext &context) { StrongAccent out; diff --git a/src/private/mx/core/generated/StrongAccent.h b/src/private/mx/core/generated/StrongAccent.h index a4c3c0f5a..b12316fad 100644 --- a/src/private/mx/core/generated/StrongAccent.h +++ b/src/private/mx/core/generated/StrongAccent.h @@ -33,8 +33,6 @@ class StrongAccent : public EmptyPlacement std::optional m_type; }; -StrongAccent parseStrongAccent(pugi::xml_node el); - StrongAccent parseStrongAccent(pugi::xml_node el, const ParseContext &context); void serializeStrongAccent(const StrongAccent &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/StyleText.cpp b/src/private/mx/core/generated/StyleText.cpp index 266e663c4..2064e350c 100644 --- a/src/private/mx/core/generated/StyleText.cpp +++ b/src/private/mx/core/generated/StyleText.cpp @@ -111,11 +111,6 @@ void StyleText::setValue(std::string value) m_value = std::move(value); } -StyleText parseStyleText(pugi::xml_node el) -{ - return parseStyleText(el, ParseContext{}); -} - StyleText parseStyleText(pugi::xml_node el, const ParseContext &context) { StyleText out; @@ -171,11 +166,6 @@ StyleText parseStyleText(pugi::xml_node el, const ParseContext &context) return out; } -void parseStyleTextContent(StyleText &out, pugi::xml_node el) -{ - parseStyleTextContent(out, el, ParseContext{}); -} - void parseStyleTextContent(StyleText &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/StyleText.h b/src/private/mx/core/generated/StyleText.h index dcaaab9b8..ee17b5b99 100644 --- a/src/private/mx/core/generated/StyleText.h +++ b/src/private/mx/core/generated/StyleText.h @@ -61,12 +61,8 @@ class StyleText final std::string m_value{}; }; -StyleText parseStyleText(pugi::xml_node el); - StyleText parseStyleText(pugi::xml_node el, const ParseContext &context); -void parseStyleTextContent(StyleText &out, pugi::xml_node el); - void parseStyleTextContent(StyleText &out, pugi::xml_node el, const ParseContext &context); void serializeStyleText(const StyleText &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Supports.cpp b/src/private/mx/core/generated/Supports.cpp index 423bd4a9d..6ef77731f 100644 --- a/src/private/mx/core/generated/Supports.cpp +++ b/src/private/mx/core/generated/Supports.cpp @@ -51,11 +51,6 @@ void Supports::setValue(std::optional value) m_value = std::move(value); } -Supports parseSupports(pugi::xml_node el) -{ - return parseSupports(el, ParseContext{}); -} - Supports parseSupports(pugi::xml_node el, const ParseContext &context) { Supports out; @@ -103,11 +98,6 @@ Supports parseSupports(pugi::xml_node el, const ParseContext &context) return out; } -void parseSupportsContent(Supports &out, pugi::xml_node el) -{ - parseSupportsContent(out, el, ParseContext{}); -} - void parseSupportsContent(Supports &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/Supports.h b/src/private/mx/core/generated/Supports.h index 9d26a13bd..36e255ed9 100644 --- a/src/private/mx/core/generated/Supports.h +++ b/src/private/mx/core/generated/Supports.h @@ -45,12 +45,8 @@ class Supports final std::optional m_value; }; -Supports parseSupports(pugi::xml_node el); - Supports parseSupports(pugi::xml_node el, const ParseContext &context); -void parseSupportsContent(Supports &out, pugi::xml_node el); - void parseSupportsContent(Supports &out, pugi::xml_node el, const ParseContext &context); void serializeSupports(const Supports &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Swing.cpp b/src/private/mx/core/generated/Swing.cpp index 70cf732d1..89af41646 100644 --- a/src/private/mx/core/generated/Swing.cpp +++ b/src/private/mx/core/generated/Swing.cpp @@ -31,11 +31,6 @@ void Swing::setSwingStyle(std::optional value) m_swingStyle = std::move(value); } -Swing parseSwing(pugi::xml_node el) -{ - return parseSwing(el, ParseContext{}); -} - Swing parseSwing(pugi::xml_node el, const ParseContext &context) { Swing out; @@ -52,11 +47,6 @@ Swing parseSwing(pugi::xml_node el, const ParseContext &context) return out; } -void parseSwingContent(Swing &out, pugi::xml_node el) -{ - parseSwingContent(out, el, ParseContext{}); -} - void parseSwingContent(Swing &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Swing.h b/src/private/mx/core/generated/Swing.h index 186cd30ed..ce57a1312 100644 --- a/src/private/mx/core/generated/Swing.h +++ b/src/private/mx/core/generated/Swing.h @@ -49,12 +49,8 @@ class Swing final std::optional m_swingStyle; }; -Swing parseSwing(pugi::xml_node el); - Swing parseSwing(pugi::xml_node el, const ParseContext &context); -void parseSwingContent(Swing &out, pugi::xml_node el); - void parseSwingContent(Swing &out, pugi::xml_node el, const ParseContext &context); void serializeSwing(const Swing &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/SwingChoice.cpp b/src/private/mx/core/generated/SwingChoice.cpp index 1af044762..bacd5e70b 100644 --- a/src/private/mx/core/generated/SwingChoice.cpp +++ b/src/private/mx/core/generated/SwingChoice.cpp @@ -26,11 +26,6 @@ SwingChoice SwingChoice::group(SwingChoiceGroup value) return SwingChoice{Storage{std::in_place_index<1>, std::move(value)}}; } -SwingChoice parseSwingChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseSwingChoice(el, cursor, ParseContext{}); -} - SwingChoice parseSwingChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "straight"))) diff --git a/src/private/mx/core/generated/SwingChoice.h b/src/private/mx/core/generated/SwingChoice.h index cb99765cb..66ba73f10 100644 --- a/src/private/mx/core/generated/SwingChoice.h +++ b/src/private/mx/core/generated/SwingChoice.h @@ -82,8 +82,6 @@ class SwingChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -SwingChoice parseSwingChoice(pugi::xml_node el, pugi::xml_node &cursor); - SwingChoice parseSwingChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeSwingChoice(const SwingChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/SwingChoiceGroup.cpp b/src/private/mx/core/generated/SwingChoiceGroup.cpp index d271579a7..b26d40f37 100644 --- a/src/private/mx/core/generated/SwingChoiceGroup.cpp +++ b/src/private/mx/core/generated/SwingChoiceGroup.cpp @@ -41,11 +41,6 @@ void SwingChoiceGroup::setSwingType(std::optional value) m_swingType = std::move(value); } -SwingChoiceGroup parseSwingChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseSwingChoiceGroup(el, cursor, ParseContext{}); -} - SwingChoiceGroup parseSwingChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { SwingChoiceGroup out; diff --git a/src/private/mx/core/generated/SwingChoiceGroup.h b/src/private/mx/core/generated/SwingChoiceGroup.h index 4164c18bf..e8cf16cf8 100644 --- a/src/private/mx/core/generated/SwingChoiceGroup.h +++ b/src/private/mx/core/generated/SwingChoiceGroup.h @@ -41,8 +41,6 @@ class SwingChoiceGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -SwingChoiceGroup parseSwingChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor); - SwingChoiceGroup parseSwingChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeSwingChoiceGroup(const SwingChoiceGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Sync.cpp b/src/private/mx/core/generated/Sync.cpp index 4b83fe501..91e23db14 100644 --- a/src/private/mx/core/generated/Sync.cpp +++ b/src/private/mx/core/generated/Sync.cpp @@ -51,11 +51,6 @@ void Sync::setTimeOnly(std::optional value) m_timeOnly = std::move(value); } -Sync parseSync(pugi::xml_node el) -{ - return parseSync(el, ParseContext{}); -} - Sync parseSync(pugi::xml_node el, const ParseContext &context) { Sync out; @@ -97,11 +92,6 @@ Sync parseSync(pugi::xml_node el, const ParseContext &context) return out; } -void parseSyncContent(Sync &out, pugi::xml_node el) -{ - parseSyncContent(out, el, ParseContext{}); -} - void parseSyncContent(Sync &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/Sync.h b/src/private/mx/core/generated/Sync.h index efc2ac6fb..17a4ead92 100644 --- a/src/private/mx/core/generated/Sync.h +++ b/src/private/mx/core/generated/Sync.h @@ -47,12 +47,8 @@ class Sync final std::optional m_timeOnly; }; -Sync parseSync(pugi::xml_node el); - Sync parseSync(pugi::xml_node el, const ParseContext &context); -void parseSyncContent(Sync &out, pugi::xml_node el); - void parseSyncContent(Sync &out, pugi::xml_node el, const ParseContext &context); void serializeSync(const Sync &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/SystemDividers.cpp b/src/private/mx/core/generated/SystemDividers.cpp index 557f3f72c..9bc60b94c 100644 --- a/src/private/mx/core/generated/SystemDividers.cpp +++ b/src/private/mx/core/generated/SystemDividers.cpp @@ -31,11 +31,6 @@ void SystemDividers::setRightDivider(EmptyPrintObjectStyleAlign value) m_rightDivider = std::move(value); } -SystemDividers parseSystemDividers(pugi::xml_node el) -{ - return parseSystemDividers(el, ParseContext{}); -} - SystemDividers parseSystemDividers(pugi::xml_node el, const ParseContext &context) { SystemDividers out; @@ -52,11 +47,6 @@ SystemDividers parseSystemDividers(pugi::xml_node el, const ParseContext &contex return out; } -void parseSystemDividersContent(SystemDividers &out, pugi::xml_node el) -{ - parseSystemDividersContent(out, el, ParseContext{}); -} - void parseSystemDividersContent(SystemDividers &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/SystemDividers.h b/src/private/mx/core/generated/SystemDividers.h index a8fdeb9e3..bad300973 100644 --- a/src/private/mx/core/generated/SystemDividers.h +++ b/src/private/mx/core/generated/SystemDividers.h @@ -42,12 +42,8 @@ class SystemDividers final EmptyPrintObjectStyleAlign m_rightDivider{}; }; -SystemDividers parseSystemDividers(pugi::xml_node el); - SystemDividers parseSystemDividers(pugi::xml_node el, const ParseContext &context); -void parseSystemDividersContent(SystemDividers &out, pugi::xml_node el); - void parseSystemDividersContent(SystemDividers &out, pugi::xml_node el, const ParseContext &context); void serializeSystemDividers(const SystemDividers &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/SystemLayout.cpp b/src/private/mx/core/generated/SystemLayout.cpp index 8329706a3..859919c36 100644 --- a/src/private/mx/core/generated/SystemLayout.cpp +++ b/src/private/mx/core/generated/SystemLayout.cpp @@ -51,11 +51,6 @@ void SystemLayout::setSystemDividers(std::optional value) m_systemDividers = std::move(value); } -SystemLayout parseSystemLayout(pugi::xml_node el) -{ - return parseSystemLayout(el, ParseContext{}); -} - SystemLayout parseSystemLayout(pugi::xml_node el, const ParseContext &context) { SystemLayout out; @@ -72,11 +67,6 @@ SystemLayout parseSystemLayout(pugi::xml_node el, const ParseContext &context) return out; } -void parseSystemLayoutContent(SystemLayout &out, pugi::xml_node el) -{ - parseSystemLayoutContent(out, el, ParseContext{}); -} - void parseSystemLayoutContent(SystemLayout &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/SystemLayout.h b/src/private/mx/core/generated/SystemLayout.h index d1ebf4f1d..a949bfc9f 100644 --- a/src/private/mx/core/generated/SystemLayout.h +++ b/src/private/mx/core/generated/SystemLayout.h @@ -60,12 +60,8 @@ class SystemLayout final std::optional m_systemDividers; }; -SystemLayout parseSystemLayout(pugi::xml_node el); - SystemLayout parseSystemLayout(pugi::xml_node el, const ParseContext &context); -void parseSystemLayoutContent(SystemLayout &out, pugi::xml_node el); - void parseSystemLayoutContent(SystemLayout &out, pugi::xml_node el, const ParseContext &context); void serializeSystemLayout(const SystemLayout &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/SystemMargins.cpp b/src/private/mx/core/generated/SystemMargins.cpp index 96b922916..7e6d12716 100644 --- a/src/private/mx/core/generated/SystemMargins.cpp +++ b/src/private/mx/core/generated/SystemMargins.cpp @@ -21,11 +21,6 @@ void SystemMargins::setLeftRightMargins(LeftRightMarginsGroup value) m_leftRightMargins = std::move(value); } -SystemMargins parseSystemMargins(pugi::xml_node el) -{ - return parseSystemMargins(el, ParseContext{}); -} - SystemMargins parseSystemMargins(pugi::xml_node el, const ParseContext &context) { SystemMargins out; @@ -42,11 +37,6 @@ SystemMargins parseSystemMargins(pugi::xml_node el, const ParseContext &context) return out; } -void parseSystemMarginsContent(SystemMargins &out, pugi::xml_node el) -{ - parseSystemMarginsContent(out, el, ParseContext{}); -} - void parseSystemMarginsContent(SystemMargins &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/SystemMargins.h b/src/private/mx/core/generated/SystemMargins.h index 78ade809f..480e75ff6 100644 --- a/src/private/mx/core/generated/SystemMargins.h +++ b/src/private/mx/core/generated/SystemMargins.h @@ -34,12 +34,8 @@ class SystemMargins final LeftRightMarginsGroup m_leftRightMargins{}; }; -SystemMargins parseSystemMargins(pugi::xml_node el); - SystemMargins parseSystemMargins(pugi::xml_node el, const ParseContext &context); -void parseSystemMarginsContent(SystemMargins &out, pugi::xml_node el); - void parseSystemMarginsContent(SystemMargins &out, pugi::xml_node el, const ParseContext &context); void serializeSystemMargins(const SystemMargins &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Tap.cpp b/src/private/mx/core/generated/Tap.cpp index 8ea61a36e..d12348a0c 100644 --- a/src/private/mx/core/generated/Tap.cpp +++ b/src/private/mx/core/generated/Tap.cpp @@ -131,11 +131,6 @@ void Tap::setValue(std::string value) m_value = std::move(value); } -Tap parseTap(pugi::xml_node el) -{ - return parseTap(el, ParseContext{}); -} - Tap parseTap(pugi::xml_node el, const ParseContext &context) { Tap out; @@ -199,11 +194,6 @@ Tap parseTap(pugi::xml_node el, const ParseContext &context) return out; } -void parseTapContent(Tap &out, pugi::xml_node el) -{ - parseTapContent(out, el, ParseContext{}); -} - void parseTapContent(Tap &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/Tap.h b/src/private/mx/core/generated/Tap.h index 6228d8134..60ec81543 100644 --- a/src/private/mx/core/generated/Tap.h +++ b/src/private/mx/core/generated/Tap.h @@ -73,12 +73,8 @@ class Tap final std::string m_value{}; }; -Tap parseTap(pugi::xml_node el); - Tap parseTap(pugi::xml_node el, const ParseContext &context); -void parseTapContent(Tap &out, pugi::xml_node el); - void parseTapContent(Tap &out, pugi::xml_node el, const ParseContext &context); void serializeTap(const Tap &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Technical.cpp b/src/private/mx/core/generated/Technical.cpp index fabfc5ddc..e7d419bac 100644 --- a/src/private/mx/core/generated/Technical.cpp +++ b/src/private/mx/core/generated/Technical.cpp @@ -36,11 +36,6 @@ void Technical::setChoice(std::vector value) m_choice = std::move(value); } -Technical parseTechnical(pugi::xml_node el) -{ - return parseTechnical(el, ParseContext{}); -} - Technical parseTechnical(pugi::xml_node el, const ParseContext &context) { Technical out; @@ -64,11 +59,6 @@ Technical parseTechnical(pugi::xml_node el, const ParseContext &context) return out; } -void parseTechnicalContent(Technical &out, pugi::xml_node el) -{ - parseTechnicalContent(out, el, ParseContext{}); -} - void parseTechnicalContent(Technical &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Technical.h b/src/private/mx/core/generated/Technical.h index 8cb8e1a93..ca6bd5bcf 100644 --- a/src/private/mx/core/generated/Technical.h +++ b/src/private/mx/core/generated/Technical.h @@ -39,12 +39,8 @@ class Technical final std::vector m_choice; }; -Technical parseTechnical(pugi::xml_node el); - Technical parseTechnical(pugi::xml_node el, const ParseContext &context); -void parseTechnicalContent(Technical &out, pugi::xml_node el); - void parseTechnicalContent(Technical &out, pugi::xml_node el, const ParseContext &context); void serializeTechnical(const Technical &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/TechnicalChoice.cpp b/src/private/mx/core/generated/TechnicalChoice.cpp index 9e7f65e12..7141bcb21 100644 --- a/src/private/mx/core/generated/TechnicalChoice.cpp +++ b/src/private/mx/core/generated/TechnicalChoice.cpp @@ -171,11 +171,6 @@ TechnicalChoice TechnicalChoice::otherTechnical(OtherPlacementText value) return TechnicalChoice{Storage{std::in_place_index<30>, std::move(value)}}; } -TechnicalChoice parseTechnicalChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseTechnicalChoice(el, cursor, ParseContext{}); -} - TechnicalChoice parseTechnicalChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "up-bow"))) diff --git a/src/private/mx/core/generated/TechnicalChoice.h b/src/private/mx/core/generated/TechnicalChoice.h index 37de53941..431f0f472 100644 --- a/src/private/mx/core/generated/TechnicalChoice.h +++ b/src/private/mx/core/generated/TechnicalChoice.h @@ -507,8 +507,6 @@ class TechnicalChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -TechnicalChoice parseTechnicalChoice(pugi::xml_node el, pugi::xml_node &cursor); - TechnicalChoice parseTechnicalChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeTechnicalChoice(const TechnicalChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/TextElementData.cpp b/src/private/mx/core/generated/TextElementData.cpp index 10b58a695..38b6b754f 100644 --- a/src/private/mx/core/generated/TextElementData.cpp +++ b/src/private/mx/core/generated/TextElementData.cpp @@ -141,11 +141,6 @@ void TextElementData::setValue(std::string value) m_value = std::move(value); } -TextElementData parseTextElementData(pugi::xml_node el) -{ - return parseTextElementData(el, ParseContext{}); -} - TextElementData parseTextElementData(pugi::xml_node el, const ParseContext &context) { TextElementData out; @@ -213,11 +208,6 @@ TextElementData parseTextElementData(pugi::xml_node el, const ParseContext &cont return out; } -void parseTextElementDataContent(TextElementData &out, pugi::xml_node el) -{ - parseTextElementDataContent(out, el, ParseContext{}); -} - void parseTextElementDataContent(TextElementData &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/TextElementData.h b/src/private/mx/core/generated/TextElementData.h index 14c8e98fa..1d5bd6f1c 100644 --- a/src/private/mx/core/generated/TextElementData.h +++ b/src/private/mx/core/generated/TextElementData.h @@ -75,12 +75,8 @@ class TextElementData final std::string m_value{}; }; -TextElementData parseTextElementData(pugi::xml_node el); - TextElementData parseTextElementData(pugi::xml_node el, const ParseContext &context); -void parseTextElementDataContent(TextElementData &out, pugi::xml_node el); - void parseTextElementDataContent(TextElementData &out, pugi::xml_node el, const ParseContext &context); void serializeTextElementData(const TextElementData &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Tie.cpp b/src/private/mx/core/generated/Tie.cpp index 28bc56fed..3b5842422 100644 --- a/src/private/mx/core/generated/Tie.cpp +++ b/src/private/mx/core/generated/Tie.cpp @@ -31,11 +31,6 @@ void Tie::setTimeOnly(std::optional value) m_timeOnly = std::move(value); } -Tie parseTie(pugi::xml_node el) -{ - return parseTie(el, ParseContext{}); -} - Tie parseTie(pugi::xml_node el, const ParseContext &context) { Tie out; @@ -69,11 +64,6 @@ Tie parseTie(pugi::xml_node el, const ParseContext &context) return out; } -void parseTieContent(Tie &out, pugi::xml_node el) -{ - parseTieContent(out, el, ParseContext{}); -} - void parseTieContent(Tie &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/Tie.h b/src/private/mx/core/generated/Tie.h index 93a4bb2a1..1b1a94344 100644 --- a/src/private/mx/core/generated/Tie.h +++ b/src/private/mx/core/generated/Tie.h @@ -35,12 +35,8 @@ class Tie final std::optional m_timeOnly; }; -Tie parseTie(pugi::xml_node el); - Tie parseTie(pugi::xml_node el, const ParseContext &context); -void parseTieContent(Tie &out, pugi::xml_node el); - void parseTieContent(Tie &out, pugi::xml_node el, const ParseContext &context); void serializeTie(const Tie &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Tied.cpp b/src/private/mx/core/generated/Tied.cpp index 1717eb182..39f8a2d5c 100644 --- a/src/private/mx/core/generated/Tied.cpp +++ b/src/private/mx/core/generated/Tied.cpp @@ -201,11 +201,6 @@ void Tied::setID(std::optional value) m_id = std::move(value); } -Tied parseTied(pugi::xml_node el) -{ - return parseTied(el, ParseContext{}); -} - Tied parseTied(pugi::xml_node el, const ParseContext &context) { Tied out; @@ -307,11 +302,6 @@ Tied parseTied(pugi::xml_node el, const ParseContext &context) return out; } -void parseTiedContent(Tied &out, pugi::xml_node el) -{ - parseTiedContent(out, el, ParseContext{}); -} - void parseTiedContent(Tied &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/Tied.h b/src/private/mx/core/generated/Tied.h index cc481a6b3..63981ad11 100644 --- a/src/private/mx/core/generated/Tied.h +++ b/src/private/mx/core/generated/Tied.h @@ -103,12 +103,8 @@ class Tied final std::optional m_id; }; -Tied parseTied(pugi::xml_node el); - Tied parseTied(pugi::xml_node el, const ParseContext &context); -void parseTiedContent(Tied &out, pugi::xml_node el); - void parseTiedContent(Tied &out, pugi::xml_node el, const ParseContext &context); void serializeTied(const Tied &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Time.cpp b/src/private/mx/core/generated/Time.cpp index 47a2b66ab..7c92596f6 100644 --- a/src/private/mx/core/generated/Time.cpp +++ b/src/private/mx/core/generated/Time.cpp @@ -181,11 +181,6 @@ void Time::setChoice(TimeChoice value) m_choice = std::move(value); } -Time parseTime(pugi::xml_node el) -{ - return parseTime(el, ParseContext{}); -} - Time parseTime(pugi::xml_node el, const ParseContext &context) { Time out; @@ -269,11 +264,6 @@ Time parseTime(pugi::xml_node el, const ParseContext &context) return out; } -void parseTimeContent(Time &out, pugi::xml_node el) -{ - parseTimeContent(out, el, ParseContext{}); -} - void parseTimeContent(Time &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Time.h b/src/private/mx/core/generated/Time.h index d5fb2f520..cf479d025 100644 --- a/src/private/mx/core/generated/Time.h +++ b/src/private/mx/core/generated/Time.h @@ -102,12 +102,8 @@ class Time final TimeChoice m_choice{}; }; -Time parseTime(pugi::xml_node el); - Time parseTime(pugi::xml_node el, const ParseContext &context); -void parseTimeContent(Time &out, pugi::xml_node el); - void parseTimeContent(Time &out, pugi::xml_node el, const ParseContext &context); void serializeTime(const Time &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/TimeChoice.cpp b/src/private/mx/core/generated/TimeChoice.cpp index eb2e9c778..3ed14ffcf 100644 --- a/src/private/mx/core/generated/TimeChoice.cpp +++ b/src/private/mx/core/generated/TimeChoice.cpp @@ -26,11 +26,6 @@ TimeChoice TimeChoice::senzaMisura(std::string value) return TimeChoice{Storage{std::in_place_index<1>, std::move(value)}}; } -TimeChoice parseTimeChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseTimeChoice(el, cursor, ParseContext{}); -} - TimeChoice parseTimeChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { if (cursor && (cursorIs(cursor, "beats"))) diff --git a/src/private/mx/core/generated/TimeChoice.h b/src/private/mx/core/generated/TimeChoice.h index 867db15ce..31e6934e4 100644 --- a/src/private/mx/core/generated/TimeChoice.h +++ b/src/private/mx/core/generated/TimeChoice.h @@ -81,8 +81,6 @@ class TimeChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -TimeChoice parseTimeChoice(pugi::xml_node el, pugi::xml_node &cursor); - TimeChoice parseTimeChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeTimeChoice(const TimeChoice &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/TimeChoiceGroup.cpp b/src/private/mx/core/generated/TimeChoiceGroup.cpp index 2cf91a9c9..22a7ead11 100644 --- a/src/private/mx/core/generated/TimeChoiceGroup.cpp +++ b/src/private/mx/core/generated/TimeChoiceGroup.cpp @@ -36,11 +36,6 @@ void TimeChoiceGroup::setInterchangeable(std::optional value) m_interchangeable = std::move(value); } -TimeChoiceGroup parseTimeChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseTimeChoiceGroup(el, cursor, ParseContext{}); -} - TimeChoiceGroup parseTimeChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { TimeChoiceGroup out; diff --git a/src/private/mx/core/generated/TimeChoiceGroup.h b/src/private/mx/core/generated/TimeChoiceGroup.h index e74225528..713b85b0f 100644 --- a/src/private/mx/core/generated/TimeChoiceGroup.h +++ b/src/private/mx/core/generated/TimeChoiceGroup.h @@ -41,8 +41,6 @@ class TimeChoiceGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -TimeChoiceGroup parseTimeChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor); - TimeChoiceGroup parseTimeChoiceGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeTimeChoiceGroup(const TimeChoiceGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/TimeModification.cpp b/src/private/mx/core/generated/TimeModification.cpp index 9e8d12860..85b5e32c6 100644 --- a/src/private/mx/core/generated/TimeModification.cpp +++ b/src/private/mx/core/generated/TimeModification.cpp @@ -41,11 +41,6 @@ void TimeModification::setGroup(std::optional value) m_group = std::move(value); } -TimeModification parseTimeModification(pugi::xml_node el) -{ - return parseTimeModification(el, ParseContext{}); -} - TimeModification parseTimeModification(pugi::xml_node el, const ParseContext &context) { TimeModification out; @@ -62,11 +57,6 @@ TimeModification parseTimeModification(pugi::xml_node el, const ParseContext &co return out; } -void parseTimeModificationContent(TimeModification &out, pugi::xml_node el) -{ - parseTimeModificationContent(out, el, ParseContext{}); -} - void parseTimeModificationContent(TimeModification &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/TimeModification.h b/src/private/mx/core/generated/TimeModification.h index e8c356ca6..0d3f301af 100644 --- a/src/private/mx/core/generated/TimeModification.h +++ b/src/private/mx/core/generated/TimeModification.h @@ -43,12 +43,8 @@ class TimeModification std::optional m_group; }; -TimeModification parseTimeModification(pugi::xml_node el); - TimeModification parseTimeModification(pugi::xml_node el, const ParseContext &context); -void parseTimeModificationContent(TimeModification &out, pugi::xml_node el); - void parseTimeModificationContent(TimeModification &out, pugi::xml_node el, const ParseContext &context); void serializeTimeModification(const TimeModification &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/TimeModificationGroup.cpp b/src/private/mx/core/generated/TimeModificationGroup.cpp index d97c264a7..4af04c3f2 100644 --- a/src/private/mx/core/generated/TimeModificationGroup.cpp +++ b/src/private/mx/core/generated/TimeModificationGroup.cpp @@ -36,11 +36,6 @@ void TimeModificationGroup::setNormalDot(std::vector value) m_normalDot = std::move(value); } -TimeModificationGroup parseTimeModificationGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseTimeModificationGroup(el, cursor, ParseContext{}); -} - TimeModificationGroup parseTimeModificationGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { TimeModificationGroup out; diff --git a/src/private/mx/core/generated/TimeModificationGroup.h b/src/private/mx/core/generated/TimeModificationGroup.h index d82f64b25..69ac2e928 100644 --- a/src/private/mx/core/generated/TimeModificationGroup.h +++ b/src/private/mx/core/generated/TimeModificationGroup.h @@ -40,8 +40,6 @@ class TimeModificationGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -TimeModificationGroup parseTimeModificationGroup(pugi::xml_node el, pugi::xml_node &cursor); - TimeModificationGroup parseTimeModificationGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); diff --git a/src/private/mx/core/generated/TimeSignatureGroup.cpp b/src/private/mx/core/generated/TimeSignatureGroup.cpp index 8acc6e769..0633c6d45 100644 --- a/src/private/mx/core/generated/TimeSignatureGroup.cpp +++ b/src/private/mx/core/generated/TimeSignatureGroup.cpp @@ -31,11 +31,6 @@ void TimeSignatureGroup::setBeatType(std::string value) m_beatType = std::move(value); } -TimeSignatureGroup parseTimeSignatureGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseTimeSignatureGroup(el, cursor, ParseContext{}); -} - TimeSignatureGroup parseTimeSignatureGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { TimeSignatureGroup out; diff --git a/src/private/mx/core/generated/TimeSignatureGroup.h b/src/private/mx/core/generated/TimeSignatureGroup.h index 053ac9b44..6a5d93919 100644 --- a/src/private/mx/core/generated/TimeSignatureGroup.h +++ b/src/private/mx/core/generated/TimeSignatureGroup.h @@ -37,8 +37,6 @@ class TimeSignatureGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -TimeSignatureGroup parseTimeSignatureGroup(pugi::xml_node el, pugi::xml_node &cursor); - TimeSignatureGroup parseTimeSignatureGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeTimeSignatureGroup(const TimeSignatureGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/TimewiseMeasure.cpp b/src/private/mx/core/generated/TimewiseMeasure.cpp index 26acb88e8..2ca6bded4 100644 --- a/src/private/mx/core/generated/TimewiseMeasure.cpp +++ b/src/private/mx/core/generated/TimewiseMeasure.cpp @@ -86,11 +86,6 @@ void TimewiseMeasure::setPart(OneOrMore value) m_part = std::move(value); } -TimewiseMeasure parseTimewiseMeasure(pugi::xml_node el) -{ - return parseTimewiseMeasure(el, ParseContext{}); -} - TimewiseMeasure parseTimewiseMeasure(pugi::xml_node el, const ParseContext &context) { TimewiseMeasure out; @@ -140,11 +135,6 @@ TimewiseMeasure parseTimewiseMeasure(pugi::xml_node el, const ParseContext &cont return out; } -void parseTimewiseMeasureContent(TimewiseMeasure &out, pugi::xml_node el) -{ - parseTimewiseMeasureContent(out, el, ParseContext{}); -} - void parseTimewiseMeasureContent(TimewiseMeasure &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/TimewiseMeasure.h b/src/private/mx/core/generated/TimewiseMeasure.h index c19d2d7eb..6e6a3ebfb 100644 --- a/src/private/mx/core/generated/TimewiseMeasure.h +++ b/src/private/mx/core/generated/TimewiseMeasure.h @@ -57,12 +57,8 @@ class TimewiseMeasure final OneOrMore m_part; }; -TimewiseMeasure parseTimewiseMeasure(pugi::xml_node el); - TimewiseMeasure parseTimewiseMeasure(pugi::xml_node el, const ParseContext &context); -void parseTimewiseMeasureContent(TimewiseMeasure &out, pugi::xml_node el); - void parseTimewiseMeasureContent(TimewiseMeasure &out, pugi::xml_node el, const ParseContext &context); void serializeTimewiseMeasure(const TimewiseMeasure &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/TimewisePart.cpp b/src/private/mx/core/generated/TimewisePart.cpp index 76c4cb5ff..f0060a1ea 100644 --- a/src/private/mx/core/generated/TimewisePart.cpp +++ b/src/private/mx/core/generated/TimewisePart.cpp @@ -36,11 +36,6 @@ void TimewisePart::setMusicData(std::vector value) m_musicData = std::move(value); } -TimewisePart parseTimewisePart(pugi::xml_node el) -{ - return parseTimewisePart(el, ParseContext{}); -} - TimewisePart parseTimewisePart(pugi::xml_node el, const ParseContext &context) { TimewisePart out; @@ -70,11 +65,6 @@ TimewisePart parseTimewisePart(pugi::xml_node el, const ParseContext &context) return out; } -void parseTimewisePartContent(TimewisePart &out, pugi::xml_node el) -{ - parseTimewisePartContent(out, el, ParseContext{}); -} - void parseTimewisePartContent(TimewisePart &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/TimewisePart.h b/src/private/mx/core/generated/TimewisePart.h index c348b7422..7a83a555d 100644 --- a/src/private/mx/core/generated/TimewisePart.h +++ b/src/private/mx/core/generated/TimewisePart.h @@ -38,12 +38,8 @@ class TimewisePart final std::vector m_musicData; }; -TimewisePart parseTimewisePart(pugi::xml_node el); - TimewisePart parseTimewisePart(pugi::xml_node el, const ParseContext &context); -void parseTimewisePartContent(TimewisePart &out, pugi::xml_node el); - void parseTimewisePartContent(TimewisePart &out, pugi::xml_node el, const ParseContext &context); void serializeTimewisePart(const TimewisePart &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Timpani.cpp b/src/private/mx/core/generated/Timpani.cpp index 339ddbdf5..116daf3c8 100644 --- a/src/private/mx/core/generated/Timpani.cpp +++ b/src/private/mx/core/generated/Timpani.cpp @@ -21,11 +21,6 @@ void Timpani::setSmufl(std::optional value) m_smufl = std::move(value); } -Timpani parseTimpani(pugi::xml_node el) -{ - return parseTimpani(el, ParseContext{}); -} - Timpani parseTimpani(pugi::xml_node el, const ParseContext &context) { Timpani out; @@ -49,11 +44,6 @@ Timpani parseTimpani(pugi::xml_node el, const ParseContext &context) return out; } -void parseTimpaniContent(Timpani &out, pugi::xml_node el) -{ - parseTimpaniContent(out, el, ParseContext{}); -} - void parseTimpaniContent(Timpani &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/Timpani.h b/src/private/mx/core/generated/Timpani.h index e42ecbd66..6ed4b21f6 100644 --- a/src/private/mx/core/generated/Timpani.h +++ b/src/private/mx/core/generated/Timpani.h @@ -30,12 +30,8 @@ class Timpani final std::optional m_smufl; }; -Timpani parseTimpani(pugi::xml_node el); - Timpani parseTimpani(pugi::xml_node el, const ParseContext &context); -void parseTimpaniContent(Timpani &out, pugi::xml_node el); - void parseTimpaniContent(Timpani &out, pugi::xml_node el, const ParseContext &context); void serializeTimpani(const Timpani &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/TraditionalKeyGroup.cpp b/src/private/mx/core/generated/TraditionalKeyGroup.cpp index 1f98f8dec..0ac5c027d 100644 --- a/src/private/mx/core/generated/TraditionalKeyGroup.cpp +++ b/src/private/mx/core/generated/TraditionalKeyGroup.cpp @@ -41,11 +41,6 @@ void TraditionalKeyGroup::setMode(std::optional value) m_mode = std::move(value); } -TraditionalKeyGroup parseTraditionalKeyGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseTraditionalKeyGroup(el, cursor, ParseContext{}); -} - TraditionalKeyGroup parseTraditionalKeyGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { TraditionalKeyGroup out; diff --git a/src/private/mx/core/generated/TraditionalKeyGroup.h b/src/private/mx/core/generated/TraditionalKeyGroup.h index 471bf3b18..4f2eaef2c 100644 --- a/src/private/mx/core/generated/TraditionalKeyGroup.h +++ b/src/private/mx/core/generated/TraditionalKeyGroup.h @@ -43,8 +43,6 @@ class TraditionalKeyGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -TraditionalKeyGroup parseTraditionalKeyGroup(pugi::xml_node el, pugi::xml_node &cursor); - TraditionalKeyGroup parseTraditionalKeyGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeTraditionalKeyGroup(const TraditionalKeyGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Transpose.cpp b/src/private/mx/core/generated/Transpose.cpp index 044df0e8e..54ada6c62 100644 --- a/src/private/mx/core/generated/Transpose.cpp +++ b/src/private/mx/core/generated/Transpose.cpp @@ -41,11 +41,6 @@ void Transpose::setTranspose(TransposeGroup value) m_transpose = std::move(value); } -Transpose parseTranspose(pugi::xml_node el) -{ - return parseTranspose(el, ParseContext{}); -} - Transpose parseTranspose(pugi::xml_node el, const ParseContext &context) { Transpose out; @@ -73,11 +68,6 @@ Transpose parseTranspose(pugi::xml_node el, const ParseContext &context) return out; } -void parseTransposeContent(Transpose &out, pugi::xml_node el) -{ - parseTransposeContent(out, el, ParseContext{}); -} - void parseTransposeContent(Transpose &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Transpose.h b/src/private/mx/core/generated/Transpose.h index c2a18eb6b..fb2553edf 100644 --- a/src/private/mx/core/generated/Transpose.h +++ b/src/private/mx/core/generated/Transpose.h @@ -45,12 +45,8 @@ class Transpose final TransposeGroup m_transpose{}; }; -Transpose parseTranspose(pugi::xml_node el); - Transpose parseTranspose(pugi::xml_node el, const ParseContext &context); -void parseTransposeContent(Transpose &out, pugi::xml_node el); - void parseTransposeContent(Transpose &out, pugi::xml_node el, const ParseContext &context); void serializeTranspose(const Transpose &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/TransposeGroup.cpp b/src/private/mx/core/generated/TransposeGroup.cpp index 9d9fb33b2..53a65ebe8 100644 --- a/src/private/mx/core/generated/TransposeGroup.cpp +++ b/src/private/mx/core/generated/TransposeGroup.cpp @@ -51,11 +51,6 @@ void TransposeGroup::setDouble(std::optional value) m_double_ = std::move(value); } -TransposeGroup parseTransposeGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseTransposeGroup(el, cursor, ParseContext{}); -} - TransposeGroup parseTransposeGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { TransposeGroup out; diff --git a/src/private/mx/core/generated/TransposeGroup.h b/src/private/mx/core/generated/TransposeGroup.h index deb762bd5..e73014e13 100644 --- a/src/private/mx/core/generated/TransposeGroup.h +++ b/src/private/mx/core/generated/TransposeGroup.h @@ -46,8 +46,6 @@ class TransposeGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -TransposeGroup parseTransposeGroup(pugi::xml_node el, pugi::xml_node &cursor); - TransposeGroup parseTransposeGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeTransposeGroup(const TransposeGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Tremolo.cpp b/src/private/mx/core/generated/Tremolo.cpp index ac7350267..1c9699d23 100644 --- a/src/private/mx/core/generated/Tremolo.cpp +++ b/src/private/mx/core/generated/Tremolo.cpp @@ -141,11 +141,6 @@ void Tremolo::setValue(TremoloMarks value) m_value = std::move(value); } -Tremolo parseTremolo(pugi::xml_node el) -{ - return parseTremolo(el, ParseContext{}); -} - Tremolo parseTremolo(pugi::xml_node el, const ParseContext &context) { Tremolo out; @@ -213,11 +208,6 @@ Tremolo parseTremolo(pugi::xml_node el, const ParseContext &context) return out; } -void parseTremoloContent(Tremolo &out, pugi::xml_node el) -{ - parseTremoloContent(out, el, ParseContext{}); -} - void parseTremoloContent(Tremolo &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/Tremolo.h b/src/private/mx/core/generated/Tremolo.h index 3ee8bcdac..838f4f8e9 100644 --- a/src/private/mx/core/generated/Tremolo.h +++ b/src/private/mx/core/generated/Tremolo.h @@ -86,12 +86,8 @@ class Tremolo final TremoloMarks m_value{}; }; -Tremolo parseTremolo(pugi::xml_node el); - Tremolo parseTremolo(pugi::xml_node el, const ParseContext &context); -void parseTremoloContent(Tremolo &out, pugi::xml_node el); - void parseTremoloContent(Tremolo &out, pugi::xml_node el, const ParseContext &context); void serializeTremolo(const Tremolo &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/TuningGroup.cpp b/src/private/mx/core/generated/TuningGroup.cpp index 7882ca893..bed10873b 100644 --- a/src/private/mx/core/generated/TuningGroup.cpp +++ b/src/private/mx/core/generated/TuningGroup.cpp @@ -41,11 +41,6 @@ void TuningGroup::setTuningOctave(Octave value) m_tuningOctave = std::move(value); } -TuningGroup parseTuningGroup(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseTuningGroup(el, cursor, ParseContext{}); -} - TuningGroup parseTuningGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { TuningGroup out; diff --git a/src/private/mx/core/generated/TuningGroup.h b/src/private/mx/core/generated/TuningGroup.h index 4adb6b1ba..7dba5e70f 100644 --- a/src/private/mx/core/generated/TuningGroup.h +++ b/src/private/mx/core/generated/TuningGroup.h @@ -44,8 +44,6 @@ class TuningGroup final /// Consumes matching siblings starting at `cursor` (which advances); `el` /// is the enclosing element, for error paths. -TuningGroup parseTuningGroup(pugi::xml_node el, pugi::xml_node &cursor); - TuningGroup parseTuningGroup(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); void serializeTuningGroup(const TuningGroup &v, pugi::xml_node el); diff --git a/src/private/mx/core/generated/Tuplet.cpp b/src/private/mx/core/generated/Tuplet.cpp index 4bf9b0712..df0f964c7 100644 --- a/src/private/mx/core/generated/Tuplet.cpp +++ b/src/private/mx/core/generated/Tuplet.cpp @@ -151,11 +151,6 @@ void Tuplet::setTupletNormal(std::optional value) m_tupletNormal = std::move(value); } -Tuplet parseTuplet(pugi::xml_node el) -{ - return parseTuplet(el, ParseContext{}); -} - Tuplet parseTuplet(pugi::xml_node el, const ParseContext &context) { Tuplet out; @@ -229,11 +224,6 @@ Tuplet parseTuplet(pugi::xml_node el, const ParseContext &context) return out; } -void parseTupletContent(Tuplet &out, pugi::xml_node el) -{ - parseTupletContent(out, el, ParseContext{}); -} - void parseTupletContent(Tuplet &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Tuplet.h b/src/private/mx/core/generated/Tuplet.h index 5ca86ac33..909a332df 100644 --- a/src/private/mx/core/generated/Tuplet.h +++ b/src/private/mx/core/generated/Tuplet.h @@ -93,12 +93,8 @@ class Tuplet final std::optional m_tupletNormal; }; -Tuplet parseTuplet(pugi::xml_node el); - Tuplet parseTuplet(pugi::xml_node el, const ParseContext &context); -void parseTupletContent(Tuplet &out, pugi::xml_node el); - void parseTupletContent(Tuplet &out, pugi::xml_node el, const ParseContext &context); void serializeTuplet(const Tuplet &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/TupletDot.cpp b/src/private/mx/core/generated/TupletDot.cpp index 49bfc232b..b86cb725d 100644 --- a/src/private/mx/core/generated/TupletDot.cpp +++ b/src/private/mx/core/generated/TupletDot.cpp @@ -61,11 +61,6 @@ void TupletDot::setColor(std::optional value) m_color = std::move(value); } -TupletDot parseTupletDot(pugi::xml_node el) -{ - return parseTupletDot(el, ParseContext{}); -} - TupletDot parseTupletDot(pugi::xml_node el, const ParseContext &context) { TupletDot out; @@ -105,11 +100,6 @@ TupletDot parseTupletDot(pugi::xml_node el, const ParseContext &context) return out; } -void parseTupletDotContent(TupletDot &out, pugi::xml_node el) -{ - parseTupletDotContent(out, el, ParseContext{}); -} - void parseTupletDotContent(TupletDot &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/TupletDot.h b/src/private/mx/core/generated/TupletDot.h index 458d96a1f..8f62ac224 100644 --- a/src/private/mx/core/generated/TupletDot.h +++ b/src/private/mx/core/generated/TupletDot.h @@ -45,12 +45,8 @@ class TupletDot final std::optional m_color; }; -TupletDot parseTupletDot(pugi::xml_node el); - TupletDot parseTupletDot(pugi::xml_node el, const ParseContext &context); -void parseTupletDotContent(TupletDot &out, pugi::xml_node el); - void parseTupletDotContent(TupletDot &out, pugi::xml_node el, const ParseContext &context); void serializeTupletDot(const TupletDot &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/TupletNumber.cpp b/src/private/mx/core/generated/TupletNumber.cpp index 866bc0c87..e274b4cd1 100644 --- a/src/private/mx/core/generated/TupletNumber.cpp +++ b/src/private/mx/core/generated/TupletNumber.cpp @@ -71,11 +71,6 @@ void TupletNumber::setValue(int value) m_value = std::move(value); } -TupletNumber parseTupletNumber(pugi::xml_node el) -{ - return parseTupletNumber(el, ParseContext{}); -} - TupletNumber parseTupletNumber(pugi::xml_node el, const ParseContext &context) { TupletNumber out; @@ -115,11 +110,6 @@ TupletNumber parseTupletNumber(pugi::xml_node el, const ParseContext &context) return out; } -void parseTupletNumberContent(TupletNumber &out, pugi::xml_node el) -{ - parseTupletNumberContent(out, el, ParseContext{}); -} - void parseTupletNumberContent(TupletNumber &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseIntegerValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/TupletNumber.h b/src/private/mx/core/generated/TupletNumber.h index 59293f0a2..b188a1d85 100644 --- a/src/private/mx/core/generated/TupletNumber.h +++ b/src/private/mx/core/generated/TupletNumber.h @@ -48,12 +48,8 @@ class TupletNumber final int m_value{}; }; -TupletNumber parseTupletNumber(pugi::xml_node el); - TupletNumber parseTupletNumber(pugi::xml_node el, const ParseContext &context); -void parseTupletNumberContent(TupletNumber &out, pugi::xml_node el); - void parseTupletNumberContent(TupletNumber &out, pugi::xml_node el, const ParseContext &context); void serializeTupletNumber(const TupletNumber &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/TupletPortion.cpp b/src/private/mx/core/generated/TupletPortion.cpp index 03499ae6a..860772545 100644 --- a/src/private/mx/core/generated/TupletPortion.cpp +++ b/src/private/mx/core/generated/TupletPortion.cpp @@ -46,11 +46,6 @@ void TupletPortion::setTupletDot(std::vector value) m_tupletDot = std::move(value); } -TupletPortion parseTupletPortion(pugi::xml_node el) -{ - return parseTupletPortion(el, ParseContext{}); -} - TupletPortion parseTupletPortion(pugi::xml_node el, const ParseContext &context) { TupletPortion out; @@ -67,11 +62,6 @@ TupletPortion parseTupletPortion(pugi::xml_node el, const ParseContext &context) return out; } -void parseTupletPortionContent(TupletPortion &out, pugi::xml_node el) -{ - parseTupletPortionContent(out, el, ParseContext{}); -} - void parseTupletPortionContent(TupletPortion &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/TupletPortion.h b/src/private/mx/core/generated/TupletPortion.h index d436f2dc7..8698cb2f8 100644 --- a/src/private/mx/core/generated/TupletPortion.h +++ b/src/private/mx/core/generated/TupletPortion.h @@ -45,12 +45,8 @@ class TupletPortion final std::vector m_tupletDot; }; -TupletPortion parseTupletPortion(pugi::xml_node el); - TupletPortion parseTupletPortion(pugi::xml_node el, const ParseContext &context); -void parseTupletPortionContent(TupletPortion &out, pugi::xml_node el); - void parseTupletPortionContent(TupletPortion &out, pugi::xml_node el, const ParseContext &context); void serializeTupletPortion(const TupletPortion &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/TupletType.cpp b/src/private/mx/core/generated/TupletType.cpp index dc3a3799b..d15bd7c3e 100644 --- a/src/private/mx/core/generated/TupletType.cpp +++ b/src/private/mx/core/generated/TupletType.cpp @@ -71,11 +71,6 @@ void TupletType::setValue(NoteTypeValue value) m_value = std::move(value); } -TupletType parseTupletType(pugi::xml_node el) -{ - return parseTupletType(el, ParseContext{}); -} - TupletType parseTupletType(pugi::xml_node el, const ParseContext &context) { TupletType out; @@ -115,11 +110,6 @@ TupletType parseTupletType(pugi::xml_node el, const ParseContext &context) return out; } -void parseTupletTypeContent(TupletType &out, pugi::xml_node el) -{ - parseTupletTypeContent(out, el, ParseContext{}); -} - void parseTupletTypeContent(TupletType &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/TupletType.h b/src/private/mx/core/generated/TupletType.h index 5fcd2c119..391bb2ebb 100644 --- a/src/private/mx/core/generated/TupletType.h +++ b/src/private/mx/core/generated/TupletType.h @@ -50,12 +50,8 @@ class TupletType final NoteTypeValue m_value{}; }; -TupletType parseTupletType(pugi::xml_node el); - TupletType parseTupletType(pugi::xml_node el, const ParseContext &context); -void parseTupletTypeContent(TupletType &out, pugi::xml_node el); - void parseTupletTypeContent(TupletType &out, pugi::xml_node el, const ParseContext &context); void serializeTupletType(const TupletType &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/TypedText.cpp b/src/private/mx/core/generated/TypedText.cpp index 0b4dfbbdb..ce8081aaf 100644 --- a/src/private/mx/core/generated/TypedText.cpp +++ b/src/private/mx/core/generated/TypedText.cpp @@ -31,11 +31,6 @@ void TypedText::setValue(std::string value) m_value = std::move(value); } -TypedText parseTypedText(pugi::xml_node el) -{ - return parseTypedText(el, ParseContext{}); -} - TypedText parseTypedText(pugi::xml_node el, const ParseContext &context) { TypedText out; @@ -59,11 +54,6 @@ TypedText parseTypedText(pugi::xml_node el, const ParseContext &context) return out; } -void parseTypedTextContent(TypedText &out, pugi::xml_node el) -{ - parseTypedTextContent(out, el, ParseContext{}); -} - void parseTypedTextContent(TypedText &out, pugi::xml_node el, const ParseContext &context) { out.setValue(std::string{childText(el)}); diff --git a/src/private/mx/core/generated/TypedText.h b/src/private/mx/core/generated/TypedText.h index b98d51af4..43a9fbf27 100644 --- a/src/private/mx/core/generated/TypedText.h +++ b/src/private/mx/core/generated/TypedText.h @@ -30,12 +30,8 @@ class TypedText final std::string m_value{}; }; -TypedText parseTypedText(pugi::xml_node el); - TypedText parseTypedText(pugi::xml_node el, const ParseContext &context); -void parseTypedTextContent(TypedText &out, pugi::xml_node el); - void parseTypedTextContent(TypedText &out, pugi::xml_node el, const ParseContext &context); void serializeTypedText(const TypedText &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Unpitched.cpp b/src/private/mx/core/generated/Unpitched.cpp index d247cc792..40060e758 100644 --- a/src/private/mx/core/generated/Unpitched.cpp +++ b/src/private/mx/core/generated/Unpitched.cpp @@ -21,11 +21,6 @@ void Unpitched::setDisplayStepOctave(std::optional value m_displayStepOctave = std::move(value); } -Unpitched parseUnpitched(pugi::xml_node el) -{ - return parseUnpitched(el, ParseContext{}); -} - Unpitched parseUnpitched(pugi::xml_node el, const ParseContext &context) { Unpitched out; @@ -42,11 +37,6 @@ Unpitched parseUnpitched(pugi::xml_node el, const ParseContext &context) return out; } -void parseUnpitchedContent(Unpitched &out, pugi::xml_node el) -{ - parseUnpitchedContent(out, el, ParseContext{}); -} - void parseUnpitchedContent(Unpitched &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Unpitched.h b/src/private/mx/core/generated/Unpitched.h index 815d535bb..2baf09a5d 100644 --- a/src/private/mx/core/generated/Unpitched.h +++ b/src/private/mx/core/generated/Unpitched.h @@ -36,12 +36,8 @@ class Unpitched final std::optional m_displayStepOctave; }; -Unpitched parseUnpitched(pugi::xml_node el); - Unpitched parseUnpitched(pugi::xml_node el, const ParseContext &context); -void parseUnpitchedContent(Unpitched &out, pugi::xml_node el); - void parseUnpitchedContent(Unpitched &out, pugi::xml_node el, const ParseContext &context); void serializeUnpitched(const Unpitched &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/VirtualInstrument.cpp b/src/private/mx/core/generated/VirtualInstrument.cpp index 14006ff4d..b88080e90 100644 --- a/src/private/mx/core/generated/VirtualInstrument.cpp +++ b/src/private/mx/core/generated/VirtualInstrument.cpp @@ -31,11 +31,6 @@ void VirtualInstrument::setVirtualName(std::optional value) m_virtualName = std::move(value); } -VirtualInstrument parseVirtualInstrument(pugi::xml_node el) -{ - return parseVirtualInstrument(el, ParseContext{}); -} - VirtualInstrument parseVirtualInstrument(pugi::xml_node el, const ParseContext &context) { VirtualInstrument out; @@ -52,11 +47,6 @@ VirtualInstrument parseVirtualInstrument(pugi::xml_node el, const ParseContext & return out; } -void parseVirtualInstrumentContent(VirtualInstrument &out, pugi::xml_node el) -{ - parseVirtualInstrumentContent(out, el, ParseContext{}); -} - void parseVirtualInstrumentContent(VirtualInstrument &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/VirtualInstrument.h b/src/private/mx/core/generated/VirtualInstrument.h index 973639720..1d28f7687 100644 --- a/src/private/mx/core/generated/VirtualInstrument.h +++ b/src/private/mx/core/generated/VirtualInstrument.h @@ -35,12 +35,8 @@ class VirtualInstrument final std::optional m_virtualName; }; -VirtualInstrument parseVirtualInstrument(pugi::xml_node el); - VirtualInstrument parseVirtualInstrument(pugi::xml_node el, const ParseContext &context); -void parseVirtualInstrumentContent(VirtualInstrument &out, pugi::xml_node el); - void parseVirtualInstrumentContent(VirtualInstrument &out, pugi::xml_node el, const ParseContext &context); void serializeVirtualInstrument(const VirtualInstrument &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/VirtualInstrumentDataGroup.cpp b/src/private/mx/core/generated/VirtualInstrumentDataGroup.cpp index fa0b7a7e4..bb24ef1eb 100644 --- a/src/private/mx/core/generated/VirtualInstrumentDataGroup.cpp +++ b/src/private/mx/core/generated/VirtualInstrumentDataGroup.cpp @@ -41,11 +41,6 @@ void VirtualInstrumentDataGroup::setVirtualInstrument(std::optional, std::move(value)}}; } -VirtualInstrumentDataGroupChoice parseVirtualInstrumentDataGroupChoice(pugi::xml_node el, pugi::xml_node &cursor) -{ - return parseVirtualInstrumentDataGroupChoice(el, cursor, ParseContext{}); -} - VirtualInstrumentDataGroupChoice parseVirtualInstrumentDataGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context) { diff --git a/src/private/mx/core/generated/VirtualInstrumentDataGroupChoice.h b/src/private/mx/core/generated/VirtualInstrumentDataGroupChoice.h index d850346b5..0d1b4fae2 100644 --- a/src/private/mx/core/generated/VirtualInstrumentDataGroupChoice.h +++ b/src/private/mx/core/generated/VirtualInstrumentDataGroupChoice.h @@ -82,8 +82,6 @@ class VirtualInstrumentDataGroupChoice final /// Consumes one alternative starting at `cursor` (which advances); `el` is /// the enclosing element, for error paths. -VirtualInstrumentDataGroupChoice parseVirtualInstrumentDataGroupChoice(pugi::xml_node el, pugi::xml_node &cursor); - VirtualInstrumentDataGroupChoice parseVirtualInstrumentDataGroupChoice(pugi::xml_node el, pugi::xml_node &cursor, const ParseContext &context); diff --git a/src/private/mx/core/generated/Wait.cpp b/src/private/mx/core/generated/Wait.cpp index 019ef7f80..ef74b34a3 100644 --- a/src/private/mx/core/generated/Wait.cpp +++ b/src/private/mx/core/generated/Wait.cpp @@ -31,11 +31,6 @@ void Wait::setTimeOnly(std::optional value) m_timeOnly = std::move(value); } -Wait parseWait(pugi::xml_node el) -{ - return parseWait(el, ParseContext{}); -} - Wait parseWait(pugi::xml_node el, const ParseContext &context) { Wait out; @@ -63,11 +58,6 @@ Wait parseWait(pugi::xml_node el, const ParseContext &context) return out; } -void parseWaitContent(Wait &out, pugi::xml_node el) -{ - parseWaitContent(out, el, ParseContext{}); -} - void parseWaitContent(Wait &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/Wait.h b/src/private/mx/core/generated/Wait.h index fbe6ca33a..73e2d8ecb 100644 --- a/src/private/mx/core/generated/Wait.h +++ b/src/private/mx/core/generated/Wait.h @@ -38,12 +38,8 @@ class Wait final std::optional m_timeOnly; }; -Wait parseWait(pugi::xml_node el); - Wait parseWait(pugi::xml_node el, const ParseContext &context); -void parseWaitContent(Wait &out, pugi::xml_node el); - void parseWaitContent(Wait &out, pugi::xml_node el, const ParseContext &context); void serializeWait(const Wait &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/WavyLine.cpp b/src/private/mx/core/generated/WavyLine.cpp index ecc9fcdb9..5a026d2af 100644 --- a/src/private/mx/core/generated/WavyLine.cpp +++ b/src/private/mx/core/generated/WavyLine.cpp @@ -171,11 +171,6 @@ void WavyLine::setLastBeat(std::optional value) m_lastBeat = std::move(value); } -WavyLine parseWavyLine(pugi::xml_node el) -{ - return parseWavyLine(el, ParseContext{}); -} - WavyLine parseWavyLine(pugi::xml_node el, const ParseContext &context) { WavyLine out; @@ -265,11 +260,6 @@ WavyLine parseWavyLine(pugi::xml_node el, const ParseContext &context) return out; } -void parseWavyLineContent(WavyLine &out, pugi::xml_node el) -{ - parseWavyLineContent(out, el, ParseContext{}); -} - void parseWavyLineContent(WavyLine &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/WavyLine.h b/src/private/mx/core/generated/WavyLine.h index 55161bc55..0a90226a7 100644 --- a/src/private/mx/core/generated/WavyLine.h +++ b/src/private/mx/core/generated/WavyLine.h @@ -87,12 +87,8 @@ class WavyLine final std::optional m_lastBeat; }; -WavyLine parseWavyLine(pugi::xml_node el); - WavyLine parseWavyLine(pugi::xml_node el, const ParseContext &context); -void parseWavyLineContent(WavyLine &out, pugi::xml_node el); - void parseWavyLineContent(WavyLine &out, pugi::xml_node el, const ParseContext &context); void serializeWavyLine(const WavyLine &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Wedge.cpp b/src/private/mx/core/generated/Wedge.cpp index 01915f407..7d99913c8 100644 --- a/src/private/mx/core/generated/Wedge.cpp +++ b/src/private/mx/core/generated/Wedge.cpp @@ -141,11 +141,6 @@ void Wedge::setID(std::optional value) m_id = std::move(value); } -Wedge parseWedge(pugi::xml_node el) -{ - return parseWedge(el, ParseContext{}); -} - Wedge parseWedge(pugi::xml_node el, const ParseContext &context) { Wedge out; @@ -223,11 +218,6 @@ Wedge parseWedge(pugi::xml_node el, const ParseContext &context) return out; } -void parseWedgeContent(Wedge &out, pugi::xml_node el) -{ - parseWedgeContent(out, el, ParseContext{}); -} - void parseWedgeContent(Wedge &out, pugi::xml_node el, const ParseContext &context) { (void)out; diff --git a/src/private/mx/core/generated/Wedge.h b/src/private/mx/core/generated/Wedge.h index 666939f3a..359b16385 100644 --- a/src/private/mx/core/generated/Wedge.h +++ b/src/private/mx/core/generated/Wedge.h @@ -78,12 +78,8 @@ class Wedge final std::optional m_id; }; -Wedge parseWedge(pugi::xml_node el); - Wedge parseWedge(pugi::xml_node el, const ParseContext &context); -void parseWedgeContent(Wedge &out, pugi::xml_node el); - void parseWedgeContent(Wedge &out, pugi::xml_node el, const ParseContext &context); void serializeWedge(const Wedge &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Wood.cpp b/src/private/mx/core/generated/Wood.cpp index 0b5e761d5..7382168f3 100644 --- a/src/private/mx/core/generated/Wood.cpp +++ b/src/private/mx/core/generated/Wood.cpp @@ -31,11 +31,6 @@ void Wood::setValue(WoodValue value) m_value = std::move(value); } -Wood parseWood(pugi::xml_node el) -{ - return parseWood(el, ParseContext{}); -} - Wood parseWood(pugi::xml_node el, const ParseContext &context) { Wood out; @@ -59,11 +54,6 @@ Wood parseWood(pugi::xml_node el, const ParseContext &context) return out; } -void parseWoodContent(Wood &out, pugi::xml_node el) -{ - parseWoodContent(out, el, ParseContext{}); -} - void parseWoodContent(Wood &out, pugi::xml_node el, const ParseContext &context) { out.setValue(parseValue(childText(el), context, el, nullptr)); diff --git a/src/private/mx/core/generated/Wood.h b/src/private/mx/core/generated/Wood.h index eea30a88c..1c054b584 100644 --- a/src/private/mx/core/generated/Wood.h +++ b/src/private/mx/core/generated/Wood.h @@ -34,12 +34,8 @@ class Wood final WoodValue m_value{}; }; -Wood parseWood(pugi::xml_node el); - Wood parseWood(pugi::xml_node el, const ParseContext &context); -void parseWoodContent(Wood &out, pugi::xml_node el); - void parseWoodContent(Wood &out, pugi::xml_node el, const ParseContext &context); void serializeWood(const Wood &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mx/core/generated/Work.cpp b/src/private/mx/core/generated/Work.cpp index 4a2db105c..64de16afd 100644 --- a/src/private/mx/core/generated/Work.cpp +++ b/src/private/mx/core/generated/Work.cpp @@ -41,11 +41,6 @@ void Work::setOpus(std::optional value) m_opus = std::move(value); } -Work parseWork(pugi::xml_node el) -{ - return parseWork(el, ParseContext{}); -} - Work parseWork(pugi::xml_node el, const ParseContext &context) { Work out; @@ -62,11 +57,6 @@ Work parseWork(pugi::xml_node el, const ParseContext &context) return out; } -void parseWorkContent(Work &out, pugi::xml_node el) -{ - parseWorkContent(out, el, ParseContext{}); -} - void parseWorkContent(Work &out, pugi::xml_node el, const ParseContext &context) { pugi::xml_node cursor = firstElement(el); diff --git a/src/private/mx/core/generated/Work.h b/src/private/mx/core/generated/Work.h index 6d6100e2a..39990cc46 100644 --- a/src/private/mx/core/generated/Work.h +++ b/src/private/mx/core/generated/Work.h @@ -40,12 +40,8 @@ class Work final std::optional m_opus; }; -Work parseWork(pugi::xml_node el); - Work parseWork(pugi::xml_node el, const ParseContext &context); -void parseWorkContent(Work &out, pugi::xml_node el); - void parseWorkContent(Work &out, pugi::xml_node el, const ParseContext &context); void serializeWork(const Work &v, pugi::xml_node parent, const char *tag); diff --git a/src/private/mxtest/core/AttributionTest.cpp b/src/private/mxtest/core/AttributionTest.cpp index 311596965..2f35547ea 100644 --- a/src/private/mxtest/core/AttributionTest.cpp +++ b/src/private/mxtest/core/AttributionTest.cpp @@ -9,6 +9,7 @@ #include "cpul/cpulTestHarness.h" #include "mx/core/Attribution.h" +#include "mx/core/ParseContext.h" #include "mx/core/Version.h" #include "mx/core/generated/Document.h" #include "mx/core/generated/Encoding.h" @@ -102,7 +103,7 @@ TEST(DoesNotAccumulateAcrossRoundTrips, Attribution) serializeWithAttribution(doc, first); // Parsing mx's own output, then re-writing, must still yield one stamp. - const auto reparsed = parse(first); + const auto reparsed = parse(first, ParseContext{}); CHECK(reparsed.ok()); if (reparsed.ok()) { diff --git a/src/private/mxtest/core/DocumentTest.cpp b/src/private/mxtest/core/DocumentTest.cpp index e2ad55b1f..b21da66e8 100644 --- a/src/private/mxtest/core/DocumentTest.cpp +++ b/src/private/mxtest/core/DocumentTest.cpp @@ -11,6 +11,7 @@ #include "mx/core/Error.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/generated/DefaultsProbe.h" #include "mx/core/generated/Document.h" #include "mx/core/generated/Version.h" @@ -28,7 +29,7 @@ Error parseExpectingError(const char *xml) { pugi::xml_document doc; CHECK(doc.load_string(xml)); - auto result = parse(doc); + auto result = parse(doc, ParseContext{}); CHECK(!result.ok()); if (result.ok()) { @@ -113,7 +114,7 @@ TEST(RejectsNewerVersion, Document) { pugi::xml_document doc; CHECK(doc.load_string("")); - auto result = parse(doc); + auto result = parse(doc, ParseContext{}); CHECK(!result.ok()); CHECK(result.error().code == ErrorCode::unsupportedVersion); } @@ -137,12 +138,12 @@ TEST(RoundTripMinimalScore, Document) { pugi::xml_document doc; CHECK(doc.load_string(kMinimalScore)); - auto parsed = parse(doc); + auto parsed = parse(doc, ParseContext{}); CHECK(parsed.ok()); CHECK(parsed.value().isScorePartwise()); pugi::xml_document out; serialize(parsed.value(), out); - auto reparsed = parse(out); + auto reparsed = parse(out, ParseContext{}); CHECK(reparsed.ok()); CHECK(parsed.value() == reparsed.value()); } @@ -153,7 +154,7 @@ TEST(RootNamespacePreserved, Document) CHECK(doc.load_string("" "M" "")); - auto parsed = parse(doc); + auto parsed = parse(doc, ParseContext{}); CHECK(parsed.ok()); CHECK_EQUAL(std::size_t{1}, parsed.value().rootNamespaces().size()); pugi::xml_document out; diff --git a/src/private/mxtest/core/ImportDiagnosticsTest.cpp b/src/private/mxtest/core/ImportDiagnosticsTest.cpp index fc777b022..57d939a55 100644 --- a/src/private/mxtest/core/ImportDiagnosticsTest.cpp +++ b/src/private/mxtest/core/ImportDiagnosticsTest.cpp @@ -144,10 +144,11 @@ TEST(SilentParseProducesTheSameDocument, ImportDiagnostics) "1"); const auto reported = importDiagnosticsParse(xml); REQUIRE(reported.ok); + CHECK(!reported.diagnostics.empty()); pugi::xml_document doc; REQUIRE(doc.load_string(xml.c_str())); - const auto silent = parse(doc); + const auto silent = parse(doc, ParseContext{}); REQUIRE(silent.ok()); CHECK(silent.value() == reported.document); } diff --git a/src/private/mxtest/core/ShapeTest.cpp b/src/private/mxtest/core/ShapeTest.cpp index bdfd72543..c622fc7c1 100644 --- a/src/private/mxtest/core/ShapeTest.cpp +++ b/src/private/mxtest/core/ShapeTest.cpp @@ -12,6 +12,7 @@ #include "mx/core/Error.h" #include "mx/core/OneOrMore.h" +#include "mx/core/ParseContext.h" #include "mx/core/Xml.h" #include "mx/core/generated/Beam.h" #include "mx/core/generated/BeamValue.h" @@ -60,7 +61,7 @@ ErrorCode parsePitchExpectingError(const char *xml) CHECK(doc.load_string(xml)); try { - parsePitch(doc.first_child()); + parsePitch(doc.first_child(), ParseContext{}); } catch (const ParseError &e) { @@ -193,7 +194,7 @@ TEST(StrictStructureParse, Shapes) // A round trip of valid input parses cleanly (values lenient). pugi::xml_document doc; CHECK(doc.load_string("G-111")); - const Pitch p = parsePitch(doc.first_child()); + const Pitch p = parsePitch(doc.first_child(), ParseContext{}); CHECK(p.step() == Step::g()); CHECK_EQUAL(9, p.octave().value()); // out-of-range value clamps } diff --git a/src/private/mxtest/corert/CoreRoundtripImpl.cpp b/src/private/mxtest/corert/CoreRoundtripImpl.cpp index 8290b9751..4b701fc7a 100644 --- a/src/private/mxtest/corert/CoreRoundtripImpl.cpp +++ b/src/private/mxtest/corert/CoreRoundtripImpl.cpp @@ -5,6 +5,7 @@ #include "mxtest/corert/CoreRoundtripImpl.h" #include "mx/core/Lexical.h" +#include "mx/core/ParseContext.h" #include "mx/core/generated/Document.h" #include "mx/core/generated/Version.h" #include "mxtest/corert/Compare.h" @@ -188,7 +189,7 @@ CoreRoundtripResult runCoreRoundtrip(const std::string &absoluteInputPath) // 3. Pin the root version to the harness baseline, then parse. setRootMusicXmlVersion(inputDoc, kMusicXmlVersionBaseline); - auto parsed = mx::core::parse(inputDoc); + auto parsed = mx::core::parse(inputDoc, mx::core::ParseContext{}); if (!parsed) { r.message = "parse failed [" + parsed.error().path + "] " + parsed.error().message; From 00759e5669b3bc41f3868509b9bbb8683c580b5c Mon Sep 17 00:00:00 2001 From: Matthew James Briggs Date: Thu, 17 Sep 2026 15:53:47 +0200 Subject: [PATCH 3/8] feat: report Token and NameToken repairs Name-token attributes now go through the reporting helper. A repaired xs:ID also warns that it may duplicate another ID in the document, since the repair can merge distinct IDs. Surrounding whitespace is a valid spelling and is not reported. Mark the unique ID exception with TODOs at getCoreDocument() and beside the claims that invalid MusicXML is unrepresentable. --- README.md | 1 + docs/ai/design/mx-core-plan.md | 1 + gen/cpp/templates/attr_parse_expr.tmpl | 2 +- gen/cpp/templates/document.h.tmpl | 1 + gen/plates/build.py | 1 + gen/plates/model.py | 3 ++ src/include/mx/api/Id.h | 1 + src/include/mx/api/MusicXml.h | 2 + src/private/mx/core/NameToken.cpp | 7 ++++ src/private/mx/core/NameToken.h | 6 +++ src/private/mx/core/ParseContext.cpp | 27 ++++++++++++-- src/private/mx/core/ParseContext.h | 18 +++++++++ src/private/mx/core/Token.cpp | 7 ++++ src/private/mx/core/Token.h | 6 +++ .../mx/core/generated/AccidentalMark.cpp | 2 +- .../core/generated/AccordionRegistration.cpp | 2 +- src/private/mx/core/generated/Arpeggiate.cpp | 2 +- .../mx/core/generated/Articulations.cpp | 2 +- src/private/mx/core/generated/Assess.cpp | 2 +- src/private/mx/core/generated/Barline.cpp | 2 +- src/private/mx/core/generated/Beam.cpp | 2 +- src/private/mx/core/generated/Bookmark.cpp | 4 +- src/private/mx/core/generated/Bracket.cpp | 2 +- src/private/mx/core/generated/Clef.cpp | 2 +- src/private/mx/core/generated/Coda.cpp | 2 +- src/private/mx/core/generated/Credit.cpp | 2 +- src/private/mx/core/generated/Dashes.cpp | 2 +- src/private/mx/core/generated/Direction.cpp | 2 +- .../mx/core/generated/DirectionType.cpp | 2 +- src/private/mx/core/generated/Document.h | 1 + src/private/mx/core/generated/Dynamics.cpp | 2 +- .../core/generated/EmptyPrintStyleAlignID.cpp | 2 +- src/private/mx/core/generated/Fermata.cpp | 2 +- src/private/mx/core/generated/FiguredBass.cpp | 2 +- src/private/mx/core/generated/ForPart.cpp | 2 +- .../mx/core/generated/FormattedSymbolID.cpp | 2 +- .../mx/core/generated/FormattedTextID.cpp | 2 +- src/private/mx/core/generated/Frame.cpp | 2 +- src/private/mx/core/generated/Glissando.cpp | 2 +- src/private/mx/core/generated/Grouping.cpp | 2 +- src/private/mx/core/generated/Harmony.cpp | 2 +- src/private/mx/core/generated/HarpPedals.cpp | 2 +- src/private/mx/core/generated/Image.cpp | 2 +- src/private/mx/core/generated/Instrument.cpp | 2 +- .../mx/core/generated/InstrumentChange.cpp | 2 +- .../mx/core/generated/InstrumentLink.cpp | 2 +- src/private/mx/core/generated/Key.cpp | 2 +- src/private/mx/core/generated/Link.cpp | 2 +- src/private/mx/core/generated/Lyric.cpp | 4 +- src/private/mx/core/generated/LyricFont.cpp | 2 +- .../mx/core/generated/LyricLanguage.cpp | 2 +- src/private/mx/core/generated/MIDIDevice.cpp | 2 +- .../mx/core/generated/MIDIInstrument.cpp | 2 +- .../mx/core/generated/MeasureStyle.cpp | 2 +- src/private/mx/core/generated/Metronome.cpp | 2 +- .../mx/core/generated/NonArpeggiate.cpp | 2 +- src/private/mx/core/generated/Notations.cpp | 2 +- src/private/mx/core/generated/Note.cpp | 2 +- src/private/mx/core/generated/OctaveShift.cpp | 2 +- src/private/mx/core/generated/Ornaments.cpp | 2 +- .../mx/core/generated/OtherDirection.cpp | 2 +- .../mx/core/generated/OtherListening.cpp | 2 +- .../mx/core/generated/OtherNotation.cpp | 2 +- .../mx/core/generated/PartwiseMeasure.cpp | 2 +- .../mx/core/generated/PartwisePart.cpp | 2 +- src/private/mx/core/generated/Pedal.cpp | 2 +- src/private/mx/core/generated/Percussion.cpp | 2 +- src/private/mx/core/generated/Play.cpp | 2 +- src/private/mx/core/generated/Player.cpp | 2 +- .../mx/core/generated/PrincipalVoice.cpp | 2 +- src/private/mx/core/generated/Print.cpp | 2 +- src/private/mx/core/generated/Scordatura.cpp | 2 +- .../mx/core/generated/ScoreInstrument.cpp | 2 +- src/private/mx/core/generated/ScorePart.cpp | 2 +- src/private/mx/core/generated/Segno.cpp | 2 +- src/private/mx/core/generated/Slide.cpp | 2 +- src/private/mx/core/generated/Slur.cpp | 2 +- src/private/mx/core/generated/Sound.cpp | 2 +- src/private/mx/core/generated/StaffDivide.cpp | 2 +- src/private/mx/core/generated/StringMute.cpp | 2 +- src/private/mx/core/generated/Supports.cpp | 4 +- src/private/mx/core/generated/Sync.cpp | 2 +- src/private/mx/core/generated/Technical.cpp | 2 +- src/private/mx/core/generated/Tied.cpp | 2 +- src/private/mx/core/generated/Time.cpp | 2 +- .../mx/core/generated/TimewiseMeasure.cpp | 2 +- .../mx/core/generated/TimewisePart.cpp | 2 +- src/private/mx/core/generated/Transpose.cpp | 2 +- src/private/mx/core/generated/Tuplet.cpp | 2 +- src/private/mx/core/generated/Wait.cpp | 2 +- src/private/mx/core/generated/Wedge.cpp | 2 +- .../mxtest/core/ImportDiagnosticsTest.cpp | 37 +++++++++++++++++-- src/private/mxtest/core/ValueTest.cpp | 10 +++++ 93 files changed, 202 insertions(+), 87 deletions(-) diff --git a/README.md b/README.md index 73eaea4aa..26f870772 100644 --- a/README.md +++ b/README.md @@ -489,6 +489,7 @@ attributes. `mx::core` is generated from the MusicXML 4.0 XSD by the generator i hand-written runtime lives in `src/private/mx/core/`, the generated model in `src/private/mx/core/generated/` -- the directory is the generated/hand-written boundary). + The generated model is valid-by-construction: enum wrappers whose named factories are the only constructors, clamp-on-construct number wrappers, composites with named fields in schema order (the serializer walks declaration order, so wrong element order is unrepresentable), diff --git a/docs/ai/design/mx-core-plan.md b/docs/ai/design/mx-core-plan.md index 37e11216c..3d04e9271 100644 --- a/docs/ai/design/mx-core-plan.md +++ b/docs/ai/design/mx-core-plan.md @@ -19,6 +19,7 @@ named groups onto the Plates is *neutral schema fact* work that serves all targe ## 1. The non-negotiables (owner's cardinal requirements) + 1. **Valid by construction.** It must be impossible to use the public C++ API to produce a document that is invalid against the MusicXML 4.0 spec. Invalid states are made *unrepresentable* by the type system wherever possible โ€” including bespoke structural diff --git a/gen/cpp/templates/attr_parse_expr.tmpl b/gen/cpp/templates/attr_parse_expr.tmpl index c9159ef2d..30eb47782 100644 --- a/gen/cpp/templates/attr_parse_expr.tmpl +++ b/gen/cpp/templates/attr_parse_expr.tmpl @@ -1 +1 @@ -{{#type_ref.is_value}}parseValue<{{type_ref.ident}}>(a.value(), context, el, {{name.wire_q}}){{/type_ref.is_value}}{{#type_ref.name_token}}{{type_ref.ident}}::parse(a.value()){{/type_ref.name_token}}{{#type_ref.is_primitive_string}}{{^type_ref.name_token}}std::string{a.value()}{{/type_ref.name_token}}{{/type_ref.is_primitive_string}}{{#type_ref.is_primitive_integer}}parseIntegerValue(a.value(), context, el, {{name.wire_q}}){{/type_ref.is_primitive_integer}}{{#type_ref.is_primitive_decimal}}parseDecimalValue(a.value(), context, el, {{name.wire_q}}){{/type_ref.is_primitive_decimal}} \ No newline at end of file +{{#type_ref.is_value}}parseValue<{{type_ref.ident}}>(a.value(), context, el, {{name.wire_q}}){{/type_ref.is_value}}{{#type_ref.name_token}}{{#type_ref.unique_id}}parseIdValue<{{type_ref.ident}}>(a.value(), context, el, {{name.wire_q}}){{/type_ref.unique_id}}{{^type_ref.unique_id}}parseValue<{{type_ref.ident}}>(a.value(), context, el, {{name.wire_q}}){{/type_ref.unique_id}}{{/type_ref.name_token}}{{#type_ref.is_primitive_string}}{{^type_ref.name_token}}std::string{a.value()}{{/type_ref.name_token}}{{/type_ref.is_primitive_string}}{{#type_ref.is_primitive_integer}}parseIntegerValue(a.value(), context, el, {{name.wire_q}}){{/type_ref.is_primitive_integer}}{{#type_ref.is_primitive_decimal}}parseDecimalValue(a.value(), context, el, {{name.wire_q}}){{/type_ref.is_primitive_decimal}} \ No newline at end of file diff --git a/gen/cpp/templates/document.h.tmpl b/gen/cpp/templates/document.h.tmpl index fccdb48bf..b39762264 100644 --- a/gen/cpp/templates/document.h.tmpl +++ b/gen/cpp/templates/document.h.tmpl @@ -94,6 +94,7 @@ private: /// SupportedMusicXMLVersion is rejected with unsupportedVersion. Result parse(const pugi::xml_document &doc, const ParseContext &context); +// TODO: document the unique ID exception /// Total for every Document (ยง1.1 guarantees validity): writes the XML /// declaration, the matching DOCTYPE, the preserved root namespace /// declarations, and the typed tree. diff --git a/gen/plates/build.py b/gen/plates/build.py index d32b5f236..c07dbeb4f 100644 --- a/gen/plates/build.py +++ b/gen/plates/build.py @@ -512,6 +512,7 @@ def _plate_ref(self, ref: ir.Ref) -> PlateRef: if ref.name in _PRIM_NUMERIC else "primitive-string", name_token=ref.name in _PRIM_NAME_TOKEN, + unique_id=ref.name == "id", ) if ref.category == "value": kind = self.values_by_name[ref.name].kind diff --git a/gen/plates/model.py b/gen/plates/model.py index dff1c57f6..838668ce4 100644 --- a/gen/plates/model.py +++ b/gen/plates/model.py @@ -59,6 +59,9 @@ class PlateRef: # lexically narrower than a free string. A validating target renders a # repairing wrapper for it; others ignore the flag. Neutral schema fact. name_token: bool = False + # True when the referent is the xs:ID primitive, whose value must be unique + # within the document. Neutral schema fact. + unique_id: bool = False @dataclass diff --git a/src/include/mx/api/Id.h b/src/include/mx/api/Id.h index 3640e0520..c62124b02 100644 --- a/src/include/mx/api/Id.h +++ b/src/include/mx/api/Id.h @@ -16,6 +16,7 @@ namespace mx namespace api { +// TODO: document the unique ID exception // The id attribute of a MusicXML element. An id is a name that identifies one element within the // document. Software uses it to point at a particular note, measure, or marking -- to line playback // up with the score, to hang an annotation on a note, or to link one file to another. diff --git a/src/include/mx/api/MusicXml.h b/src/include/mx/api/MusicXml.h index a3c9c7b68..0a3eeab1b 100644 --- a/src/include/mx/api/MusicXml.h +++ b/src/include/mx/api/MusicXml.h @@ -58,6 +58,8 @@ class MusicXml // Writes the document to a character stream. Result writeToStream(std::ostream &stream) const; + // TODO: document ID validity loophole + // // This is an escape hatch in case mx::api does not do what you need and // you want to edit the core DOM directly. You will need to include the // private mx::core headers in your header search paths to do so. Not diff --git a/src/private/mx/core/NameToken.cpp b/src/private/mx/core/NameToken.cpp index bc7156e68..b581fa716 100644 --- a/src/private/mx/core/NameToken.cpp +++ b/src/private/mx/core/NameToken.cpp @@ -71,4 +71,11 @@ NameToken NameToken::parse(std::string_view text) return NameToken{std::string{text}}; } +NameToken NameToken::parse(std::string_view text, ValueParseOutcome &outcome) +{ + NameToken strict; + outcome = tryParse(trimWhitespace(text), strict) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; + return parse(text); +} + } // namespace mx::core diff --git a/src/private/mx/core/NameToken.h b/src/private/mx/core/NameToken.h index 678f91ccc..1536693a7 100644 --- a/src/private/mx/core/NameToken.h +++ b/src/private/mx/core/NameToken.h @@ -6,6 +6,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -42,6 +44,10 @@ class NameToken final /// Lenient: repairs into the nearest valid token. static NameToken parse(std::string_view text); + /// Lenient, and says whether the text had to be repaired. Surrounding + /// XML whitespace is not a repair. + static NameToken parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const NameToken &other) const noexcept = default; private: diff --git a/src/private/mx/core/ParseContext.cpp b/src/private/mx/core/ParseContext.cpp index 54b715125..f1705668a 100644 --- a/src/private/mx/core/ParseContext.cpp +++ b/src/private/mx/core/ParseContext.cpp @@ -23,8 +23,11 @@ void ParseContext::report(Diagnostic diagnostic) const } } -void reportValueRepair(const ParseContext &context, ValueParseOutcome outcome, pugi::xml_node el, const char *attribute, - std::string_view text, std::string_view replacement) +namespace +{ + +Diagnostic valueRepairDiagnostic(ValueParseOutcome outcome, pugi::xml_node el, const char *attribute, + std::string_view text, std::string_view replacement) { const bool invalid = outcome == ValueParseOutcome::invalid; std::string message = invalid ? "invalid value \"" : "value \""; @@ -39,8 +42,24 @@ void reportValueRepair(const ParseContext &context, ValueParseOutcome outcome, p message += invalid ? "; using \"" : " adjusted to \""; message += replacement; message += "\""; - context.report(Diagnostic{invalid ? DiagnosticCode::invalidValue : DiagnosticCode::valueAdjusted, nodePath(el), - std::move(message)}); + return Diagnostic{invalid ? DiagnosticCode::invalidValue : DiagnosticCode::valueAdjusted, nodePath(el), + std::move(message)}; +} + +} // namespace + +void reportValueRepair(const ParseContext &context, ValueParseOutcome outcome, pugi::xml_node el, const char *attribute, + std::string_view text, std::string_view replacement) +{ + context.report(valueRepairDiagnostic(outcome, el, attribute, text, replacement)); +} + +void reportIdRepair(const ParseContext &context, ValueParseOutcome outcome, pugi::xml_node el, const char *attribute, + std::string_view text, std::string_view replacement) +{ + Diagnostic diagnostic = valueRepairDiagnostic(outcome, el, attribute, text, replacement); + diagnostic.message += "; the repaired ID may duplicate another ID in the document"; + context.report(std::move(diagnostic)); } void reportAttributeDefaulted(const ParseContext &context, pugi::xml_node el, const char *attribute, diff --git a/src/private/mx/core/ParseContext.h b/src/private/mx/core/ParseContext.h index 499f52bf2..d36dc8e8a 100644 --- a/src/private/mx/core/ParseContext.h +++ b/src/private/mx/core/ParseContext.h @@ -55,6 +55,11 @@ class ParseContext void reportValueRepair(const ParseContext &context, ValueParseOutcome outcome, pugi::xml_node el, const char *attribute, std::string_view text, std::string_view replacement); +/// Reports a repaired xs:ID attribute, warning that the repair may have made +/// it the same as another ID in the document. +void reportIdRepair(const ParseContext &context, ValueParseOutcome outcome, pugi::xml_node el, const char *attribute, + std::string_view text, std::string_view replacement); + void reportAttributeDefaulted(const ParseContext &context, pugi::xml_node el, const char *attribute, std::string_view value); @@ -79,6 +84,19 @@ T parseValue(std::string_view text, const ParseContext &context, pugi::xml_node } } +/// The lenient parse of an xs:ID attribute, reporting any repair it made. +template +T parseIdValue(std::string_view text, const ParseContext &context, pugi::xml_node el, const char *attribute) +{ + ValueParseOutcome outcome = ValueParseOutcome::valid; + T value = T::parse(text, outcome); + if (outcome != ValueParseOutcome::valid) + { + reportIdRepair(context, outcome, el, attribute, text, std::string{value.toString()}); + } + return value; +} + int parseIntegerValue(std::string_view text, const ParseContext &context, pugi::xml_node el, const char *attribute); Decimal parseDecimalValue(std::string_view text, const ParseContext &context, pugi::xml_node el, const char *attribute); diff --git a/src/private/mx/core/Token.cpp b/src/private/mx/core/Token.cpp index 641ffb32e..651c5842c 100644 --- a/src/private/mx/core/Token.cpp +++ b/src/private/mx/core/Token.cpp @@ -85,4 +85,11 @@ Token Token::parse(std::string_view text) return Token{std::string{text}}; } +Token Token::parse(std::string_view text, ValueParseOutcome &outcome) +{ + Token strict; + outcome = tryParse(trimWhitespace(text), strict) ? ValueParseOutcome::valid : ValueParseOutcome::invalid; + return parse(text); +} + } // namespace mx::core diff --git a/src/private/mx/core/Token.h b/src/private/mx/core/Token.h index 3cd78db3c..8dcfe5771 100644 --- a/src/private/mx/core/Token.h +++ b/src/private/mx/core/Token.h @@ -6,6 +6,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -43,6 +45,10 @@ class Token final /// Lenient: repairs into the nearest valid NCName. static Token parse(std::string_view text); + /// Lenient, and says whether the text had to be repaired. Surrounding + /// XML whitespace is not a repair. + static Token parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const Token &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/AccidentalMark.cpp b/src/private/mx/core/generated/AccidentalMark.cpp index 8fdc2bde4..93f5aa9d4 100644 --- a/src/private/mx/core/generated/AccidentalMark.cpp +++ b/src/private/mx/core/generated/AccidentalMark.cpp @@ -239,7 +239,7 @@ AccidentalMark parseAccidentalMark(pugi::xml_node el, const ParseContext &contex } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/AccordionRegistration.cpp b/src/private/mx/core/generated/AccordionRegistration.cpp index a7af034be..c1396f048 100644 --- a/src/private/mx/core/generated/AccordionRegistration.cpp +++ b/src/private/mx/core/generated/AccordionRegistration.cpp @@ -217,7 +217,7 @@ AccordionRegistration parseAccordionRegistration(pugi::xml_node el, const ParseC } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Arpeggiate.cpp b/src/private/mx/core/generated/Arpeggiate.cpp index b4c7c8bfe..0a0a82260 100644 --- a/src/private/mx/core/generated/Arpeggiate.cpp +++ b/src/private/mx/core/generated/Arpeggiate.cpp @@ -159,7 +159,7 @@ Arpeggiate parseArpeggiate(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Articulations.cpp b/src/private/mx/core/generated/Articulations.cpp index 7ad7b72f2..3684e12fe 100644 --- a/src/private/mx/core/generated/Articulations.cpp +++ b/src/private/mx/core/generated/Articulations.cpp @@ -48,7 +48,7 @@ Articulations parseArticulations(pugi::xml_node el, const ParseContext &context) } if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Assess.cpp b/src/private/mx/core/generated/Assess.cpp index c88eef864..0610d696a 100644 --- a/src/private/mx/core/generated/Assess.cpp +++ b/src/private/mx/core/generated/Assess.cpp @@ -59,7 +59,7 @@ Assess parseAssess(pugi::xml_node el, const ParseContext &context) } else if (aname == "player") { - out.setPlayer(Token::parse(a.value())); + out.setPlayer(parseValue(a.value(), context, el, "player")); } else if (aname == "time-only") { diff --git a/src/private/mx/core/generated/Barline.cpp b/src/private/mx/core/generated/Barline.cpp index 077373d8f..288d6b741 100644 --- a/src/private/mx/core/generated/Barline.cpp +++ b/src/private/mx/core/generated/Barline.cpp @@ -179,7 +179,7 @@ Barline parseBarline(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Beam.cpp b/src/private/mx/core/generated/Beam.cpp index d7c23c2b2..12237e9bf 100644 --- a/src/private/mx/core/generated/Beam.cpp +++ b/src/private/mx/core/generated/Beam.cpp @@ -99,7 +99,7 @@ Beam parseBeam(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Bookmark.cpp b/src/private/mx/core/generated/Bookmark.cpp index 25c00a834..641da9db6 100644 --- a/src/private/mx/core/generated/Bookmark.cpp +++ b/src/private/mx/core/generated/Bookmark.cpp @@ -65,7 +65,7 @@ Bookmark parseBookmark(pugi::xml_node el, const ParseContext &context) if (aname == "id") { seen_id = true; - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else if (aname == "name") { @@ -73,7 +73,7 @@ Bookmark parseBookmark(pugi::xml_node el, const ParseContext &context) } else if (aname == "element") { - out.setElement(NameToken::parse(a.value())); + out.setElement(parseValue(a.value(), context, el, "element")); } else if (aname == "position") { diff --git a/src/private/mx/core/generated/Bracket.cpp b/src/private/mx/core/generated/Bracket.cpp index 72500550d..0172206d8 100644 --- a/src/private/mx/core/generated/Bracket.cpp +++ b/src/private/mx/core/generated/Bracket.cpp @@ -205,7 +205,7 @@ Bracket parseBracket(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Clef.cpp b/src/private/mx/core/generated/Clef.cpp index 96ba91716..1bc0c9b63 100644 --- a/src/private/mx/core/generated/Clef.cpp +++ b/src/private/mx/core/generated/Clef.cpp @@ -239,7 +239,7 @@ Clef parseClef(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Coda.cpp b/src/private/mx/core/generated/Coda.cpp index 428ede00c..836f971a2 100644 --- a/src/private/mx/core/generated/Coda.cpp +++ b/src/private/mx/core/generated/Coda.cpp @@ -201,7 +201,7 @@ Coda parseCoda(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Credit.cpp b/src/private/mx/core/generated/Credit.cpp index dff9671fe..993e5edcf 100644 --- a/src/private/mx/core/generated/Credit.cpp +++ b/src/private/mx/core/generated/Credit.cpp @@ -102,7 +102,7 @@ Credit parseCredit(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Dashes.cpp b/src/private/mx/core/generated/Dashes.cpp index 9bd3566ac..a3a973b9e 100644 --- a/src/private/mx/core/generated/Dashes.cpp +++ b/src/private/mx/core/generated/Dashes.cpp @@ -161,7 +161,7 @@ Dashes parseDashes(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Direction.cpp b/src/private/mx/core/generated/Direction.cpp index a3bcc7b3f..5f68b6714 100644 --- a/src/private/mx/core/generated/Direction.cpp +++ b/src/private/mx/core/generated/Direction.cpp @@ -140,7 +140,7 @@ Direction parseDirection(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/DirectionType.cpp b/src/private/mx/core/generated/DirectionType.cpp index 4e12e8d06..f40056e8f 100644 --- a/src/private/mx/core/generated/DirectionType.cpp +++ b/src/private/mx/core/generated/DirectionType.cpp @@ -43,7 +43,7 @@ DirectionType parseDirectionType(pugi::xml_node el, const ParseContext &context) } if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Document.h b/src/private/mx/core/generated/Document.h index 36a2bcb96..0ffa10891 100644 --- a/src/private/mx/core/generated/Document.h +++ b/src/private/mx/core/generated/Document.h @@ -105,6 +105,7 @@ class Document final /// SupportedMusicXMLVersion is rejected with unsupportedVersion. Result parse(const pugi::xml_document &doc, const ParseContext &context); +// TODO: document the unique ID exception /// Total for every Document (ยง1.1 guarantees validity): writes the XML /// declaration, the matching DOCTYPE, the preserved root namespace /// declarations, and the typed tree. diff --git a/src/private/mx/core/generated/Dynamics.cpp b/src/private/mx/core/generated/Dynamics.cpp index f3193e082..5d0ce9100 100644 --- a/src/private/mx/core/generated/Dynamics.cpp +++ b/src/private/mx/core/generated/Dynamics.cpp @@ -272,7 +272,7 @@ Dynamics parseDynamics(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/EmptyPrintStyleAlignID.cpp b/src/private/mx/core/generated/EmptyPrintStyleAlignID.cpp index 2720d13cd..e131f6f40 100644 --- a/src/private/mx/core/generated/EmptyPrintStyleAlignID.cpp +++ b/src/private/mx/core/generated/EmptyPrintStyleAlignID.cpp @@ -187,7 +187,7 @@ EmptyPrintStyleAlignID parseEmptyPrintStyleAlignID(pugi::xml_node el, const Pars } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Fermata.cpp b/src/private/mx/core/generated/Fermata.cpp index 014336d8f..f06f200ae 100644 --- a/src/private/mx/core/generated/Fermata.cpp +++ b/src/private/mx/core/generated/Fermata.cpp @@ -183,7 +183,7 @@ Fermata parseFermata(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/FiguredBass.cpp b/src/private/mx/core/generated/FiguredBass.cpp index 53557f047..e8b75e67b 100644 --- a/src/private/mx/core/generated/FiguredBass.cpp +++ b/src/private/mx/core/generated/FiguredBass.cpp @@ -306,7 +306,7 @@ FiguredBass parseFiguredBass(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/ForPart.cpp b/src/private/mx/core/generated/ForPart.cpp index 5748a109e..1afb91847 100644 --- a/src/private/mx/core/generated/ForPart.cpp +++ b/src/private/mx/core/generated/ForPart.cpp @@ -67,7 +67,7 @@ ForPart parseForPart(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/FormattedSymbolID.cpp b/src/private/mx/core/generated/FormattedSymbolID.cpp index ecc9a2d42..436b4e360 100644 --- a/src/private/mx/core/generated/FormattedSymbolID.cpp +++ b/src/private/mx/core/generated/FormattedSymbolID.cpp @@ -323,7 +323,7 @@ FormattedSymbolID parseFormattedSymbolID(pugi::xml_node el, const ParseContext & } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/FormattedTextID.cpp b/src/private/mx/core/generated/FormattedTextID.cpp index c6e2717af..e9427bc93 100644 --- a/src/private/mx/core/generated/FormattedTextID.cpp +++ b/src/private/mx/core/generated/FormattedTextID.cpp @@ -351,7 +351,7 @@ FormattedTextID parseFormattedTextID(pugi::xml_node el, const ParseContext &cont } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Frame.cpp b/src/private/mx/core/generated/Frame.cpp index 5b82c7662..c32059651 100644 --- a/src/private/mx/core/generated/Frame.cpp +++ b/src/private/mx/core/generated/Frame.cpp @@ -218,7 +218,7 @@ Frame parseFrame(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Glissando.cpp b/src/private/mx/core/generated/Glissando.cpp index c2c58eb1a..5ca7b4689 100644 --- a/src/private/mx/core/generated/Glissando.cpp +++ b/src/private/mx/core/generated/Glissando.cpp @@ -241,7 +241,7 @@ Glissando parseGlissando(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Grouping.cpp b/src/private/mx/core/generated/Grouping.cpp index ec3c463d5..3a76ecb02 100644 --- a/src/private/mx/core/generated/Grouping.cpp +++ b/src/private/mx/core/generated/Grouping.cpp @@ -92,7 +92,7 @@ Grouping parseGrouping(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Harmony.cpp b/src/private/mx/core/generated/Harmony.cpp index af4b9ad3f..742f64004 100644 --- a/src/private/mx/core/generated/Harmony.cpp +++ b/src/private/mx/core/generated/Harmony.cpp @@ -298,7 +298,7 @@ Harmony parseHarmony(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/HarpPedals.cpp b/src/private/mx/core/generated/HarpPedals.cpp index 22d6c8d39..0a7b910e0 100644 --- a/src/private/mx/core/generated/HarpPedals.cpp +++ b/src/private/mx/core/generated/HarpPedals.cpp @@ -202,7 +202,7 @@ HarpPedals parseHarpPedals(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Image.cpp b/src/private/mx/core/generated/Image.cpp index 1bfd99f57..2ba06f193 100644 --- a/src/private/mx/core/generated/Image.cpp +++ b/src/private/mx/core/generated/Image.cpp @@ -177,7 +177,7 @@ Image parseImage(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Instrument.cpp b/src/private/mx/core/generated/Instrument.cpp index dab2810e8..5628eeaf6 100644 --- a/src/private/mx/core/generated/Instrument.cpp +++ b/src/private/mx/core/generated/Instrument.cpp @@ -35,7 +35,7 @@ Instrument parseInstrument(pugi::xml_node el, const ParseContext &context) if (aname == "id") { seen_id = true; - out.setID(Token::parse(a.value())); + out.setID(parseValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/InstrumentChange.cpp b/src/private/mx/core/generated/InstrumentChange.cpp index c1d31768f..c61973bec 100644 --- a/src/private/mx/core/generated/InstrumentChange.cpp +++ b/src/private/mx/core/generated/InstrumentChange.cpp @@ -45,7 +45,7 @@ InstrumentChange parseInstrumentChange(pugi::xml_node el, const ParseContext &co if (aname == "id") { seen_id = true; - out.setID(Token::parse(a.value())); + out.setID(parseValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/InstrumentLink.cpp b/src/private/mx/core/generated/InstrumentLink.cpp index 27c22f038..37351c2a1 100644 --- a/src/private/mx/core/generated/InstrumentLink.cpp +++ b/src/private/mx/core/generated/InstrumentLink.cpp @@ -35,7 +35,7 @@ InstrumentLink parseInstrumentLink(pugi::xml_node el, const ParseContext &contex if (aname == "id") { seen_id = true; - out.setID(Token::parse(a.value())); + out.setID(parseValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Key.cpp b/src/private/mx/core/generated/Key.cpp index 12eee0737..4fe8df5d5 100644 --- a/src/private/mx/core/generated/Key.cpp +++ b/src/private/mx/core/generated/Key.cpp @@ -212,7 +212,7 @@ Key parseKey(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Link.cpp b/src/private/mx/core/generated/Link.cpp index 76d4c26e0..f3788a04c 100644 --- a/src/private/mx/core/generated/Link.cpp +++ b/src/private/mx/core/generated/Link.cpp @@ -183,7 +183,7 @@ Link parseLink(pugi::xml_node el, const ParseContext &context) } else if (aname == "element") { - out.setElement(NameToken::parse(a.value())); + out.setElement(parseValue(a.value(), context, el, "element")); } else if (aname == "position") { diff --git a/src/private/mx/core/generated/Lyric.cpp b/src/private/mx/core/generated/Lyric.cpp index 8253fe544..774bfc9cf 100644 --- a/src/private/mx/core/generated/Lyric.cpp +++ b/src/private/mx/core/generated/Lyric.cpp @@ -183,7 +183,7 @@ Lyric parseLyric(pugi::xml_node el, const ParseContext &context) } if (aname == "number") { - out.setNumber(NameToken::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else if (aname == "name") { @@ -227,7 +227,7 @@ Lyric parseLyric(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/LyricFont.cpp b/src/private/mx/core/generated/LyricFont.cpp index bb44fa005..29bb74a0d 100644 --- a/src/private/mx/core/generated/LyricFont.cpp +++ b/src/private/mx/core/generated/LyricFont.cpp @@ -83,7 +83,7 @@ LyricFont parseLyricFont(pugi::xml_node el, const ParseContext &context) } if (aname == "number") { - out.setNumber(NameToken::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else if (aname == "name") { diff --git a/src/private/mx/core/generated/LyricLanguage.cpp b/src/private/mx/core/generated/LyricLanguage.cpp index 7dc7e490f..1707a5131 100644 --- a/src/private/mx/core/generated/LyricLanguage.cpp +++ b/src/private/mx/core/generated/LyricLanguage.cpp @@ -54,7 +54,7 @@ LyricLanguage parseLyricLanguage(pugi::xml_node el, const ParseContext &context) } if (aname == "number") { - out.setNumber(NameToken::parse(a.value())); + out.setNumber(parseValue(a.value(), context, el, "number")); } else if (aname == "name") { diff --git a/src/private/mx/core/generated/MIDIDevice.cpp b/src/private/mx/core/generated/MIDIDevice.cpp index f7e0f1d20..84ab156d0 100644 --- a/src/private/mx/core/generated/MIDIDevice.cpp +++ b/src/private/mx/core/generated/MIDIDevice.cpp @@ -57,7 +57,7 @@ MIDIDevice parseMIDIDevice(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/MIDIInstrument.cpp b/src/private/mx/core/generated/MIDIInstrument.cpp index a03464436..605055011 100644 --- a/src/private/mx/core/generated/MIDIInstrument.cpp +++ b/src/private/mx/core/generated/MIDIInstrument.cpp @@ -115,7 +115,7 @@ MIDIInstrument parseMIDIInstrument(pugi::xml_node el, const ParseContext &contex if (aname == "id") { seen_id = true; - out.setID(Token::parse(a.value())); + out.setID(parseValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/MeasureStyle.cpp b/src/private/mx/core/generated/MeasureStyle.cpp index 0d81eb26d..4a83c6de6 100644 --- a/src/private/mx/core/generated/MeasureStyle.cpp +++ b/src/private/mx/core/generated/MeasureStyle.cpp @@ -127,7 +127,7 @@ MeasureStyle parseMeasureStyle(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Metronome.cpp b/src/private/mx/core/generated/Metronome.cpp index 1a53ff407..78738bf36 100644 --- a/src/private/mx/core/generated/Metronome.cpp +++ b/src/private/mx/core/generated/Metronome.cpp @@ -239,7 +239,7 @@ Metronome parseMetronome(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/NonArpeggiate.cpp b/src/private/mx/core/generated/NonArpeggiate.cpp index d5ffff2cd..21bd0d124 100644 --- a/src/private/mx/core/generated/NonArpeggiate.cpp +++ b/src/private/mx/core/generated/NonArpeggiate.cpp @@ -147,7 +147,7 @@ NonArpeggiate parseNonArpeggiate(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Notations.cpp b/src/private/mx/core/generated/Notations.cpp index 82f29111b..cf6a25877 100644 --- a/src/private/mx/core/generated/Notations.cpp +++ b/src/private/mx/core/generated/Notations.cpp @@ -72,7 +72,7 @@ Notations parseNotations(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Note.cpp b/src/private/mx/core/generated/Note.cpp index 39d3850d0..d1f7b71ef 100644 --- a/src/private/mx/core/generated/Note.cpp +++ b/src/private/mx/core/generated/Note.cpp @@ -503,7 +503,7 @@ Note parseNote(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/OctaveShift.cpp b/src/private/mx/core/generated/OctaveShift.cpp index e631528dd..3fe716707 100644 --- a/src/private/mx/core/generated/OctaveShift.cpp +++ b/src/private/mx/core/generated/OctaveShift.cpp @@ -231,7 +231,7 @@ OctaveShift parseOctaveShift(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Ornaments.cpp b/src/private/mx/core/generated/Ornaments.cpp index f65ec1d7c..133a7f00e 100644 --- a/src/private/mx/core/generated/Ornaments.cpp +++ b/src/private/mx/core/generated/Ornaments.cpp @@ -48,7 +48,7 @@ Ornaments parseOrnaments(pugi::xml_node el, const ParseContext &context) } if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/OtherDirection.cpp b/src/private/mx/core/generated/OtherDirection.cpp index 1d4e0e971..cfb4a459a 100644 --- a/src/private/mx/core/generated/OtherDirection.cpp +++ b/src/private/mx/core/generated/OtherDirection.cpp @@ -225,7 +225,7 @@ OtherDirection parseOtherDirection(pugi::xml_node el, const ParseContext &contex } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/OtherListening.cpp b/src/private/mx/core/generated/OtherListening.cpp index 79db3c92f..e6b941bb9 100644 --- a/src/private/mx/core/generated/OtherListening.cpp +++ b/src/private/mx/core/generated/OtherListening.cpp @@ -69,7 +69,7 @@ OtherListening parseOtherListening(pugi::xml_node el, const ParseContext &contex } else if (aname == "player") { - out.setPlayer(Token::parse(a.value())); + out.setPlayer(parseValue(a.value(), context, el, "player")); } else if (aname == "time-only") { diff --git a/src/private/mx/core/generated/OtherNotation.cpp b/src/private/mx/core/generated/OtherNotation.cpp index 3879c0774..cf34e36e0 100644 --- a/src/private/mx/core/generated/OtherNotation.cpp +++ b/src/private/mx/core/generated/OtherNotation.cpp @@ -241,7 +241,7 @@ OtherNotation parseOtherNotation(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/PartwiseMeasure.cpp b/src/private/mx/core/generated/PartwiseMeasure.cpp index 0adbee573..70ae7a1d1 100644 --- a/src/private/mx/core/generated/PartwiseMeasure.cpp +++ b/src/private/mx/core/generated/PartwiseMeasure.cpp @@ -120,7 +120,7 @@ PartwiseMeasure parsePartwiseMeasure(pugi::xml_node el, const ParseContext &cont } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/PartwisePart.cpp b/src/private/mx/core/generated/PartwisePart.cpp index 409424363..7902aa4eb 100644 --- a/src/private/mx/core/generated/PartwisePart.cpp +++ b/src/private/mx/core/generated/PartwisePart.cpp @@ -50,7 +50,7 @@ PartwisePart parsePartwisePart(pugi::xml_node el, const ParseContext &context) if (aname == "id") { seen_id = true; - out.setID(Token::parse(a.value())); + out.setID(parseValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Pedal.cpp b/src/private/mx/core/generated/Pedal.cpp index e80e72b77..9b19435d6 100644 --- a/src/private/mx/core/generated/Pedal.cpp +++ b/src/private/mx/core/generated/Pedal.cpp @@ -259,7 +259,7 @@ Pedal parsePedal(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Percussion.cpp b/src/private/mx/core/generated/Percussion.cpp index b28ce4a73..70f2ff798 100644 --- a/src/private/mx/core/generated/Percussion.cpp +++ b/src/private/mx/core/generated/Percussion.cpp @@ -211,7 +211,7 @@ Percussion parsePercussion(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Play.cpp b/src/private/mx/core/generated/Play.cpp index 4a4547b1c..3eeeb4747 100644 --- a/src/private/mx/core/generated/Play.cpp +++ b/src/private/mx/core/generated/Play.cpp @@ -48,7 +48,7 @@ Play parsePlay(pugi::xml_node el, const ParseContext &context) } if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Player.cpp b/src/private/mx/core/generated/Player.cpp index d5235385b..1c8d6bf7b 100644 --- a/src/private/mx/core/generated/Player.cpp +++ b/src/private/mx/core/generated/Player.cpp @@ -45,7 +45,7 @@ Player parsePlayer(pugi::xml_node el, const ParseContext &context) if (aname == "id") { seen_id = true; - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/PrincipalVoice.cpp b/src/private/mx/core/generated/PrincipalVoice.cpp index db4f33fc9..65099afe3 100644 --- a/src/private/mx/core/generated/PrincipalVoice.cpp +++ b/src/private/mx/core/generated/PrincipalVoice.cpp @@ -229,7 +229,7 @@ PrincipalVoice parsePrincipalVoice(pugi::xml_node el, const ParseContext &contex } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Print.cpp b/src/private/mx/core/generated/Print.cpp index 2da075be0..bbbddbe0c 100644 --- a/src/private/mx/core/generated/Print.cpp +++ b/src/private/mx/core/generated/Print.cpp @@ -153,7 +153,7 @@ Print parsePrint(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Scordatura.cpp b/src/private/mx/core/generated/Scordatura.cpp index 14b24b99e..0016c9675 100644 --- a/src/private/mx/core/generated/Scordatura.cpp +++ b/src/private/mx/core/generated/Scordatura.cpp @@ -48,7 +48,7 @@ Scordatura parseScordatura(pugi::xml_node el, const ParseContext &context) } if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/ScoreInstrument.cpp b/src/private/mx/core/generated/ScoreInstrument.cpp index 6b9dd9e78..98aa4dd0b 100644 --- a/src/private/mx/core/generated/ScoreInstrument.cpp +++ b/src/private/mx/core/generated/ScoreInstrument.cpp @@ -65,7 +65,7 @@ ScoreInstrument parseScoreInstrument(pugi::xml_node el, const ParseContext &cont if (aname == "id") { seen_id = true; - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/ScorePart.cpp b/src/private/mx/core/generated/ScorePart.cpp index 4e891e6cd..26a6aaec7 100644 --- a/src/private/mx/core/generated/ScorePart.cpp +++ b/src/private/mx/core/generated/ScorePart.cpp @@ -160,7 +160,7 @@ ScorePart parseScorePart(pugi::xml_node el, const ParseContext &context) if (aname == "id") { seen_id = true; - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Segno.cpp b/src/private/mx/core/generated/Segno.cpp index a4f84033d..56406ea74 100644 --- a/src/private/mx/core/generated/Segno.cpp +++ b/src/private/mx/core/generated/Segno.cpp @@ -201,7 +201,7 @@ Segno parseSegno(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Slide.cpp b/src/private/mx/core/generated/Slide.cpp index dbb50443c..0188b0fac 100644 --- a/src/private/mx/core/generated/Slide.cpp +++ b/src/private/mx/core/generated/Slide.cpp @@ -297,7 +297,7 @@ Slide parseSlide(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Slur.cpp b/src/private/mx/core/generated/Slur.cpp index db96d41f1..343b84097 100644 --- a/src/private/mx/core/generated/Slur.cpp +++ b/src/private/mx/core/generated/Slur.cpp @@ -287,7 +287,7 @@ Slur parseSlur(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Sound.cpp b/src/private/mx/core/generated/Sound.cpp index 54a48fda7..015c5d814 100644 --- a/src/private/mx/core/generated/Sound.cpp +++ b/src/private/mx/core/generated/Sound.cpp @@ -306,7 +306,7 @@ Sound parseSound(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/StaffDivide.cpp b/src/private/mx/core/generated/StaffDivide.cpp index 0f0b0dd8c..1659b5c01 100644 --- a/src/private/mx/core/generated/StaffDivide.cpp +++ b/src/private/mx/core/generated/StaffDivide.cpp @@ -203,7 +203,7 @@ StaffDivide parseStaffDivide(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/StringMute.cpp b/src/private/mx/core/generated/StringMute.cpp index 1fd60c0e6..a5c16aa88 100644 --- a/src/private/mx/core/generated/StringMute.cpp +++ b/src/private/mx/core/generated/StringMute.cpp @@ -203,7 +203,7 @@ StringMute parseStringMute(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Supports.cpp b/src/private/mx/core/generated/Supports.cpp index 6ef77731f..5b75b36ed 100644 --- a/src/private/mx/core/generated/Supports.cpp +++ b/src/private/mx/core/generated/Supports.cpp @@ -71,11 +71,11 @@ Supports parseSupports(pugi::xml_node el, const ParseContext &context) else if (aname == "element") { seen_element = true; - out.setElement(NameToken::parse(a.value())); + out.setElement(parseValue(a.value(), context, el, "element")); } else if (aname == "attribute") { - out.setAttribute(NameToken::parse(a.value())); + out.setAttribute(parseValue(a.value(), context, el, "attribute")); } else if (aname == "value") { diff --git a/src/private/mx/core/generated/Sync.cpp b/src/private/mx/core/generated/Sync.cpp index 91e23db14..79c8e3cf0 100644 --- a/src/private/mx/core/generated/Sync.cpp +++ b/src/private/mx/core/generated/Sync.cpp @@ -73,7 +73,7 @@ Sync parseSync(pugi::xml_node el, const ParseContext &context) } else if (aname == "player") { - out.setPlayer(Token::parse(a.value())); + out.setPlayer(parseValue(a.value(), context, el, "player")); } else if (aname == "time-only") { diff --git a/src/private/mx/core/generated/Technical.cpp b/src/private/mx/core/generated/Technical.cpp index e7d419bac..930a36209 100644 --- a/src/private/mx/core/generated/Technical.cpp +++ b/src/private/mx/core/generated/Technical.cpp @@ -48,7 +48,7 @@ Technical parseTechnical(pugi::xml_node el, const ParseContext &context) } if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Tied.cpp b/src/private/mx/core/generated/Tied.cpp index 39f8a2d5c..7e300b3c6 100644 --- a/src/private/mx/core/generated/Tied.cpp +++ b/src/private/mx/core/generated/Tied.cpp @@ -287,7 +287,7 @@ Tied parseTied(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Time.cpp b/src/private/mx/core/generated/Time.cpp index 7c92596f6..56d10bb47 100644 --- a/src/private/mx/core/generated/Time.cpp +++ b/src/private/mx/core/generated/Time.cpp @@ -253,7 +253,7 @@ Time parseTime(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/TimewiseMeasure.cpp b/src/private/mx/core/generated/TimewiseMeasure.cpp index 2ca6bded4..57856e823 100644 --- a/src/private/mx/core/generated/TimewiseMeasure.cpp +++ b/src/private/mx/core/generated/TimewiseMeasure.cpp @@ -120,7 +120,7 @@ TimewiseMeasure parseTimewiseMeasure(pugi::xml_node el, const ParseContext &cont } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/TimewisePart.cpp b/src/private/mx/core/generated/TimewisePart.cpp index f0060a1ea..d24fa9508 100644 --- a/src/private/mx/core/generated/TimewisePart.cpp +++ b/src/private/mx/core/generated/TimewisePart.cpp @@ -50,7 +50,7 @@ TimewisePart parseTimewisePart(pugi::xml_node el, const ParseContext &context) if (aname == "id") { seen_id = true; - out.setID(Token::parse(a.value())); + out.setID(parseValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Transpose.cpp b/src/private/mx/core/generated/Transpose.cpp index 54ada6c62..80a05cfc4 100644 --- a/src/private/mx/core/generated/Transpose.cpp +++ b/src/private/mx/core/generated/Transpose.cpp @@ -57,7 +57,7 @@ Transpose parseTranspose(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Tuplet.cpp b/src/private/mx/core/generated/Tuplet.cpp index df0f964c7..5ba9086da 100644 --- a/src/private/mx/core/generated/Tuplet.cpp +++ b/src/private/mx/core/generated/Tuplet.cpp @@ -209,7 +209,7 @@ Tuplet parseTuplet(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mx/core/generated/Wait.cpp b/src/private/mx/core/generated/Wait.cpp index ef74b34a3..6f0dd639f 100644 --- a/src/private/mx/core/generated/Wait.cpp +++ b/src/private/mx/core/generated/Wait.cpp @@ -43,7 +43,7 @@ Wait parseWait(pugi::xml_node el, const ParseContext &context) } if (aname == "player") { - out.setPlayer(Token::parse(a.value())); + out.setPlayer(parseValue(a.value(), context, el, "player")); } else if (aname == "time-only") { diff --git a/src/private/mx/core/generated/Wedge.cpp b/src/private/mx/core/generated/Wedge.cpp index 7d99913c8..732f032e5 100644 --- a/src/private/mx/core/generated/Wedge.cpp +++ b/src/private/mx/core/generated/Wedge.cpp @@ -203,7 +203,7 @@ Wedge parseWedge(pugi::xml_node el, const ParseContext &context) } else if (aname == "id") { - out.setID(Token::parse(a.value())); + out.setID(parseIdValue(a.value(), context, el, "id")); } else { diff --git a/src/private/mxtest/core/ImportDiagnosticsTest.cpp b/src/private/mxtest/core/ImportDiagnosticsTest.cpp index 57d939a55..645b92315 100644 --- a/src/private/mxtest/core/ImportDiagnosticsTest.cpp +++ b/src/private/mxtest/core/ImportDiagnosticsTest.cpp @@ -128,11 +128,42 @@ TEST(RepairsAccumulateInDocumentOrder, ImportDiagnostics) CHECK_EQUAL(std::string{"/score-partwise/part/measure/note[2]"}, parsed.diagnostics[3].path); } -TEST(ValidAlternateSpellingsReportNothing, ImportDiagnostics) +TEST(RepairedIdWarnsThatItMayDuplicateAnother, ImportDiagnostics) +{ + const auto parsed = + importDiagnosticsParse(importDiagnosticsScore("", "1")); + REQUIRE(parsed.ok); + REQUIRE(parsed.diagnostics.size() == 1); + const Diagnostic &diagnostic = parsed.diagnostics.front(); + CHECK(DiagnosticCode::invalidValue == diagnostic.code); + CHECK_EQUAL(std::string{"/score-partwise/part/measure/note"}, diagnostic.path); + CHECK_EQUAL(std::string{"invalid value \"1\" in attribute \"id\"; using \"X\"; " + "the repaired ID may duplicate another ID in the document"}, + diagnostic.message); +} + +TEST(RepairedReferencesAndNameTokensOmitTheIdWarning, ImportDiagnostics) { const auto parsed = importDiagnosticsParse( - importDiagnosticsScore("", "C+04" - " 1 quarter")); + "Music" + "1" + "la"); + REQUIRE(parsed.ok); + REQUIRE(parsed.diagnostics.size() == 2); + CHECK(DiagnosticCode::invalidValue == parsed.diagnostics[0].code); + CHECK_EQUAL(std::string{"/score-partwise/part"}, parsed.diagnostics[0].path); + CHECK_EQUAL(std::string{"invalid value \"P 1\" in attribute \"id\"; using \"P1\""}, parsed.diagnostics[0].message); + CHECK(DiagnosticCode::invalidValue == parsed.diagnostics[1].code); + CHECK_EQUAL(std::string{"/score-partwise/part/measure/note/lyric"}, parsed.diagnostics[1].path); + CHECK_EQUAL(std::string{"invalid value \"1 2\" in attribute \"number\"; using \"12\""}, + parsed.diagnostics[1].message); +} + +TEST(ValidAlternateSpellingsReportNothing, ImportDiagnostics) +{ + const auto parsed = importDiagnosticsParse(importDiagnosticsScore( + "", "C+04" + " 1 quarter")); REQUIRE(parsed.ok); CHECK(parsed.diagnostics.empty()); } diff --git a/src/private/mxtest/core/ValueTest.cpp b/src/private/mxtest/core/ValueTest.cpp index fcc4626bf..2b2a7b090 100644 --- a/src/private/mxtest/core/ValueTest.cpp +++ b/src/private/mxtest/core/ValueTest.cpp @@ -273,6 +273,11 @@ TEST(TokenRepairsToNCName, Values) CHECK(!Token::tryParse("1P", parsed)); // leading digit CHECK(!Token::tryParse("P 1", parsed)); // space CHECK(!Token::tryParse("", parsed)); // empty + ValueParseOutcome outcome = ValueParseOutcome::invalid; + CHECK_EQUAL(std::string{"P1"}, Token::parse(" P1 ", outcome).toString()); + CHECK(ValueParseOutcome::valid == outcome); // surrounding whitespace is not a repair + CHECK_EQUAL(std::string{"P1"}, Token::parse("P 1", outcome).toString()); + CHECK(ValueParseOutcome::invalid == outcome); } TEST(NameTokenRepairsToNmtoken, Values) @@ -287,4 +292,9 @@ TEST(NameTokenRepairsToNmtoken, Values) CHECK(NameToken::tryParse("verse-1", parsed)); CHECK(!NameToken::tryParse("verse one", parsed)); // space CHECK(!NameToken::tryParse("", parsed)); // empty + ValueParseOutcome outcome = ValueParseOutcome::invalid; + CHECK_EQUAL(std::string{"1"}, NameToken::parse(" 1 ", outcome).toString()); + CHECK(ValueParseOutcome::valid == outcome); // surrounding whitespace is not a repair + CHECK_EQUAL(std::string{"verseone"}, NameToken::parse("verse one", outcome).toString()); + CHECK(ValueParseOutcome::invalid == outcome); } From e438ff252a48d52dd96ee80267594bd8193c0086 Mon Sep 17 00:00:00 2001 From: Matthew James Briggs Date: Thu, 17 Sep 2026 17:28:59 +0200 Subject: [PATCH 4/8] feat: report bespoke value type repairs Color, font-family, SMuFL glyph names, time-only, yyyy-mm-dd and ending-number values gain parse(text, outcome), which reports invalid when the strict parse rejects the text. parseValue no longer has a silent branch, so a value type without the outcome form fails to compile. --- gen/cpp/templates/color.cpp.tmpl | 12 +++++ gen/cpp/templates/color.h.tmpl | 5 ++ .../templates/comma_separated_text.cpp.tmpl | 12 +++++ gen/cpp/templates/comma_separated_text.h.tmpl | 5 ++ gen/cpp/templates/ending_number.cpp.tmpl | 12 +++++ gen/cpp/templates/ending_number.h.tmpl | 5 ++ gen/cpp/templates/nmtoken_string.cpp.tmpl | 12 +++++ gen/cpp/templates/nmtoken_string.h.tmpl | 5 ++ gen/cpp/templates/smufl_prefixed.cpp.tmpl | 12 +++++ gen/cpp/templates/smufl_prefixed.h.tmpl | 5 ++ gen/cpp/templates/smufl_wavy.cpp.tmpl | 12 +++++ gen/cpp/templates/smufl_wavy.h.tmpl | 5 ++ gen/cpp/templates/time_only.cpp.tmpl | 12 +++++ gen/cpp/templates/time_only.h.tmpl | 5 ++ gen/cpp/templates/yyyy_mm_dd.cpp.tmpl | 12 +++++ gen/cpp/templates/yyyy_mm_dd.h.tmpl | 5 ++ src/private/mx/core/ParseContext.h | 20 +++----- src/private/mx/core/generated/Color.cpp | 12 +++++ src/private/mx/core/generated/Color.h | 5 ++ .../mx/core/generated/CommaSeparatedText.cpp | 12 +++++ .../mx/core/generated/CommaSeparatedText.h | 5 ++ .../mx/core/generated/EndingNumber.cpp | 12 +++++ src/private/mx/core/generated/EndingNumber.h | 5 ++ src/private/mx/core/generated/FontFamily.cpp | 12 +++++ src/private/mx/core/generated/FontFamily.h | 5 ++ .../generated/SmuflAccidentalGlyphName.cpp | 12 +++++ .../core/generated/SmuflAccidentalGlyphName.h | 5 ++ .../mx/core/generated/SmuflCodaGlyphName.cpp | 12 +++++ .../mx/core/generated/SmuflCodaGlyphName.h | 5 ++ .../mx/core/generated/SmuflGlyphName.cpp | 12 +++++ .../mx/core/generated/SmuflGlyphName.h | 5 ++ .../core/generated/SmuflLyricsGlyphName.cpp | 12 +++++ .../mx/core/generated/SmuflLyricsGlyphName.h | 5 ++ .../generated/SmuflPictogramGlyphName.cpp | 12 +++++ .../core/generated/SmuflPictogramGlyphName.h | 5 ++ .../mx/core/generated/SmuflSegnoGlyphName.cpp | 12 +++++ .../mx/core/generated/SmuflSegnoGlyphName.h | 5 ++ .../core/generated/SmuflWavyLineGlyphName.cpp | 12 +++++ .../core/generated/SmuflWavyLineGlyphName.h | 5 ++ src/private/mx/core/generated/TimeOnly.cpp | 12 +++++ src/private/mx/core/generated/TimeOnly.h | 5 ++ src/private/mx/core/generated/YyyyMmDd.cpp | 12 +++++ src/private/mx/core/generated/YyyyMmDd.h | 5 ++ .../mxtest/core/ImportDiagnosticsTest.cpp | 51 +++++++++++++++++++ 44 files changed, 414 insertions(+), 14 deletions(-) diff --git a/gen/cpp/templates/color.cpp.tmpl b/gen/cpp/templates/color.cpp.tmpl index 71a4d95f5..b999d6a5a 100644 --- a/gen/cpp/templates/color.cpp.tmpl +++ b/gen/cpp/templates/color.cpp.tmpl @@ -96,4 +96,16 @@ bool {{ident}}::tryParse(std::string_view text, {{ident}} &out) noexcept return out; } +{{ident}} {{ident}}::parse(std::string_view text, ValueParseOutcome &outcome) noexcept +{ + {{ident}} out; + if (tryParse(text, out)) + { + outcome = ValueParseOutcome::valid; + return out; + } + outcome = ValueParseOutcome::invalid; + return parse(text); +} + } // namespace {{vars.namespace}} diff --git a/gen/cpp/templates/color.h.tmpl b/gen/cpp/templates/color.h.tmpl index 2a785858d..77dd691bd 100644 --- a/gen/cpp/templates/color.h.tmpl +++ b/gen/cpp/templates/color.h.tmpl @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include #include @@ -81,6 +83,9 @@ public: /// Lenient: malformed text yields opaque black. static {{ident}} parse(std::string_view text) noexcept; + /// Lenient, and says whether the text had to be repaired. + static {{ident}} parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const {{ident}} &other) const noexcept = default; private: diff --git a/gen/cpp/templates/comma_separated_text.cpp.tmpl b/gen/cpp/templates/comma_separated_text.cpp.tmpl index e1e8fc0db..d0dd21ebe 100644 --- a/gen/cpp/templates/comma_separated_text.cpp.tmpl +++ b/gen/cpp/templates/comma_separated_text.cpp.tmpl @@ -120,4 +120,16 @@ bool {{ident}}::tryParse(std::string_view text, {{ident}} &out) return out; } +{{ident}} {{ident}}::parse(std::string_view text, ValueParseOutcome &outcome) +{ + {{ident}} out; + if (tryParse(text, out)) + { + outcome = ValueParseOutcome::valid; + return out; + } + outcome = ValueParseOutcome::invalid; + return parse(text); +} + } // namespace {{vars.namespace}} diff --git a/gen/cpp/templates/comma_separated_text.h.tmpl b/gen/cpp/templates/comma_separated_text.h.tmpl index b70bb923e..ff6350e5a 100644 --- a/gen/cpp/templates/comma_separated_text.h.tmpl +++ b/gen/cpp/templates/comma_separated_text.h.tmpl @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include #include @@ -43,6 +45,9 @@ public: /// Lenient: repairs into the nearest valid list. static {{ident}} parse(std::string_view text); + /// Lenient, and says whether the text had to be repaired. + static {{ident}} parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const {{ident}} &other) const noexcept { return m_items == other.m_items; diff --git a/gen/cpp/templates/ending_number.cpp.tmpl b/gen/cpp/templates/ending_number.cpp.tmpl index 2a386a159..a439b220a 100644 --- a/gen/cpp/templates/ending_number.cpp.tmpl +++ b/gen/cpp/templates/ending_number.cpp.tmpl @@ -101,4 +101,16 @@ bool {{ident}}::tryParse(std::string_view text, {{ident}} &out) return out; } +{{ident}} {{ident}}::parse(std::string_view text, ValueParseOutcome &outcome) +{ + {{ident}} out; + if (tryParse(text, out)) + { + outcome = ValueParseOutcome::valid; + return out; + } + outcome = ValueParseOutcome::invalid; + return parse(text); +} + } // namespace {{vars.namespace}} diff --git a/gen/cpp/templates/ending_number.h.tmpl b/gen/cpp/templates/ending_number.h.tmpl index 40d390562..bad22539f 100644 --- a/gen/cpp/templates/ending_number.h.tmpl +++ b/gen/cpp/templates/ending_number.h.tmpl @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include #include @@ -43,6 +45,9 @@ public: /// Lenient: repairs into the nearest valid value. static {{ident}} parse(std::string_view text); + /// Lenient, and says whether the text had to be repaired. + static {{ident}} parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const {{ident}} &other) const noexcept { return m_values == other.m_values; diff --git a/gen/cpp/templates/nmtoken_string.cpp.tmpl b/gen/cpp/templates/nmtoken_string.cpp.tmpl index 26a4c5f04..0977ea0e5 100644 --- a/gen/cpp/templates/nmtoken_string.cpp.tmpl +++ b/gen/cpp/templates/nmtoken_string.cpp.tmpl @@ -70,4 +70,16 @@ bool {{ident}}::tryParse(std::string_view text, {{ident}} &out) return {{ident}}{std::string{text}}; } +{{ident}} {{ident}}::parse(std::string_view text, ValueParseOutcome &outcome) +{ + {{ident}} out; + if (tryParse(text, out)) + { + outcome = ValueParseOutcome::valid; + return out; + } + outcome = ValueParseOutcome::invalid; + return parse(text); +} + } // namespace {{vars.namespace}} diff --git a/gen/cpp/templates/nmtoken_string.h.tmpl b/gen/cpp/templates/nmtoken_string.h.tmpl index ef4a5171a..3d4a004d6 100644 --- a/gen/cpp/templates/nmtoken_string.h.tmpl +++ b/gen/cpp/templates/nmtoken_string.h.tmpl @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -40,6 +42,9 @@ public: /// Lenient: repairs into the nearest valid token. static {{ident}} parse(std::string_view text); + /// Lenient, and says whether the text had to be repaired. + static {{ident}} parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const {{ident}} &other) const noexcept = default; private: diff --git a/gen/cpp/templates/smufl_prefixed.cpp.tmpl b/gen/cpp/templates/smufl_prefixed.cpp.tmpl index a3eddd9c4..82e179c3c 100644 --- a/gen/cpp/templates/smufl_prefixed.cpp.tmpl +++ b/gen/cpp/templates/smufl_prefixed.cpp.tmpl @@ -143,4 +143,16 @@ bool {{ident}}::tryParse(std::string_view text, {{ident}} &out) return {{ident}}{std::string{text}}; } +{{ident}} {{ident}}::parse(std::string_view text, ValueParseOutcome &outcome) +{ + {{ident}} out; + if (tryParse(text, out)) + { + outcome = ValueParseOutcome::valid; + return out; + } + outcome = ValueParseOutcome::invalid; + return parse(text); +} + } // namespace {{vars.namespace}} diff --git a/gen/cpp/templates/smufl_prefixed.h.tmpl b/gen/cpp/templates/smufl_prefixed.h.tmpl index 3180d54e7..cf841508f 100644 --- a/gen/cpp/templates/smufl_prefixed.h.tmpl +++ b/gen/cpp/templates/smufl_prefixed.h.tmpl @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -59,6 +61,9 @@ public: /// Lenient: repairs into the nearest valid glyph name. static {{ident}} parse(std::string_view text); + /// Lenient, and says whether the text had to be repaired. + static {{ident}} parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const {{ident}} &other) const noexcept = default; private: diff --git a/gen/cpp/templates/smufl_wavy.cpp.tmpl b/gen/cpp/templates/smufl_wavy.cpp.tmpl index 481d79a02..d054d9c2a 100644 --- a/gen/cpp/templates/smufl_wavy.cpp.tmpl +++ b/gen/cpp/templates/smufl_wavy.cpp.tmpl @@ -120,4 +120,16 @@ bool {{ident}}::tryParse(std::string_view text, {{ident}} &out) return {{ident}}{Kind::wiggle, std::string{text}}; } +{{ident}} {{ident}}::parse(std::string_view text, ValueParseOutcome &outcome) +{ + {{ident}} out; + if (tryParse(text, out)) + { + outcome = ValueParseOutcome::valid; + return out; + } + outcome = ValueParseOutcome::invalid; + return parse(text); +} + } // namespace {{vars.namespace}} diff --git a/gen/cpp/templates/smufl_wavy.h.tmpl b/gen/cpp/templates/smufl_wavy.h.tmpl index 425f410ae..9e8b8be68 100644 --- a/gen/cpp/templates/smufl_wavy.h.tmpl +++ b/gen/cpp/templates/smufl_wavy.h.tmpl @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -52,6 +54,9 @@ public: /// Lenient: repairs into the nearest valid glyph name. static {{ident}} parse(std::string_view text); + /// Lenient, and says whether the text had to be repaired. + static {{ident}} parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const {{ident}} &other) const noexcept = default; private: diff --git a/gen/cpp/templates/time_only.cpp.tmpl b/gen/cpp/templates/time_only.cpp.tmpl index 032951199..d296f3b3b 100644 --- a/gen/cpp/templates/time_only.cpp.tmpl +++ b/gen/cpp/templates/time_only.cpp.tmpl @@ -103,4 +103,16 @@ bool {{ident}}::tryParse(std::string_view text, {{ident}} &out) return out; } +{{ident}} {{ident}}::parse(std::string_view text, ValueParseOutcome &outcome) +{ + {{ident}} out; + if (tryParse(text, out)) + { + outcome = ValueParseOutcome::valid; + return out; + } + outcome = ValueParseOutcome::invalid; + return parse(text); +} + } // namespace {{vars.namespace}} diff --git a/gen/cpp/templates/time_only.h.tmpl b/gen/cpp/templates/time_only.h.tmpl index eeb718fb8..24d096bbb 100644 --- a/gen/cpp/templates/time_only.h.tmpl +++ b/gen/cpp/templates/time_only.h.tmpl @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include #include @@ -41,6 +43,9 @@ public: /// Lenient: repairs into the nearest valid list. static {{ident}} parse(std::string_view text); + /// Lenient, and says whether the text had to be repaired. + static {{ident}} parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const {{ident}} &other) const noexcept { return m_values == other.m_values; diff --git a/gen/cpp/templates/yyyy_mm_dd.cpp.tmpl b/gen/cpp/templates/yyyy_mm_dd.cpp.tmpl index be628071b..18cb7c8cb 100644 --- a/gen/cpp/templates/yyyy_mm_dd.cpp.tmpl +++ b/gen/cpp/templates/yyyy_mm_dd.cpp.tmpl @@ -131,4 +131,16 @@ bool {{ident}}::tryParse(std::string_view text, {{ident}} &out) noexcept return out; } +{{ident}} {{ident}}::parse(std::string_view text, ValueParseOutcome &outcome) noexcept +{ + {{ident}} out; + if (tryParse(text, out)) + { + outcome = ValueParseOutcome::valid; + return out; + } + outcome = ValueParseOutcome::invalid; + return parse(text); +} + } // namespace {{vars.namespace}} diff --git a/gen/cpp/templates/yyyy_mm_dd.h.tmpl b/gen/cpp/templates/yyyy_mm_dd.h.tmpl index f03265ee7..a8ee7164e 100644 --- a/gen/cpp/templates/yyyy_mm_dd.h.tmpl +++ b/gen/cpp/templates/yyyy_mm_dd.h.tmpl @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -52,6 +54,9 @@ public: /// components clamp. static {{ident}} parse(std::string_view text) noexcept; + /// Lenient, and says whether the text had to be repaired. + static {{ident}} parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const {{ident}} &other) const noexcept = default; private: diff --git a/src/private/mx/core/ParseContext.h b/src/private/mx/core/ParseContext.h index d36dc8e8a..9d599ad1c 100644 --- a/src/private/mx/core/ParseContext.h +++ b/src/private/mx/core/ParseContext.h @@ -63,25 +63,17 @@ void reportIdRepair(const ParseContext &context, ValueParseOutcome outcome, pugi void reportAttributeDefaulted(const ParseContext &context, pugi::xml_node el, const char *attribute, std::string_view value); -/// The lenient parse of a value type, reporting any repair it made. A type -/// without an outcome-reporting parse is parsed silently. +/// The lenient parse of a value type, reporting any repair it made. template T parseValue(std::string_view text, const ParseContext &context, pugi::xml_node el, const char *attribute) { - if constexpr (requires(std::string_view s, ValueParseOutcome &o) { T::parse(s, o); }) - { - ValueParseOutcome outcome = ValueParseOutcome::valid; - T value = T::parse(text, outcome); - if (outcome != ValueParseOutcome::valid) - { - reportValueRepair(context, outcome, el, attribute, text, std::string{value.toString()}); - } - return value; - } - else + ValueParseOutcome outcome = ValueParseOutcome::valid; + T value = T::parse(text, outcome); + if (outcome != ValueParseOutcome::valid) { - return T::parse(text); + reportValueRepair(context, outcome, el, attribute, text, std::string{value.toString()}); } + return value; } /// The lenient parse of an xs:ID attribute, reporting any repair it made. diff --git a/src/private/mx/core/generated/Color.cpp b/src/private/mx/core/generated/Color.cpp index c80542ffb..2e73a9086 100644 --- a/src/private/mx/core/generated/Color.cpp +++ b/src/private/mx/core/generated/Color.cpp @@ -96,4 +96,16 @@ Color Color::parse(std::string_view text) noexcept return out; } +Color Color::parse(std::string_view text, ValueParseOutcome &outcome) noexcept +{ + Color out; + if (tryParse(text, out)) + { + outcome = ValueParseOutcome::valid; + return out; + } + outcome = ValueParseOutcome::invalid; + return parse(text); +} + } // namespace mx::core diff --git a/src/private/mx/core/generated/Color.h b/src/private/mx/core/generated/Color.h index a727a205f..b8771f0ae 100644 --- a/src/private/mx/core/generated/Color.h +++ b/src/private/mx/core/generated/Color.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include #include @@ -83,6 +85,9 @@ class Color final /// Lenient: malformed text yields opaque black. static Color parse(std::string_view text) noexcept; + /// Lenient, and says whether the text had to be repaired. + static Color parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const Color &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/CommaSeparatedText.cpp b/src/private/mx/core/generated/CommaSeparatedText.cpp index 5126c6589..0b6c8e0a4 100644 --- a/src/private/mx/core/generated/CommaSeparatedText.cpp +++ b/src/private/mx/core/generated/CommaSeparatedText.cpp @@ -120,4 +120,16 @@ CommaSeparatedText CommaSeparatedText::parse(std::string_view text) return out; } +CommaSeparatedText CommaSeparatedText::parse(std::string_view text, ValueParseOutcome &outcome) +{ + CommaSeparatedText out; + if (tryParse(text, out)) + { + outcome = ValueParseOutcome::valid; + return out; + } + outcome = ValueParseOutcome::invalid; + return parse(text); +} + } // namespace mx::core diff --git a/src/private/mx/core/generated/CommaSeparatedText.h b/src/private/mx/core/generated/CommaSeparatedText.h index fa11711ea..220f722af 100644 --- a/src/private/mx/core/generated/CommaSeparatedText.h +++ b/src/private/mx/core/generated/CommaSeparatedText.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include #include @@ -42,6 +44,9 @@ class CommaSeparatedText final /// Lenient: repairs into the nearest valid list. static CommaSeparatedText parse(std::string_view text); + /// Lenient, and says whether the text had to be repaired. + static CommaSeparatedText parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const CommaSeparatedText &other) const noexcept { return m_items == other.m_items; diff --git a/src/private/mx/core/generated/EndingNumber.cpp b/src/private/mx/core/generated/EndingNumber.cpp index a849bcb3f..0489a6332 100644 --- a/src/private/mx/core/generated/EndingNumber.cpp +++ b/src/private/mx/core/generated/EndingNumber.cpp @@ -101,4 +101,16 @@ EndingNumber EndingNumber::parse(std::string_view text) return out; } +EndingNumber EndingNumber::parse(std::string_view text, ValueParseOutcome &outcome) +{ + EndingNumber out; + if (tryParse(text, out)) + { + outcome = ValueParseOutcome::valid; + return out; + } + outcome = ValueParseOutcome::invalid; + return parse(text); +} + } // namespace mx::core diff --git a/src/private/mx/core/generated/EndingNumber.h b/src/private/mx/core/generated/EndingNumber.h index 9dc703149..beda365aa 100644 --- a/src/private/mx/core/generated/EndingNumber.h +++ b/src/private/mx/core/generated/EndingNumber.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include #include @@ -44,6 +46,9 @@ class EndingNumber final /// Lenient: repairs into the nearest valid value. static EndingNumber parse(std::string_view text); + /// Lenient, and says whether the text had to be repaired. + static EndingNumber parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const EndingNumber &other) const noexcept { return m_values == other.m_values; diff --git a/src/private/mx/core/generated/FontFamily.cpp b/src/private/mx/core/generated/FontFamily.cpp index 1bb0a1aa8..12c16e841 100644 --- a/src/private/mx/core/generated/FontFamily.cpp +++ b/src/private/mx/core/generated/FontFamily.cpp @@ -120,4 +120,16 @@ FontFamily FontFamily::parse(std::string_view text) return out; } +FontFamily FontFamily::parse(std::string_view text, ValueParseOutcome &outcome) +{ + FontFamily out; + if (tryParse(text, out)) + { + outcome = ValueParseOutcome::valid; + return out; + } + outcome = ValueParseOutcome::invalid; + return parse(text); +} + } // namespace mx::core diff --git a/src/private/mx/core/generated/FontFamily.h b/src/private/mx/core/generated/FontFamily.h index 68eea2b34..09948c99d 100644 --- a/src/private/mx/core/generated/FontFamily.h +++ b/src/private/mx/core/generated/FontFamily.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include #include @@ -45,6 +47,9 @@ class FontFamily final /// Lenient: repairs into the nearest valid list. static FontFamily parse(std::string_view text); + /// Lenient, and says whether the text had to be repaired. + static FontFamily parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const FontFamily &other) const noexcept { return m_items == other.m_items; diff --git a/src/private/mx/core/generated/SmuflAccidentalGlyphName.cpp b/src/private/mx/core/generated/SmuflAccidentalGlyphName.cpp index b9d527615..aa7186017 100644 --- a/src/private/mx/core/generated/SmuflAccidentalGlyphName.cpp +++ b/src/private/mx/core/generated/SmuflAccidentalGlyphName.cpp @@ -124,4 +124,16 @@ SmuflAccidentalGlyphName SmuflAccidentalGlyphName::parse(std::string_view text) return SmuflAccidentalGlyphName{std::string{text}}; } +SmuflAccidentalGlyphName SmuflAccidentalGlyphName::parse(std::string_view text, ValueParseOutcome &outcome) +{ + SmuflAccidentalGlyphName out; + if (tryParse(text, out)) + { + outcome = ValueParseOutcome::valid; + return out; + } + outcome = ValueParseOutcome::invalid; + return parse(text); +} + } // namespace mx::core diff --git a/src/private/mx/core/generated/SmuflAccidentalGlyphName.h b/src/private/mx/core/generated/SmuflAccidentalGlyphName.h index e4087ed1c..705030f18 100644 --- a/src/private/mx/core/generated/SmuflAccidentalGlyphName.h +++ b/src/private/mx/core/generated/SmuflAccidentalGlyphName.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -57,6 +59,9 @@ class SmuflAccidentalGlyphName final /// Lenient: repairs into the nearest valid glyph name. static SmuflAccidentalGlyphName parse(std::string_view text); + /// Lenient, and says whether the text had to be repaired. + static SmuflAccidentalGlyphName parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const SmuflAccidentalGlyphName &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/SmuflCodaGlyphName.cpp b/src/private/mx/core/generated/SmuflCodaGlyphName.cpp index d3bd6e67b..ce99d1875 100644 --- a/src/private/mx/core/generated/SmuflCodaGlyphName.cpp +++ b/src/private/mx/core/generated/SmuflCodaGlyphName.cpp @@ -97,4 +97,16 @@ SmuflCodaGlyphName SmuflCodaGlyphName::parse(std::string_view text) return SmuflCodaGlyphName{std::string{text}}; } +SmuflCodaGlyphName SmuflCodaGlyphName::parse(std::string_view text, ValueParseOutcome &outcome) +{ + SmuflCodaGlyphName out; + if (tryParse(text, out)) + { + outcome = ValueParseOutcome::valid; + return out; + } + outcome = ValueParseOutcome::invalid; + return parse(text); +} + } // namespace mx::core diff --git a/src/private/mx/core/generated/SmuflCodaGlyphName.h b/src/private/mx/core/generated/SmuflCodaGlyphName.h index 953fe532e..aff3f4326 100644 --- a/src/private/mx/core/generated/SmuflCodaGlyphName.h +++ b/src/private/mx/core/generated/SmuflCodaGlyphName.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -37,6 +39,9 @@ class SmuflCodaGlyphName final /// Lenient: repairs into the nearest valid glyph name. static SmuflCodaGlyphName parse(std::string_view text); + /// Lenient, and says whether the text had to be repaired. + static SmuflCodaGlyphName parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const SmuflCodaGlyphName &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/SmuflGlyphName.cpp b/src/private/mx/core/generated/SmuflGlyphName.cpp index 61e16cd06..4a48f3ebe 100644 --- a/src/private/mx/core/generated/SmuflGlyphName.cpp +++ b/src/private/mx/core/generated/SmuflGlyphName.cpp @@ -70,4 +70,16 @@ SmuflGlyphName SmuflGlyphName::parse(std::string_view text) return SmuflGlyphName{std::string{text}}; } +SmuflGlyphName SmuflGlyphName::parse(std::string_view text, ValueParseOutcome &outcome) +{ + SmuflGlyphName out; + if (tryParse(text, out)) + { + outcome = ValueParseOutcome::valid; + return out; + } + outcome = ValueParseOutcome::invalid; + return parse(text); +} + } // namespace mx::core diff --git a/src/private/mx/core/generated/SmuflGlyphName.h b/src/private/mx/core/generated/SmuflGlyphName.h index 6ae20c1a1..05066b5fb 100644 --- a/src/private/mx/core/generated/SmuflGlyphName.h +++ b/src/private/mx/core/generated/SmuflGlyphName.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -40,6 +42,9 @@ class SmuflGlyphName final /// Lenient: repairs into the nearest valid token. static SmuflGlyphName parse(std::string_view text); + /// Lenient, and says whether the text had to be repaired. + static SmuflGlyphName parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const SmuflGlyphName &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/SmuflLyricsGlyphName.cpp b/src/private/mx/core/generated/SmuflLyricsGlyphName.cpp index 913e9fef6..f52c18c89 100644 --- a/src/private/mx/core/generated/SmuflLyricsGlyphName.cpp +++ b/src/private/mx/core/generated/SmuflLyricsGlyphName.cpp @@ -105,4 +105,16 @@ SmuflLyricsGlyphName SmuflLyricsGlyphName::parse(std::string_view text) return SmuflLyricsGlyphName{std::string{text}}; } +SmuflLyricsGlyphName SmuflLyricsGlyphName::parse(std::string_view text, ValueParseOutcome &outcome) +{ + SmuflLyricsGlyphName out; + if (tryParse(text, out)) + { + outcome = ValueParseOutcome::valid; + return out; + } + outcome = ValueParseOutcome::invalid; + return parse(text); +} + } // namespace mx::core diff --git a/src/private/mx/core/generated/SmuflLyricsGlyphName.h b/src/private/mx/core/generated/SmuflLyricsGlyphName.h index 970cc9e24..099b5eb42 100644 --- a/src/private/mx/core/generated/SmuflLyricsGlyphName.h +++ b/src/private/mx/core/generated/SmuflLyricsGlyphName.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -39,6 +41,9 @@ class SmuflLyricsGlyphName final /// Lenient: repairs into the nearest valid glyph name. static SmuflLyricsGlyphName parse(std::string_view text); + /// Lenient, and says whether the text had to be repaired. + static SmuflLyricsGlyphName parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const SmuflLyricsGlyphName &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/SmuflPictogramGlyphName.cpp b/src/private/mx/core/generated/SmuflPictogramGlyphName.cpp index a71955a29..3d2ea7f89 100644 --- a/src/private/mx/core/generated/SmuflPictogramGlyphName.cpp +++ b/src/private/mx/core/generated/SmuflPictogramGlyphName.cpp @@ -105,4 +105,16 @@ SmuflPictogramGlyphName SmuflPictogramGlyphName::parse(std::string_view text) return SmuflPictogramGlyphName{std::string{text}}; } +SmuflPictogramGlyphName SmuflPictogramGlyphName::parse(std::string_view text, ValueParseOutcome &outcome) +{ + SmuflPictogramGlyphName out; + if (tryParse(text, out)) + { + outcome = ValueParseOutcome::valid; + return out; + } + outcome = ValueParseOutcome::invalid; + return parse(text); +} + } // namespace mx::core diff --git a/src/private/mx/core/generated/SmuflPictogramGlyphName.h b/src/private/mx/core/generated/SmuflPictogramGlyphName.h index 5edf8dfae..a5627475c 100644 --- a/src/private/mx/core/generated/SmuflPictogramGlyphName.h +++ b/src/private/mx/core/generated/SmuflPictogramGlyphName.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -39,6 +41,9 @@ class SmuflPictogramGlyphName final /// Lenient: repairs into the nearest valid glyph name. static SmuflPictogramGlyphName parse(std::string_view text); + /// Lenient, and says whether the text had to be repaired. + static SmuflPictogramGlyphName parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const SmuflPictogramGlyphName &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/SmuflSegnoGlyphName.cpp b/src/private/mx/core/generated/SmuflSegnoGlyphName.cpp index 88db3505e..8bea76b35 100644 --- a/src/private/mx/core/generated/SmuflSegnoGlyphName.cpp +++ b/src/private/mx/core/generated/SmuflSegnoGlyphName.cpp @@ -97,4 +97,16 @@ SmuflSegnoGlyphName SmuflSegnoGlyphName::parse(std::string_view text) return SmuflSegnoGlyphName{std::string{text}}; } +SmuflSegnoGlyphName SmuflSegnoGlyphName::parse(std::string_view text, ValueParseOutcome &outcome) +{ + SmuflSegnoGlyphName out; + if (tryParse(text, out)) + { + outcome = ValueParseOutcome::valid; + return out; + } + outcome = ValueParseOutcome::invalid; + return parse(text); +} + } // namespace mx::core diff --git a/src/private/mx/core/generated/SmuflSegnoGlyphName.h b/src/private/mx/core/generated/SmuflSegnoGlyphName.h index 7767ffa96..5dc255898 100644 --- a/src/private/mx/core/generated/SmuflSegnoGlyphName.h +++ b/src/private/mx/core/generated/SmuflSegnoGlyphName.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -37,6 +39,9 @@ class SmuflSegnoGlyphName final /// Lenient: repairs into the nearest valid glyph name. static SmuflSegnoGlyphName parse(std::string_view text); + /// Lenient, and says whether the text had to be repaired. + static SmuflSegnoGlyphName parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const SmuflSegnoGlyphName &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/SmuflWavyLineGlyphName.cpp b/src/private/mx/core/generated/SmuflWavyLineGlyphName.cpp index bdaebb54f..0b45c3d60 100644 --- a/src/private/mx/core/generated/SmuflWavyLineGlyphName.cpp +++ b/src/private/mx/core/generated/SmuflWavyLineGlyphName.cpp @@ -119,4 +119,16 @@ SmuflWavyLineGlyphName SmuflWavyLineGlyphName::parse(std::string_view text) return SmuflWavyLineGlyphName{Kind::wiggle, std::string{text}}; } +SmuflWavyLineGlyphName SmuflWavyLineGlyphName::parse(std::string_view text, ValueParseOutcome &outcome) +{ + SmuflWavyLineGlyphName out; + if (tryParse(text, out)) + { + outcome = ValueParseOutcome::valid; + return out; + } + outcome = ValueParseOutcome::invalid; + return parse(text); +} + } // namespace mx::core diff --git a/src/private/mx/core/generated/SmuflWavyLineGlyphName.h b/src/private/mx/core/generated/SmuflWavyLineGlyphName.h index e0b381630..7829c5d7d 100644 --- a/src/private/mx/core/generated/SmuflWavyLineGlyphName.h +++ b/src/private/mx/core/generated/SmuflWavyLineGlyphName.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -53,6 +55,9 @@ class SmuflWavyLineGlyphName final /// Lenient: repairs into the nearest valid glyph name. static SmuflWavyLineGlyphName parse(std::string_view text); + /// Lenient, and says whether the text had to be repaired. + static SmuflWavyLineGlyphName parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const SmuflWavyLineGlyphName &other) const noexcept = default; private: diff --git a/src/private/mx/core/generated/TimeOnly.cpp b/src/private/mx/core/generated/TimeOnly.cpp index 2e245e020..f9653deb9 100644 --- a/src/private/mx/core/generated/TimeOnly.cpp +++ b/src/private/mx/core/generated/TimeOnly.cpp @@ -103,4 +103,16 @@ TimeOnly TimeOnly::parse(std::string_view text) return out; } +TimeOnly TimeOnly::parse(std::string_view text, ValueParseOutcome &outcome) +{ + TimeOnly out; + if (tryParse(text, out)) + { + outcome = ValueParseOutcome::valid; + return out; + } + outcome = ValueParseOutcome::invalid; + return parse(text); +} + } // namespace mx::core diff --git a/src/private/mx/core/generated/TimeOnly.h b/src/private/mx/core/generated/TimeOnly.h index 9601a43cf..6e76662c4 100644 --- a/src/private/mx/core/generated/TimeOnly.h +++ b/src/private/mx/core/generated/TimeOnly.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include #include @@ -42,6 +44,9 @@ class TimeOnly final /// Lenient: repairs into the nearest valid list. static TimeOnly parse(std::string_view text); + /// Lenient, and says whether the text had to be repaired. + static TimeOnly parse(std::string_view text, ValueParseOutcome &outcome); + bool operator==(const TimeOnly &other) const noexcept { return m_values == other.m_values; diff --git a/src/private/mx/core/generated/YyyyMmDd.cpp b/src/private/mx/core/generated/YyyyMmDd.cpp index 3180fb5b0..ff369cd26 100644 --- a/src/private/mx/core/generated/YyyyMmDd.cpp +++ b/src/private/mx/core/generated/YyyyMmDd.cpp @@ -130,4 +130,16 @@ YyyyMmDd YyyyMmDd::parse(std::string_view text) noexcept return out; } +YyyyMmDd YyyyMmDd::parse(std::string_view text, ValueParseOutcome &outcome) noexcept +{ + YyyyMmDd out; + if (tryParse(text, out)) + { + outcome = ValueParseOutcome::valid; + return out; + } + outcome = ValueParseOutcome::invalid; + return parse(text); +} + } // namespace mx::core diff --git a/src/private/mx/core/generated/YyyyMmDd.h b/src/private/mx/core/generated/YyyyMmDd.h index 675e33dd1..9c7f31845 100644 --- a/src/private/mx/core/generated/YyyyMmDd.h +++ b/src/private/mx/core/generated/YyyyMmDd.h @@ -2,6 +2,8 @@ #pragma once +#include "mx/core/Lexical.h" + #include #include @@ -51,6 +53,9 @@ class YyyyMmDd final /// components clamp. static YyyyMmDd parse(std::string_view text) noexcept; + /// Lenient, and says whether the text had to be repaired. + static YyyyMmDd parse(std::string_view text, ValueParseOutcome &outcome) noexcept; + bool operator==(const YyyyMmDd &other) const noexcept = default; private: diff --git a/src/private/mxtest/core/ImportDiagnosticsTest.cpp b/src/private/mxtest/core/ImportDiagnosticsTest.cpp index 645b92315..fb31b3fa9 100644 --- a/src/private/mxtest/core/ImportDiagnosticsTest.cpp +++ b/src/private/mxtest/core/ImportDiagnosticsTest.cpp @@ -183,3 +183,54 @@ TEST(SilentParseProducesTheSameDocument, ImportDiagnostics) REQUIRE(silent.ok()); CHECK(silent.value() == reported.document); } + +inline std::string importDiagnosticsBespokeScore(const std::string &date, const std::string &ending, + const std::string &color, const std::string &timeOnly, + const std::string &fontFamily, const std::string &accidental, + const std::string ¬ehead, const std::string &wavyLine) +{ + return importDiagnosticsScore( + "" + date + "", + "C41sharpnormal"); +} + +TEST(EachBespokeValueTypeReportsARepair, ImportDiagnostics) +{ + const auto parsed = importDiagnosticsParse(importDiagnosticsBespokeScore( + "2024-02-30", "1-2", "#ff0000", "1, x", "Arial,,Serif", "sharp", "note head", "guitarVibrato")); + REQUIRE(parsed.ok); + const std::vector> expected{ + {"/score-partwise/identification/encoding/encoding-date", "invalid value \"2024-02-30\"; using \"1900-01-01\""}, + {"/score-partwise/part/measure/barline/ending", "invalid value \"1-2\" in attribute \"number\"; using \"\""}, + {"/score-partwise/part/measure/note", "invalid value \"#ff0000\" in attribute \"color\"; using \"#000000\""}, + {"/score-partwise/part/measure/note", "invalid value \"1, x\" in attribute \"time-only\"; using \"1\""}, + {"/score-partwise/part/measure/note/accidental", + "invalid value \"Arial,,Serif\" in attribute \"font-family\"; using \"Arial Serif\""}, + {"/score-partwise/part/measure/note/accidental", + "invalid value \"sharp\" in attribute \"smufl\"; using \"accsharp\""}, + {"/score-partwise/part/measure/note/notehead", + "invalid value \"note head\" in attribute \"smufl\"; using \"notehead\""}, + {"/score-partwise/part/measure/note/notations/ornaments/wavy-line", + "invalid value \"guitarVibrato\" in attribute \"smufl\"; using \"wiggleguitarVibrato\""}, + }; + REQUIRE(parsed.diagnostics.size() == expected.size()); + for (std::size_t i = 0; i < expected.size(); ++i) + { + CHECK(DiagnosticCode::invalidValue == parsed.diagnostics[i].code); + CHECK_EQUAL(expected[i].first, parsed.diagnostics[i].path); + CHECK_EQUAL(expected[i].second, parsed.diagnostics[i].message); + } +} + +TEST(ValidBespokeValuesReportNothing, ImportDiagnostics) +{ + const auto parsed = importDiagnosticsParse(importDiagnosticsBespokeScore( + "2024-02-29", "1, 2", "#80FF0000", "1,2", "Arial, Serif", "accidentalSharp", "noteheadBlack", "wiggleTrill")); + REQUIRE(parsed.ok); + CHECK(parsed.diagnostics.empty()); +} From d2247e74c61a0befe9ab4b731bbbfd1cc8d1bc1a Mon Sep 17 00:00:00 2001 From: Matthew James Briggs Date: Thu, 17 Sep 2026 17:58:10 +0200 Subject: [PATCH 5/8] feat: add droppedData and read plumbing DiagnosticCode gains droppedData, for data that could not be read or written and was left out. The read context now reaches the direction, note, ornament and layout readers and the timewise conversion, and the direction readers take a MeasureCursor so reports carry the part and measure. --- src/include/mx/api/Diagnostics.h | 9 +++++---- src/private/mx/api/MusicXml.cpp | 5 +++-- src/private/mx/impl/DirectionReader.cpp | 11 +++++++---- src/private/mx/impl/DirectionReader.h | 10 ++++++---- src/private/mx/impl/LayoutFunctions.cpp | 8 +++++--- src/private/mx/impl/LayoutFunctions.h | 7 +++++-- src/private/mx/impl/MeasureReader.cpp | 6 +++--- src/private/mx/impl/NoteFunctions.cpp | 6 +++--- src/private/mx/impl/NoteFunctions.h | 8 +++++--- src/private/mx/impl/OrnamentsFunctions.cpp | 5 +++-- src/private/mx/impl/OrnamentsFunctions.h | 8 +++++--- src/private/mx/impl/ScoreConversions.cpp | 2 +- src/private/mx/impl/ScoreConversions.h | 3 ++- src/private/mx/impl/ScoreReader.cpp | 2 +- src/private/mxtest/impl/DirectionReaderTest.cpp | 10 +++++----- src/private/mxtest/impl/DirectionWriterTest.cpp | 12 ++++++------ 16 files changed, 65 insertions(+), 47 deletions(-) diff --git a/src/include/mx/api/Diagnostics.h b/src/include/mx/api/Diagnostics.h index e4a001bd8..37e538c05 100644 --- a/src/include/mx/api/Diagnostics.h +++ b/src/include/mx/api/Diagnostics.h @@ -26,10 +26,11 @@ enum class Severity // The recoverable decision reported by a diagnostic. enum class DiagnosticCode { - valueAdjusted, // a value was changed to one that MusicXML can represent - unmatchedSpanner, // a spanner endpoint had no matching endpoint - invalidValue, // a value could not be read, so a default was used - missingValueDefaulted // a required value was missing, so a default was used + valueAdjusted, // a value was changed to one that MusicXML can represent + unmatchedSpanner, // a spanner endpoint had no matching endpoint + invalidValue, // a value could not be read, so a default was used + missingValueDefaulted, // a required value was missing, so a default was used + droppedData // data could not be read or written, so it was left out }; // A non-fatal problem noticed while producing a score or MusicXML document. diff --git a/src/private/mx/api/MusicXml.cpp b/src/private/mx/api/MusicXml.cpp index 777402ec3..1c57741a9 100644 --- a/src/private/mx/api/MusicXml.cpp +++ b/src/private/mx/api/MusicXml.cpp @@ -405,8 +405,9 @@ Result getScore(const MusicXml &document, Diagnostics &diagnostics) // that; the owned document is untouched. if (coreDocument.isScoreTimewise()) { - const core::ScorePartwise scorePartwise = impl::timewisePartwise(coreDocument.asScoreTimewise()); - impl::ScoreReader reader{scorePartwise, impl::DiagnosticsContext{diagnostics}}; + const impl::DiagnosticsContext context{diagnostics}; + const core::ScorePartwise scorePartwise = impl::timewisePartwise(coreDocument.asScoreTimewise(), context); + impl::ScoreReader reader{scorePartwise, context}; auto score = reader.getScoreData(); score.musicXmlType = "timewise"; return score; diff --git a/src/private/mx/impl/DirectionReader.cpp b/src/private/mx/impl/DirectionReader.cpp index c951bd9b9..7f765fa71 100644 --- a/src/private/mx/impl/DirectionReader.cpp +++ b/src/private/mx/impl/DirectionReader.cpp @@ -98,13 +98,16 @@ namespace mx { namespace impl { -DirectionReader::DirectionReader(const core::Direction &inDirection, Cursor inCursor) - : myDirection{&inDirection}, myHarmony{nullptr}, myCursor{inCursor}, myConverter{}, myOutDirectionData{} +DirectionReader::DirectionReader(const core::Direction &inDirection, MeasureCursor inCursor, + DiagnosticsContext diagnostics) + : myDirection{&inDirection}, myHarmony{nullptr}, myCursor{inCursor}, myConverter{}, myDiagnostics{diagnostics}, + myOutDirectionData{} { } -DirectionReader::DirectionReader(const core::Harmony &inHarmony, Cursor inCursor) - : myDirection{nullptr}, myHarmony{&inHarmony}, myCursor{inCursor}, myConverter{}, myOutDirectionData{} +DirectionReader::DirectionReader(const core::Harmony &inHarmony, MeasureCursor inCursor, DiagnosticsContext diagnostics) + : myDirection{nullptr}, myHarmony{&inHarmony}, myCursor{inCursor}, myConverter{}, myDiagnostics{diagnostics}, + myOutDirectionData{} { } diff --git a/src/private/mx/impl/DirectionReader.h b/src/private/mx/impl/DirectionReader.h index 392f86e8e..05b921e78 100644 --- a/src/private/mx/impl/DirectionReader.h +++ b/src/private/mx/impl/DirectionReader.h @@ -12,7 +12,8 @@ #include "mx/core/generated/HarmonyChordGroup.h" #include "mx/core/generated/PercussionChoice.h" #include "mx/impl/Converter.h" -#include "mx/impl/Cursor.h" +#include "mx/impl/DiagnosticsContext.h" +#include "mx/impl/MeasureCursor.h" #include "mx/impl/PositionFunctions.h" #include @@ -25,15 +26,16 @@ namespace impl class DirectionReader { public: - DirectionReader(const core::Direction &inDirection, Cursor inCursor); - DirectionReader(const core::Harmony &inHarmony, Cursor inCursor); + DirectionReader(const core::Direction &inDirection, MeasureCursor inCursor, DiagnosticsContext diagnostics = {}); + DirectionReader(const core::Harmony &inHarmony, MeasureCursor inCursor, DiagnosticsContext diagnostics = {}); api::DirectionData getDirectionData(); private: const core::Direction *const myDirection; const core::Harmony *const myHarmony; - const Cursor myCursor; + const MeasureCursor myCursor; const Converter myConverter; + DiagnosticsContext myDiagnostics; api::DirectionData myOutDirectionData; private: diff --git a/src/private/mx/impl/LayoutFunctions.cpp b/src/private/mx/impl/LayoutFunctions.cpp index c94291c6f..5a37c56b1 100644 --- a/src/private/mx/impl/LayoutFunctions.cpp +++ b/src/private/mx/impl/LayoutFunctions.cpp @@ -299,14 +299,15 @@ void addAppearance(const api::DefaultsData &inDefaults, core::ScoreHeaderGroup & outScoreHeaderGroup.setDefaults(defaults); } -api::DefaultsData createDefaults(const core::ScoreHeaderGroup &inScoreHeaderGroup) +api::DefaultsData createDefaults(const core::ScoreHeaderGroup &inScoreHeaderGroup, + const DiagnosticsContext &diagnostics) { api::DefaultsData defaults; addScaling(inScoreHeaderGroup, defaults); addPageMargins(inScoreHeaderGroup, defaults); addSystemMargins(inScoreHeaderGroup, defaults); addStaffLayout(inScoreHeaderGroup, defaults); - addAppearance(inScoreHeaderGroup, defaults); + addAppearance(inScoreHeaderGroup, defaults, diagnostics); addDefaultsFonts(inScoreHeaderGroup, defaults); return defaults; } @@ -457,7 +458,8 @@ void addStaffLayout(const core::ScoreHeaderGroup &inScoreHeaderGroup, api::Defau } } -void addAppearance(const core::ScoreHeaderGroup &inScoreHeaderGroup, api::DefaultsData &outDefaults) +void addAppearance(const core::ScoreHeaderGroup &inScoreHeaderGroup, api::DefaultsData &outDefaults, + const DiagnosticsContext &diagnostics) { outDefaults.appearance.clear(); diff --git a/src/private/mx/impl/LayoutFunctions.h b/src/private/mx/impl/LayoutFunctions.h index 463d79fc5..49e0da925 100644 --- a/src/private/mx/impl/LayoutFunctions.h +++ b/src/private/mx/impl/LayoutFunctions.h @@ -6,6 +6,7 @@ #include "mx/api/DefaultsData.h" #include "mx/core/generated/ScoreHeaderGroup.h" +#include "mx/impl/DiagnosticsContext.h" namespace mx { @@ -22,12 +23,14 @@ void addDefaultsFonts(const api::DefaultsData &inDefaults, core::ScoreHeaderGrou //////////////////////////////////////////////////////////////////////////////////////////////////////////////// // core::ScoreHeaderGroup -> api::DefaultsData -api::DefaultsData createDefaults(const core::ScoreHeaderGroup &inScoreHeaderGroup); +api::DefaultsData createDefaults(const core::ScoreHeaderGroup &inScoreHeaderGroup, + const DiagnosticsContext &diagnostics); void addScaling(const core::ScoreHeaderGroup &inScoreHeaderGroup, api::DefaultsData &outDefaults); void addPageMargins(const core::ScoreHeaderGroup &inScoreHeaderGroup, api::DefaultsData &outDefaults); void addSystemMargins(const core::ScoreHeaderGroup &inScoreHeaderGroup, api::DefaultsData &outDefaults); void addStaffLayout(const core::ScoreHeaderGroup &inScoreHeaderGroup, api::DefaultsData &outDefaults); -void addAppearance(const core::ScoreHeaderGroup &inScoreHeaderGroup, api::DefaultsData &outDefaults); +void addAppearance(const core::ScoreHeaderGroup &inScoreHeaderGroup, api::DefaultsData &outDefaults, + const DiagnosticsContext &diagnostics); void addDefaultsFonts(const core::ScoreHeaderGroup &inScoreHeaderGroup, api::DefaultsData &outDefaults); } // namespace impl } // namespace mx diff --git a/src/private/mx/impl/MeasureReader.cpp b/src/private/mx/impl/MeasureReader.cpp index 8a26d7b23..6c48b69b7 100644 --- a/src/private/mx/impl/MeasureReader.cpp +++ b/src/private/mx/impl/MeasureReader.cpp @@ -382,7 +382,7 @@ void MeasureReader::parseNote(const core::Note &inMxNote, const core::Note *next myCurrentCursor.isBackupInProgress = false; impl::NoteReader noteReader{inMxNote}; - impl::NoteFunctions noteFunc{inMxNote, myCurrentCursor}; + impl::NoteFunctions noteFunc{inMxNote, myCurrentCursor, myDiagnostics}; auto noteData = noteFunc.parseNote(); int noteDataStaffIndex = noteReader.getStaffNumber() - 1; @@ -605,7 +605,7 @@ void MeasureReader::parseForward(const core::Forward &inMxForward) const void MeasureReader::parseDirection(const core::Direction &inDirection) const { - DirectionReader reader{inDirection, myCurrentCursor}; + DirectionReader reader{inDirection, myCurrentCursor, myDiagnostics}; auto directionData = reader.getDirectionData(); // make an adjustment if the directionData refers to a non-existent staff @@ -787,7 +787,7 @@ std::optional MeasureReader::parseAttributes(const core::Att void MeasureReader::parseHarmony(const core::Harmony &inHarmony) const { - DirectionReader reader{inHarmony, myCurrentCursor}; + DirectionReader reader{inHarmony, myCurrentCursor, myDiagnostics}; auto directionData = reader.getDirectionData(); // make an adjustment if the directionData refers to a non-existent staff diff --git a/src/private/mx/impl/NoteFunctions.cpp b/src/private/mx/impl/NoteFunctions.cpp index 6f1a61c3e..6d327c2e2 100644 --- a/src/private/mx/impl/NoteFunctions.cpp +++ b/src/private/mx/impl/NoteFunctions.cpp @@ -30,8 +30,8 @@ namespace mx { namespace impl { -NoteFunctions::NoteFunctions(const core::Note &inMxNote, impl::Cursor inCursor) - : myNote{inMxNote}, myCursor{inCursor}, myOutNoteData{} +NoteFunctions::NoteFunctions(const core::Note &inMxNote, MeasureCursor inCursor, DiagnosticsContext diagnostics) + : myNote{inMxNote}, myCursor{inCursor}, myDiagnostics{diagnostics}, myOutNoteData{} { } @@ -260,7 +260,7 @@ void NoteFunctions::parseNotations() const break; } case core::NotationsChoice::Kind::ornaments: { - OrnamentsFunctions funcs{notationsChoice.asOrnaments(), myCursor}; + OrnamentsFunctions funcs{notationsChoice.asOrnaments(), myCursor, myDiagnostics}; funcs.parseOrnaments(myOutNoteData.noteAttachmentData); break; } diff --git a/src/private/mx/impl/NoteFunctions.h b/src/private/mx/impl/NoteFunctions.h index def668952..cd87d0787 100644 --- a/src/private/mx/impl/NoteFunctions.h +++ b/src/private/mx/impl/NoteFunctions.h @@ -7,7 +7,8 @@ #include "mx/api/NoteData.h" #include "mx/core/generated/Note.h" #include "mx/impl/Converter.h" -#include "mx/impl/Cursor.h" +#include "mx/impl/DiagnosticsContext.h" +#include "mx/impl/MeasureCursor.h" #include @@ -20,13 +21,14 @@ class NoteReader; class NoteFunctions { public: - NoteFunctions(const core::Note &inMxNote, impl::Cursor cursor); + NoteFunctions(const core::Note &inMxNote, MeasureCursor cursor, DiagnosticsContext diagnostics = {}); ~NoteFunctions() = default; api::NoteData parseNote() const; private: const core::Note &myNote; - const impl::Cursor myCursor; + const MeasureCursor myCursor; + DiagnosticsContext myDiagnostics; mutable api::NoteData myOutNoteData; mutable std::mutex myMutex; diff --git a/src/private/mx/impl/OrnamentsFunctions.cpp b/src/private/mx/impl/OrnamentsFunctions.cpp index 1579188cc..a779779f0 100644 --- a/src/private/mx/impl/OrnamentsFunctions.cpp +++ b/src/private/mx/impl/OrnamentsFunctions.cpp @@ -40,8 +40,9 @@ void ornamentsFunctionsParseMordentSpecificAttributes(const core::Mordent &m, ap } } -OrnamentsFunctions::OrnamentsFunctions(const core::Ornaments &inOrnaments, impl::Cursor inCursor) - : myOrnaments{inOrnaments}, myCursor{inCursor} +OrnamentsFunctions::OrnamentsFunctions(const core::Ornaments &inOrnaments, MeasureCursor inCursor, + DiagnosticsContext diagnostics) + : myOrnaments{inOrnaments}, myCursor{inCursor}, myDiagnostics{diagnostics} { } diff --git a/src/private/mx/impl/OrnamentsFunctions.h b/src/private/mx/impl/OrnamentsFunctions.h index acb1459e9..1a377d316 100644 --- a/src/private/mx/impl/OrnamentsFunctions.h +++ b/src/private/mx/impl/OrnamentsFunctions.h @@ -7,7 +7,8 @@ #include "mx/api/MarkData.h" #include "mx/api/NoteAttachmentData.h" #include "mx/impl/Converter.h" -#include "mx/impl/Cursor.h" +#include "mx/impl/DiagnosticsContext.h" +#include "mx/impl/MeasureCursor.h" namespace mx { @@ -22,7 +23,7 @@ namespace impl class OrnamentsFunctions { public: - OrnamentsFunctions(const core::Ornaments &inOrnaments, impl::Cursor inCursor); + OrnamentsFunctions(const core::Ornaments &inOrnaments, MeasureCursor inCursor, DiagnosticsContext diagnostics = {}); ~OrnamentsFunctions() = default; OrnamentsFunctions(const OrnamentsFunctions &) = default; OrnamentsFunctions(OrnamentsFunctions &&) = default; @@ -30,7 +31,8 @@ class OrnamentsFunctions private: const core::Ornaments &myOrnaments; - const impl::Cursor myCursor; + const MeasureCursor myCursor; + DiagnosticsContext myDiagnostics; private: void parseOrnamentsSet(api::NoteAttachmentData &outAttachments) const; diff --git a/src/private/mx/impl/ScoreConversions.cpp b/src/private/mx/impl/ScoreConversions.cpp index 0f96fec8e..0b289d68e 100644 --- a/src/private/mx/impl/ScoreConversions.cpp +++ b/src/private/mx/impl/ScoreConversions.cpp @@ -117,7 +117,7 @@ core::ScoreTimewise partwiseTimewise(const core::ScorePartwise &inScore) return outScore; } -core::ScorePartwise timewisePartwise(const core::ScoreTimewise &inScore) +core::ScorePartwise timewisePartwise(const core::ScoreTimewise &inScore, const DiagnosticsContext &diagnostics) { core::ScorePartwise outScore; outScore.setScoreHeader(inScore.scoreHeader()); diff --git a/src/private/mx/impl/ScoreConversions.h b/src/private/mx/impl/ScoreConversions.h index 19165debf..ec756f705 100644 --- a/src/private/mx/impl/ScoreConversions.h +++ b/src/private/mx/impl/ScoreConversions.h @@ -6,6 +6,7 @@ #include "mx/core/generated/ScorePartwise.h" #include "mx/core/generated/ScoreTimewise.h" +#include "mx/impl/DiagnosticsContext.h" namespace mx { @@ -21,7 +22,7 @@ namespace impl core::ScoreTimewise partwiseTimewise(const core::ScorePartwise &inScore); // Converts a 'score-timewise' to 'score-partwise'. -core::ScorePartwise timewisePartwise(const core::ScoreTimewise &inScore); +core::ScorePartwise timewisePartwise(const core::ScoreTimewise &inScore, const DiagnosticsContext &diagnostics); } // namespace impl } // namespace mx diff --git a/src/private/mx/impl/ScoreReader.cpp b/src/private/mx/impl/ScoreReader.cpp index c855e71db..3f62175c9 100644 --- a/src/private/mx/impl/ScoreReader.cpp +++ b/src/private/mx/impl/ScoreReader.cpp @@ -258,7 +258,7 @@ api::ScoreData ScoreReader::getScoreData() const if (myHeaderGroup.defaults().has_value()) { - myOutScoreData.defaults = createDefaults(myHeaderGroup); + myOutScoreData.defaults = createDefaults(myHeaderGroup, myDiagnostics); } createCredits(myHeaderGroup, myOutScoreData); diff --git a/src/private/mxtest/impl/DirectionReaderTest.cpp b/src/private/mxtest/impl/DirectionReaderTest.cpp index b958d70af..a91d546f0 100644 --- a/src/private/mxtest/impl/DirectionReaderTest.cpp +++ b/src/private/mxtest/impl/DirectionReaderTest.cpp @@ -28,7 +28,7 @@ TEST(ottavaStart15ma, DirectionReader) core::DirectionType dirType{}; dirType.setChoice(core::DirectionTypeChoice::octaveShift(oct)); dir.setDirectionType(core::OneOrMore{dirType}); - Cursor cursor{1, 100}; + MeasureCursor cursor{1, 100}; cursor.tickTimePosition = tickTimePosition; DirectionReader reader{dir, cursor}; auto directionData = reader.getDirectionData(); @@ -59,7 +59,7 @@ TEST(ottavaStart22maAnd22mb, DirectionReader) direction.setDirectionType(core::OneOrMore{upType}); direction.addDirectionType(downType); - Cursor cursor{1, 100}; + MeasureCursor cursor{1, 100}; DirectionReader reader{direction, cursor}; const auto directionData = reader.getDirectionData(); @@ -101,7 +101,7 @@ TEST(ottavaStart8vaAnd8vb, DirectionReader) dir.addDirectionType(dirType2); dir.addDirectionType(dirType3); - Cursor cursor{1, 111}; + MeasureCursor cursor{1, 111}; cursor.tickTimePosition = tickTimePosition; DirectionReader reader{dir, cursor}; auto directionData = reader.getDirectionData(); @@ -133,7 +133,7 @@ TEST(ottavaStop, DirectionReader) dirType.setChoice(core::DirectionTypeChoice::octaveShift(oct)); core::Direction dir{}; dir.setDirectionType(core::OneOrMore{dirType}); - Cursor cursor{1, 100}; + MeasureCursor cursor{1, 100}; cursor.tickTimePosition = tickTimePosition; DirectionReader reader{dir, cursor}; auto directionData = reader.getDirectionData(); @@ -157,7 +157,7 @@ TEST(ottavaStopWithoutSize, DirectionReader) dirType.setChoice(core::DirectionTypeChoice::octaveShift(oct)); core::Direction dir{}; dir.setDirectionType(core::OneOrMore{dirType}); - Cursor cursor{1, 100}; + MeasureCursor cursor{1, 100}; DirectionReader reader{dir, cursor}; const auto directionData = reader.getDirectionData(); REQUIRE(directionData.directionTypes.size() == 1); diff --git a/src/private/mxtest/impl/DirectionWriterTest.cpp b/src/private/mxtest/impl/DirectionWriterTest.cpp index 385272b9f..6f2b0d9f7 100644 --- a/src/private/mxtest/impl/DirectionWriterTest.cpp +++ b/src/private/mxtest/impl/DirectionWriterTest.cpp @@ -23,7 +23,7 @@ using namespace mx::impl; TEST(ottavaStartStop, DirectionWriter) { - Cursor cursor{1, 100}; + MeasureCursor cursor{1, 100}; cursor.isFirstMeasureInPart = false; api::DirectionData directionData; @@ -91,7 +91,7 @@ TEST(ottava22maAnd22mb, DirectionWriter) down.ottavaType = api::OttavaType::o22mb; directionData.directionTypes.emplace_back(api::DirectionChoice{down}); - Cursor cursor{1, 100}; + MeasureCursor cursor{1, 100}; SpannerResolver spannerResolver; DirectionWriter writer{directionData, cursor, spannerResolver}; const auto mdcSet = writer.getDirectionLikeThings(); @@ -165,7 +165,7 @@ TEST(segnoAndCodaRoundTrip, DirectionWriter) directionData.directionTypes.emplace_back(api::DirectionChoice{segno}); directionData.directionTypes.emplace_back(api::DirectionChoice{coda}); - Cursor cursor{1, 100}; + MeasureCursor cursor{1, 100}; SpannerResolver spannerResolver; DirectionWriter writer{directionData, cursor, spannerResolver}; const auto mdcSet = writer.getDirectionLikeThings(); @@ -218,7 +218,7 @@ TEST(rehearsalRoundTrip, DirectionWriter) api::DirectionData directionData; directionData.directionTypes.emplace_back(api::DirectionChoice{rehearsal}); - Cursor cursor{1, 100}; + MeasureCursor cursor{1, 100}; SpannerResolver spannerResolver; DirectionWriter writer{directionData, cursor, spannerResolver}; const auto mdcSet = writer.getDirectionLikeThings(); @@ -247,7 +247,7 @@ TEST(directiveRoundTrip, DirectionWriter) directionData.directionTypes.emplace_back(api::DirectionChoice{rehearsal}); directionData.directive = api::Bool::yes; - Cursor cursor{1, 100}; + MeasureCursor cursor{1, 100}; SpannerResolver spannerResolver; DirectionWriter writer{directionData, cursor, spannerResolver}; const auto mdcSet = writer.getDirectionLikeThings(); @@ -273,7 +273,7 @@ TEST(directiveUnspecifiedWritesNoAttribute, DirectionWriter) api::DirectionData directionData; directionData.directionTypes.emplace_back(api::DirectionChoice{rehearsal}); - Cursor cursor{1, 100}; + MeasureCursor cursor{1, 100}; SpannerResolver spannerResolver; DirectionWriter writer{directionData, cursor, spannerResolver}; const auto mdcSet = writer.getDirectionLikeThings(); From cf13a56d44f3b29aefad837e231f061daf6c5fcc Mon Sep 17 00:00:00 2001 From: Matthew James Briggs Date: Thu, 17 Sep 2026 18:17:10 +0200 Subject: [PATCH 6/8] feat: report read recoveries getScore now reports the data it changes, defaults or leaves out: unmatched or duplicate parts, unbalanced part groups, rounded divisions and durations, a clamped backup, out-of-range staff numbers, snapped octave-shift sizes and tremolos, dropped degrees, staff details and repeated time signatures, and more. A non-numeric part-group number reads as unspecified and a clef number above the staff count adds staves, where both failed the read. Divisions that round to 0 read as 1, and a least common multiple of the divisions that overflows falls back to the largest divisions. --- src/private/mx/impl/Cursor.cpp | 10 +- src/private/mx/impl/Cursor.h | 2 + src/private/mx/impl/DiagnosticsContext.h | 10 + src/private/mx/impl/DirectionReader.cpp | 76 +++++- src/private/mx/impl/DirectionReader.h | 2 + src/private/mx/impl/LayoutFunctions.cpp | 5 + src/private/mx/impl/MeasureReader.cpp | 163 +++++++++++- src/private/mx/impl/MeasureReader.h | 4 + src/private/mx/impl/OrnamentsFunctions.cpp | 12 +- src/private/mx/impl/PartReader.cpp | 61 ++--- src/private/mx/impl/PartReader.h | 5 +- src/private/mx/impl/ScoreConversions.cpp | 28 ++ src/private/mx/impl/ScoreReader.cpp | 168 +++++++++--- .../mxtest/api/ReadDiagnosticsTest.cpp | 247 ++++++++++++++++++ 14 files changed, 700 insertions(+), 93 deletions(-) create mode 100644 src/private/mxtest/api/ReadDiagnosticsTest.cpp diff --git a/src/private/mx/impl/Cursor.cpp b/src/private/mx/impl/Cursor.cpp index a67ec560e..cb6f99983 100644 --- a/src/private/mx/impl/Cursor.cpp +++ b/src/private/mx/impl/Cursor.cpp @@ -43,16 +43,20 @@ int Cursor::convertDurationToGlobalTickScale(const core::PositiveDivisions &dura } int Cursor::convertDurationToGlobalTickScale(double durationValue) const +{ + return static_cast(std::ceil(convertDurationToExactGlobalTicks(durationValue) - 0.5)); +} + +double Cursor::convertDurationToExactGlobalTicks(double durationValue) const { if (this->ticksPerQuarter == this->getGlobalTicksPerQuarter()) { - return static_cast(std::ceil(durationValue - 0.5)); + return durationValue; } const double currentTicksPerQuarter = static_cast(this->ticksPerQuarter); const double globalTicksPerQuarter = static_cast(this->getGlobalTicksPerQuarter()); - const double convertedVal = durationValue * (globalTicksPerQuarter / currentTicksPerQuarter); - return static_cast(std::ceil(convertedVal - 0.5)); + return durationValue * (globalTicksPerQuarter / currentTicksPerQuarter); } int Cursor::convertDurationToGlobalTickScale(int durationValue) const diff --git a/src/private/mx/impl/Cursor.h b/src/private/mx/impl/Cursor.h index 5c626fc3a..82370896f 100644 --- a/src/private/mx/impl/Cursor.h +++ b/src/private/mx/impl/Cursor.h @@ -52,6 +52,8 @@ class Cursor int convertDurationToGlobalTickScale(const core::PositiveDivisions &duration) const; int convertDurationToGlobalTickScale(double durationValue) const; + // The duration in global ticks before it is rounded to a whole tick. + double convertDurationToExactGlobalTicks(double durationValue) const; int convertDurationToGlobalTickScale(int duration) const; private: diff --git a/src/private/mx/impl/DiagnosticsContext.h b/src/private/mx/impl/DiagnosticsContext.h index c0ce5662c..d8dfd9501 100644 --- a/src/private/mx/impl/DiagnosticsContext.h +++ b/src/private/mx/impl/DiagnosticsContext.h @@ -49,5 +49,15 @@ class DiagnosticsContext private: std::shared_ptr> myDiagnostics; }; + +// The part, measure and tick of a cursor, for a report that is not about one staff or voice. +inline api::Location measureLocation(const MeasureCursor &cursor) +{ + api::Location location; + location.partIndex = cursor.partIndex; + location.measureIndex = cursor.measureIndex; + location.tickTimePosition = cursor.tickTimePosition; + return location; +} } // namespace impl } // namespace mx diff --git a/src/private/mx/impl/DirectionReader.cpp b/src/private/mx/impl/DirectionReader.cpp index 7f765fa71..c79a07900 100644 --- a/src/private/mx/impl/DirectionReader.cpp +++ b/src/private/mx/impl/DirectionReader.cpp @@ -4,6 +4,7 @@ #include "mx/impl/DirectionReader.h" #include "mx/api/WedgeData.h" +#include "mx/core/Lexical.h" #include "mx/core/generated/Accord.h" #include "mx/core/generated/AccordionRegistration.h" #include "mx/core/generated/Barre.h" @@ -111,6 +112,20 @@ DirectionReader::DirectionReader(const core::Harmony &inHarmony, MeasureCursor i { } +void DirectionReader::report(api::Severity severity, api::DiagnosticCode code, std::string message) const +{ + myDiagnostics.report(severity, code, measureLocation(myCursor), std::move(message)); +} + +void DirectionReader::reportRounded(const char *name, double value, int rounded) const +{ + if (value != static_cast(rounded)) + { + report(api::Severity::warning, api::DiagnosticCode::valueAdjusted, + std::string{name} + " " + core::formatDouble(value) + " rounded to " + std::to_string(rounded)); + } +} + api::DirectionData DirectionReader::getDirectionData() { myOutDirectionData = initializeData(); @@ -152,6 +167,7 @@ void DirectionReader::parseOffset() { const auto rawVal = myDirection->offset()->value().value().value(); myOutDirectionData.offset = static_cast(std::ceil(rawVal - 0.5)); + reportRounded("offset", rawVal, *myOutDirectionData.offset); } } else if (myHarmony) @@ -160,6 +176,7 @@ void DirectionReader::parseOffset() { const auto rawVal = myHarmony->offset()->value().value().value(); myOutDirectionData.offset = static_cast(std::ceil(rawVal - 0.5)); + reportRounded("offset", rawVal, *myOutDirectionData.offset); } } } @@ -234,10 +251,16 @@ void DirectionReader::parseValues() if (myDirection->editorialVoiceDirection().voice().has_value()) { int parsedVoice = api::VALUE_UNSPECIFIED; - if (utility::stringToInt(myDirection->editorialVoiceDirection().voice()->c_str(), parsedVoice)) + const std::string voiceText = *myDirection->editorialVoiceDirection().voice(); + if (utility::stringToInt(voiceText, parsedVoice)) { myOutDirectionData.voice = parsedVoice; } + else + { + report(api::Severity::warning, api::DiagnosticCode::invalidValue, + "direction voice \"" + voiceText + "\" is not a number; it is not read"); + } } } else if (myHarmony) @@ -750,6 +773,13 @@ void DirectionReader::parseOctaveShift(const core::DirectionType &directionType) amount = *octaveShift.size(); } + if (amount != 8 && amount != 15 && amount != 22) + { + const int used = amount >= 22 ? 22 : (amount > 8 ? 15 : 8); + report(api::Severity::warning, api::DiagnosticCode::valueAdjusted, + "octave-shift size " + std::to_string(amount) + " is not 8, 15 or 22; using " + std::to_string(used)); + } + // Per the MusicXML spec, octave-shift's type attribute describes the direction the // *written* notes are shifted from the true (sounding) pitch: an 8va, which sounds an // octave above what is written, is encoded as type="down" (notes are written below true @@ -1191,7 +1221,9 @@ void DirectionReader::parseHarmony(const core::Harmony &inHarmony, const core::H if (root.rootAlter().has_value()) { - chord.rootAlter = mx::utility::roundTo(root.rootAlter()->value().value().value()); + const double rawAlter = root.rootAlter()->value().value().value(); + chord.rootAlter = mx::utility::roundTo(rawAlter); + reportRounded("root-alter", rawAlter, chord.rootAlter); } break; } @@ -1208,7 +1240,9 @@ void DirectionReader::parseHarmony(const core::Harmony &inHarmony, const core::H if (numeral.numeralAlter().has_value()) { chord.hasNumeralAlter = true; - chord.numeralAlter = mx::utility::roundTo(numeral.numeralAlter()->value().value().value()); + const double rawAlter = numeral.numeralAlter()->value().value().value(); + chord.numeralAlter = mx::utility::roundTo(rawAlter); + reportRounded("numeral-alter", rawAlter, chord.numeralAlter); } if (numeral.numeralKey().has_value()) @@ -1294,7 +1328,9 @@ void DirectionReader::parseHarmony(const core::Harmony &inHarmony, const core::H if (bass.bassAlter().has_value()) { - chord.bassAlter = mx::utility::roundTo(bass.bassAlter()->value().value().value()); + const double rawAlter = bass.bassAlter()->value().value().value(); + chord.bassAlter = mx::utility::roundTo(rawAlter); + reportRounded("bass-alter", rawAlter, chord.bassAlter); } } @@ -1312,9 +1348,21 @@ void DirectionReader::parseHarmony(const core::Harmony &inHarmony, const core::H bool doAddExtension = true; const auto typeVal = degree.degreeType().value(); - const auto alter = mx::utility::roundTo(degree.degreeAlter().value().value().value()); + const double rawAlter = degree.degreeAlter().value().value().value(); + const auto alter = mx::utility::roundTo(rawAlter); const auto value = degree.degreeValue().value(); + if (alter < -2 || alter > 2) + { + report(api::Severity::warning, api::DiagnosticCode::valueAdjusted, + "degree-alter " + core::formatDouble(rawAlter) + " is out of range; using " + + std::to_string(alter < 0 ? -2 : 2)); + } + else + { + reportRounded("degree-alter", rawAlter, alter); + } + switch (typeVal.tag()) { case core::DegreeTypeValue::Tag::alter: @@ -1385,6 +1433,8 @@ void DirectionReader::parseHarmony(const core::Harmony &inHarmony, const core::H break; default: doAddExtension = false; + report(api::Severity::error, api::DiagnosticCode::droppedData, + "degree-value " + std::to_string(value) + " is not supported; the degree is not read"); break; } @@ -1439,14 +1489,28 @@ void DirectionReader::parseHarmony(const core::Harmony &inHarmony, const core::H if (frameNote.fingering().has_value()) { const auto fingeringText = frameNote.fingering()->value(); + std::size_t length = 0; try { - frameNoteData.fingering = std::stoi(fingeringText); + frameNoteData.fingering = std::stoi(fingeringText, &length); frameNoteData.isFingeringSpecified = true; } catch (...) { } + + // reported outside the try so a throwing diagnostic handler is not swallowed + if (!frameNoteData.isFingeringSpecified) + { + report(api::Severity::error, api::DiagnosticCode::droppedData, + "frame-note fingering \"" + fingeringText + "\" is not a number; it is not read"); + } + else if (length != fingeringText.size()) + { + report(api::Severity::warning, api::DiagnosticCode::valueAdjusted, + "frame-note fingering \"" + fingeringText + "\" is not a number; using " + + std::to_string(frameNoteData.fingering)); + } } if (frameNote.barre().has_value()) diff --git a/src/private/mx/impl/DirectionReader.h b/src/private/mx/impl/DirectionReader.h index 05b921e78..b28f26f3d 100644 --- a/src/private/mx/impl/DirectionReader.h +++ b/src/private/mx/impl/DirectionReader.h @@ -40,6 +40,8 @@ class DirectionReader private: mx::api::DirectionData initializeData(); + void report(api::Severity severity, api::DiagnosticCode code, std::string message) const; + void reportRounded(const char *name, double value, int rounded) const; void parseOffset(); void parsePlacement(); void parseSystemRelation(); diff --git a/src/private/mx/impl/LayoutFunctions.cpp b/src/private/mx/impl/LayoutFunctions.cpp index 5a37c56b1..3e8a260a9 100644 --- a/src/private/mx/impl/LayoutFunctions.cpp +++ b/src/private/mx/impl/LayoutFunctions.cpp @@ -509,6 +509,11 @@ void addAppearance(const core::ScoreHeaderGroup &inScoreHeaderGroup, api::Defaul { data.value = parsedOtherAppearanceValue.value(); } + else + { + diagnostics.report(api::Severity::warning, api::DiagnosticCode::invalidValue, api::Location{}, + "other-appearance \"" + oa.value() + "\" is not a number; using 0"); + } outDefaults.appearance.emplace_back(std::move(data)); } } diff --git a/src/private/mx/impl/MeasureReader.cpp b/src/private/mx/impl/MeasureReader.cpp index 6c48b69b7..80e2634ea 100644 --- a/src/private/mx/impl/MeasureReader.cpp +++ b/src/private/mx/impl/MeasureReader.cpp @@ -7,6 +7,7 @@ #include "mx/api/DirectionData.h" #include "mx/api/KeyData.h" #include "mx/api/NoteData.h" +#include "mx/core/Lexical.h" #include "mx/core/generated/Attributes.h" #include "mx/core/generated/AttributesChoice.h" #include "mx/core/generated/Backup.h" @@ -242,6 +243,10 @@ void MeasureReader::parseTimeSignature() const entry.second.id.reset(); } + // the api holds one time signature per measure for all staves and one per staff + bool isAllStavesTimeFound = false; + std::set staffTimesFound; + TimeReader timeReader{myPartwiseMeasure.musicData()}; for (const auto &found : timeReader.getTimeSignatures()) // isImplicit == false on each { @@ -250,11 +255,8 @@ void MeasureReader::parseTimeSignature() const // clamp an out-of-range staff number to "all staves", mirroring the keys pattern if (staffIndex != api::INDEX_UNSPECIFIED && staffIndex > myCurrentCursor.getNumStaves() - 1) { - api::Location location; - location.partIndex = myCurrentCursor.partIndex; - location.measureIndex = myCurrentCursor.measureIndex; - location.tickTimePosition = myCurrentCursor.tickTimePosition; - myDiagnostics.report(api::Severity::warning, api::DiagnosticCode::valueAdjusted, std::move(location), + myDiagnostics.report(api::Severity::warning, api::DiagnosticCode::valueAdjusted, + measureLocation(myCurrentCursor), "time signature staff number " + std::to_string(staffIndex + 1) + " is out of range; applying it to all staves"); staffIndex = api::INDEX_UNSPECIFIED; @@ -262,6 +264,14 @@ void MeasureReader::parseTimeSignature() const if (staffIndex == api::INDEX_UNSPECIFIED) { + if (isAllStavesTimeFound) + { + myDiagnostics.report( + api::Severity::error, api::DiagnosticCode::droppedData, measureLocation(myCurrentCursor), + "a measure has more than one time signature for all staves; only the last is read"); + } + isAllStavesTimeFound = true; + // a restated unscoped time governs all staves: it supersedes carried-forward per-staff // overrides (but not overrides stated explicitly in this same measure) timeSignature = found.timeChoice; @@ -272,6 +282,13 @@ void MeasureReader::parseTimeSignature() const } else { + if (!staffTimesFound.insert(staffIndex).second) + { + myDiagnostics.report(api::Severity::error, api::DiagnosticCode::droppedData, + measureLocation(myCurrentCursor), + "a measure has more than one time signature for staff " + + std::to_string(staffIndex + 1) + "; only the last is read"); + } staffTimeSignatures[staffIndex] = found.timeChoice; } } @@ -382,10 +399,9 @@ void MeasureReader::parseNote(const core::Note &inMxNote, const core::Note *next myCurrentCursor.isBackupInProgress = false; impl::NoteReader noteReader{inMxNote}; - impl::NoteFunctions noteFunc{inMxNote, myCurrentCursor, myDiagnostics}; - auto noteData = noteFunc.parseNote(); int noteDataStaffIndex = noteReader.getStaffNumber() - 1; + const bool isStaffNumberOutOfRange = noteReader.getIsStaffSpecified() && noteDataStaffIndex < 0; if (noteDataStaffIndex < 0) { @@ -417,12 +433,30 @@ void MeasureReader::parseNote(const core::Note &inMxNote, const core::Note *next { bucketStaffIndex = noteDataStaffIndex; } - else if (bucketStaffIndex != noteDataStaffIndex) + + myCurrentCursor.staffIndex = bucketStaffIndex; + + // the cursor has the note's staff before the note is parsed, so the note's reports carry it + impl::NoteFunctions noteFunc{inMxNote, myCurrentCursor, myDiagnostics}; + auto noteData = noteFunc.parseNote(); + + if (bucketStaffIndex != noteDataStaffIndex) { noteData.crossStaffIndex = noteDataStaffIndex; } - myCurrentCursor.staffIndex = bucketStaffIndex; + auto location = measureLocation(myCurrentCursor); + location.staffIndex = bucketStaffIndex; + + if (isStaffNumberOutOfRange) + { + myDiagnostics.report(api::Severity::warning, api::DiagnosticCode::valueAdjusted, location, + "note staff number " + std::to_string(noteReader.getStaffNumber()) + + " is out of range; using staff 1"); + } + + reportBeamRepairs(inMxNote, noteReader, location); + reportRoundedDuration("note", noteReader.getDurationValue(), location); bool isThisNotePartOfAChord = noteData.isChord || isNextNotePartOfAChord; noteData.isChord = isThisNotePartOfAChord; @@ -580,6 +614,8 @@ void MeasureReader::parseBackup(const core::Backup &inMxBackup) const // a chord cannot straddle a timeline jump myPreviousNoteBucketStaffIndex = -1; + reportRoundedDuration("backup", static_cast(inMxBackup.duration().value().value()), + measureLocation(myCurrentCursor)); const int backupAmount = myCurrentCursor.convertDurationToGlobalTickScale(inMxBackup.duration()); advanceTickTimePosition(-1 * backupAmount, "backup"); @@ -587,6 +623,9 @@ void MeasureReader::parseBackup(const core::Backup &inMxBackup) const { auto problemAmount = myCurrentCursor.tickTimePosition * -1; advanceTickTimePosition(problemAmount, "correct backup negative error"); + myDiagnostics.report(api::Severity::warning, api::DiagnosticCode::valueAdjusted, + measureLocation(myCurrentCursor), + "backup moves before the start of the measure; using the measure start"); } } @@ -599,6 +638,8 @@ void MeasureReader::parseForward(const core::Forward &inMxForward) const // forward from, so a source's / voice/staff is expected to not round-trip. // a chord cannot straddle a timeline jump myPreviousNoteBucketStaffIndex = -1; + reportRoundedDuration("forward", static_cast(inMxForward.duration().value().value()), + measureLocation(myCurrentCursor)); const int forwardAmount = myCurrentCursor.convertDurationToGlobalTickScale(inMxForward.duration()); advanceTickTimePosition(forwardAmount, "forward"); } @@ -620,6 +661,13 @@ void MeasureReader::parseDirection(const core::Direction &inDirection) const isStaffIndexInsane = staffIndex >= myOutMeasureData.staves.size(); + if (isStaffIndexSpecified && isStaffIndexInsane) + { + myDiagnostics.report( + api::Severity::warning, api::DiagnosticCode::valueAdjusted, measureLocation(myCurrentCursor), + "direction staff number " + std::to_string(*inDirection.staff()) + " is out of range; using staff 1"); + } + if (!isStaffIndexSpecified || isStaffIndexInsane) { staffIndex = 0; @@ -644,8 +692,20 @@ std::optional MeasureReader::parseAttributes(const core::Att if (inMxAttributes.divisions().has_value()) { - const auto newDivisionsValueDecimal = inMxAttributes.divisions()->value().value(); - myCurrentCursor.ticksPerQuarter = static_cast(std::ceil(newDivisionsValueDecimal - 0.5)); + const auto newDivisionsValueDecimal = static_cast(inMxAttributes.divisions()->value().value()); + + // divisions that round to 0 read as 1 rather than dividing durations by 0 + const int ticksPerQuarter = std::max(static_cast(std::ceil(newDivisionsValueDecimal - 0.5)), 1); + + if (static_cast(ticksPerQuarter) != newDivisionsValueDecimal) + { + myDiagnostics.report(api::Severity::warning, api::DiagnosticCode::valueAdjusted, + measureLocation(myCurrentCursor), + "divisions " + core::formatDouble(newDivisionsValueDecimal) + " rounded to " + + std::to_string(ticksPerQuarter)); + } + + myCurrentCursor.ticksPerQuarter = ticksPerQuarter; } // TODO - continue work on measure numbering and style etc @@ -708,6 +768,10 @@ std::optional MeasureReader::parseAttributes(const core::Att keyData.staffIndex = key.number()->value() - 1; if (keyData.staffIndex > myCurrentCursor.getNumStaves() - 1) { + myDiagnostics.report(api::Severity::warning, api::DiagnosticCode::valueAdjusted, + measureLocation(myCurrentCursor), + "key staff number " + std::to_string(keyData.staffIndex + 1) + + " is out of range; applying it to all staves"); keyData.staffIndex = api::INDEX_UNSPECIFIED; } } @@ -773,6 +837,10 @@ std::optional MeasureReader::parseAttributes(const core::Att transposeData.staffIndex = coreTranspose.number()->value() - 1; if (transposeData.staffIndex > myCurrentCursor.getNumStaves() - 1) { + myDiagnostics.report(api::Severity::warning, api::DiagnosticCode::valueAdjusted, + measureLocation(myCurrentCursor), + "transpose staff number " + std::to_string(transposeData.staffIndex + 1) + + " is out of range; applying it to all staves"); transposeData.staffIndex = api::INDEX_UNSPECIFIED; } } @@ -802,6 +870,13 @@ void MeasureReader::parseHarmony(const core::Harmony &inHarmony) const isStaffIndexInsane = staffIndex >= myOutMeasureData.staves.size(); + if (isStaffIndexSpecified && isStaffIndexInsane) + { + myDiagnostics.report( + api::Severity::warning, api::DiagnosticCode::valueAdjusted, measureLocation(myCurrentCursor), + "harmony staff number " + std::to_string(*inHarmony.staff()) + " is out of range; using staff 1"); + } + if (!isStaffIndexSpecified || isStaffIndexInsane) { staffIndex = 0; @@ -839,6 +914,8 @@ void MeasureReader::parseFiguredBass(const core::FiguredBass &inMxFiguredBass, c if (inMxFiguredBass.duration().has_value()) { + reportRoundedDuration("figured-bass", static_cast(inMxFiguredBass.duration()->value().value()), + measureLocation(myCurrentCursor)); figuredBass.durationTimeTicks = myCurrentCursor.convertDurationToGlobalTickScale(*inMxFiguredBass.duration()); } @@ -1032,6 +1109,9 @@ void MeasureReader::importStaffDetails(const core::Attributes &inMxAttributes) c if (staffIndex < 0 || staffIndex >= static_cast(myOutMeasureData.staves.size())) { + myDiagnostics.report( + api::Severity::error, api::DiagnosticCode::droppedData, measureLocation(myCurrentCursor), + "staff-details staff number " + std::to_string(staffIndex + 1) + " is out of range; it is not read"); continue; } @@ -1125,6 +1205,15 @@ void MeasureReader::importClef(const core::Clef &inClef) const const bool sourceHasNumber = inClef.number().has_value(); int celfStaffIndex = sourceHasNumber ? inClef.number()->value() - 1 : 0; + // PartReader counts clef numbers toward the staff count, so only a number below 1 is out of range + if (celfStaffIndex < 0) + { + myDiagnostics.report( + api::Severity::warning, api::DiagnosticCode::valueAdjusted, measureLocation(myCurrentCursor), + "clef staff number " + std::to_string(celfStaffIndex + 1) + " is out of range; using staff 1"); + celfStaffIndex = 0; + } + // Auto rule (see ClefData::writeStaffNumber): include the number unless this is a single-staff // part carrying the implied 1 (staff index 0). Record an explicit override only when the source // diverges from that rule, so the common case stays unspecified. @@ -1319,5 +1408,57 @@ void MeasureReader::advanceTickTimePosition(int amount, std::string reason) cons myHistory.push_back(record); // std::cout << record.reason << std::endl; } + +void MeasureReader::reportRoundedDuration(const char *element, double duration, api::Location location) const +{ + const double exactTicks = myCurrentCursor.convertDurationToExactGlobalTicks(duration); + const int ticks = myCurrentCursor.convertDurationToGlobalTickScale(duration); + + if (std::abs(exactTicks - static_cast(ticks)) > 1e-6) + { + myDiagnostics.report(api::Severity::warning, api::DiagnosticCode::valueAdjusted, std::move(location), + std::string{element} + " duration " + core::formatDouble(duration) + " is " + + core::formatDouble(exactTicks) + " ticks; using " + std::to_string(ticks)); + } +} + +void MeasureReader::reportBeamRepairs(const core::Note &inMxNote, const NoteReader ¬eReader, + const api::Location &location) const +{ + const auto beams = inMxNote.beam(); + std::set numbers; + int duplicateNumber = 0; + + for (const auto &beam : beams) + { + const int number = beam.number().has_value() ? beam.number()->value() : core::BeamLevel{}.value(); + if (!numbers.insert(number).second && duplicateNumber == 0) + { + duplicateNumber = number; + } + } + + if (duplicateNumber != 0) + { + const std::string duplicate = "a note has more than one beam number " + std::to_string(duplicateNumber); + const auto droppedCount = beams.size() - noteReader.getBeams().size(); + + if (droppedCount > 0) + { + myDiagnostics.report(api::Severity::error, api::DiagnosticCode::droppedData, location, + duplicate + "; " + std::to_string(droppedCount) + " of its beams are not read"); + } + else + { + myDiagnostics.report(api::Severity::warning, api::DiagnosticCode::valueAdjusted, location, + duplicate + "; renumbering its beams"); + } + } + else if (!numbers.empty() && *numbers.crbegin() != static_cast(numbers.size())) + { + myDiagnostics.report(api::Severity::warning, api::DiagnosticCode::valueAdjusted, location, + "a note's beam numbers do not count up from 1; renumbering its beams"); + } +} } // namespace impl } // namespace mx diff --git a/src/private/mx/impl/MeasureReader.h b/src/private/mx/impl/MeasureReader.h index e075fec2e..5e6f8f05a 100644 --- a/src/private/mx/impl/MeasureReader.h +++ b/src/private/mx/impl/MeasureReader.h @@ -37,6 +37,7 @@ class Clef; namespace impl { +class NoteReader; class MeasureReader { @@ -130,6 +131,9 @@ class MeasureReader bool isUserRequestedVoiceNumberConsistentAcrossAllVoices(const api::StaffData &staff) const; int getUserRequestedVoiceNumber(const api::VoiceData &voiceData) const; void advanceTickTimePosition(int amount, std::string reason) const; + void reportRoundedDuration(const char *element, double duration, api::Location location) const; + void reportBeamRepairs(const core::Note &inMxNote, const NoteReader ¬eReader, + const api::Location &location) const; }; } // namespace impl } // namespace mx diff --git a/src/private/mx/impl/OrnamentsFunctions.cpp b/src/private/mx/impl/OrnamentsFunctions.cpp index a779779f0..b8ba69628 100644 --- a/src/private/mx/impl/OrnamentsFunctions.cpp +++ b/src/private/mx/impl/OrnamentsFunctions.cpp @@ -213,18 +213,20 @@ void OrnamentsFunctions::parseOrnament(const core::OrnamentsGroupChoice &choiceO case 8: outMark.markType = api::MarkType::tremoloSingleEight; break; - default: + default: { // Three slashes, the customary one-note tremolo. Reached by a count of 0, which is a // legal but degenerate single-type tremolo that would draw nothing -- an unmeasured // tremolo is also written with a count of 0, but says so with type="unmeasured" and is // handled above. - // - // TODO: the remap is silent and lossy -- a count of 0 reads back as 3 and is written - // out that way. mx has no warning channel, so there is nowhere to report it. Log the - // downgrade here if a logging framework is ever added. outMark.markType = api::MarkType::tremoloSingleThree; + auto location = measureLocation(myCursor); + location.staffIndex = myCursor.staffIndex; + myDiagnostics.report(api::Severity::warning, api::DiagnosticCode::valueAdjusted, std::move(location), + "tremolo with " + std::to_string(tremolo.value().value()) + + " marks is not supported; using 3"); break; } + } break; } diff --git a/src/private/mx/impl/PartReader.cpp b/src/private/mx/impl/PartReader.cpp index 180cdd9ee..b52df6fac 100644 --- a/src/private/mx/impl/PartReader.cpp +++ b/src/private/mx/impl/PartReader.cpp @@ -74,10 +74,9 @@ void PartReader::readNameDisplay(const core::PartName &nameElement, const std::o } PartReader::PartReader(const core::ScorePart &inScorePart, const core::PartwisePart &inPartwisePartRef, - int globalTicksPerMeasure, const core::ScorePartwise &inScore, int inDivisionsValue, - DiagnosticsContext diagnostics) + int globalTicksPerMeasure, int partIndex, int inDivisionsValue, DiagnosticsContext diagnostics) : myPartwisePart{inPartwisePartRef}, myScorePart{inScorePart}, myNumStaves{-1}, myIsStavesElementPresent{false}, - myGlobalTicksPerMeasure{globalTicksPerMeasure}, myScore{inScore}, myPartIndex{-1}, + myGlobalTicksPerMeasure{globalTicksPerMeasure}, myPartIndex{partIndex}, myConstructedDivisionsValue{inDivisionsValue}, myDiagnostics{diagnostics} { const auto ppId = myPartwisePart.id().value(); @@ -86,9 +85,6 @@ PartReader::PartReader(const core::ScorePart &inScorePart, const core::PartwiseP { MX_THROW("the partwise-part id must match the score-part id"); } - const auto partIndex = findPartIndex(ppId); - MX_ASSERT(partIndex >= 0); - myPartIndex = partIndex; myNumStaves = calculateNumStaves(myIsStavesElementPresent); } @@ -148,6 +144,7 @@ int PartReader::calculateNumStaves(bool &outIsStavesElementPresent) const { outIsStavesElementPresent = false; int numStaves = 1; + int declaredStaves = 1; for (const auto &measure : myPartwisePart.measure()) { @@ -173,11 +170,19 @@ int PartReader::calculateNumStaves(bool &outIsStavesElementPresent) const { outIsStavesElementPresent = true; int temp = *attributes.staves(); + declaredStaves = std::max(declaredStaves, temp); if (temp > numStaves) { numStaves = temp; } } + for (const auto &clef : attributes.clef()) + { + if (clef.number().has_value() && clef.number()->value() > numStaves) + { + numStaves = clef.number()->value(); + } + } break; } case core::MusicDataChoice::Kind::harmony: { @@ -200,6 +205,16 @@ int PartReader::calculateNumStaves(bool &outIsStavesElementPresent) const } } + if (numStaves > declaredStaves) + { + api::Location location; + location.partIndex = myPartIndex; + myDiagnostics.report(api::Severity::warning, api::DiagnosticCode::valueAdjusted, std::move(location), + "staff number " + std::to_string(numStaves) + " is above the staff count " + + std::to_string(declaredStaves) + "; reading the part with " + + std::to_string(numStaves) + " staves"); + } + return numStaves; } @@ -277,6 +292,14 @@ void PartReader::parseScoreInstrument(const core::ScoreInstrument &scoreInstrume Converter c; myOutPartData.instrumentData.soundID = c.convert(instrSound.asSoundID()); } + else + { + api::Location location; + location.partIndex = myPartIndex; + myDiagnostics.report(api::Severity::error, api::DiagnosticCode::droppedData, std::move(location), + "instrument-sound \"" + instrSound.asString() + + "\" is not a known sound; it is not read"); + } } if (vidg.virtualInstrument().has_value()) @@ -367,31 +390,5 @@ void PartReader::parseMidiInstrument(const core::MIDIInstrument &inst) const } } -int PartReader::findPartIndex(const std::string &inPartId) const -{ - const auto &partList = myScore.scoreHeader().partList(); - const auto &firstPart = partList.scorePart(); - int index = 0; - - if (firstPart.id().value() == inPartId) - { - return index; - } - - ++index; - - for (const auto &p : partList.choice()) - { - if (p.isScorePart()) - { - if (p.asScorePart().id().value() == inPartId) - { - return index; - } - ++index; - } - } - return api::INDEX_UNSPECIFIED; -} } // namespace impl } // namespace mx diff --git a/src/private/mx/impl/PartReader.h b/src/private/mx/impl/PartReader.h index c3a5b7c12..9b713323e 100644 --- a/src/private/mx/impl/PartReader.h +++ b/src/private/mx/impl/PartReader.h @@ -32,8 +32,7 @@ class PartReader { public: PartReader(const core::ScorePart &inScorePart, const core::PartwisePart &inPartwisePartRef, - int globalTicksPerMeasure, const core::ScorePartwise &inScore, int inDivisionsValue, - DiagnosticsContext diagnostics = {}); + int globalTicksPerMeasure, int partIndex, int inDivisionsValue, DiagnosticsContext diagnostics = {}); api::PartData getPartData(); impl::MeasureCursor getCursor() const; @@ -48,7 +47,6 @@ class PartReader int myNumStaves; bool myIsStavesElementPresent; const int myGlobalTicksPerMeasure; - const core::ScorePartwise &myScore; int myPartIndex; const int myConstructedDivisionsValue; DiagnosticsContext myDiagnostics; @@ -67,7 +65,6 @@ class PartReader void parseVirtualInstrument(const core::VirtualInstrument &virtualInstrument) const; void parseMidiDeviceInstrumentGroup(const core::ScorePartMIDIGroup &grp) const; void parseMidiInstrument(const core::MIDIInstrument &inst) const; - int findPartIndex(const std::string &inPartId) const; template void updateNumStaves(const ELEMENT_TYPE &element, int &outNumStaves) const { diff --git a/src/private/mx/impl/ScoreConversions.cpp b/src/private/mx/impl/ScoreConversions.cpp index 0b289d68e..e43fc44a3 100644 --- a/src/private/mx/impl/ScoreConversions.cpp +++ b/src/private/mx/impl/ScoreConversions.cpp @@ -13,6 +13,8 @@ #include "mx/core/generated/TimewisePart.h" #include +#include +#include #include namespace mx @@ -123,6 +125,32 @@ core::ScorePartwise timewisePartwise(const core::ScoreTimewise &inScore, const D outScore.setScoreHeader(inScore.scoreHeader()); outScore.setVersion(inScore.version()); + // Only the first part in a measure with each score-part id is regrouped below. + const auto scoreParts = headerPartList(inScore.scoreHeader()); + int measureIndex = 0; + for (const auto &m : inScore.measure()) + { + std::set ids; + for (const auto &part : m.part()) + { + const auto &id = part.id().value(); + const auto isScorePart = [&id](const core::ScorePart *sp) { return sp->id().value() == id; }; + api::Location location; + location.measureIndex = measureIndex; + if (std::none_of(scoreParts.cbegin(), scoreParts.cend(), isScorePart)) + { + diagnostics.report(api::Severity::error, api::DiagnosticCode::droppedData, std::move(location), + "part \"" + id + "\" matches no score-part; it is not read"); + } + else if (!ids.insert(id).second) + { + diagnostics.report(api::Severity::error, api::DiagnosticCode::droppedData, std::move(location), + "a measure has more than one part \"" + id + "\"; only the first is read"); + } + } + ++measureIndex; + } + /* Create a PartwisePart for each part in the main list */ std::vector outParts; for (const auto *sp : headerPartList(inScore.scoreHeader())) diff --git a/src/private/mx/impl/ScoreReader.cpp b/src/private/mx/impl/ScoreReader.cpp index 3f62175c9..a3bba6d34 100644 --- a/src/private/mx/impl/ScoreReader.cpp +++ b/src/private/mx/impl/ScoreReader.cpp @@ -32,7 +32,6 @@ #include "mx/impl/Converter.h" #include "mx/impl/EncodingFunctions.h" #include "mx/impl/LayoutFunctions.h" -#include "mx/impl/LcmGcd.h" #include "mx/impl/NameDisplayFunctions.h" #include "mx/impl/PageTextFunctions.h" #include "mx/impl/PartReader.h" @@ -40,10 +39,29 @@ #include "mx/utility/StringToInt.h" #include "mx/utility/Throw.h" +#include +#include +#include +#include + namespace mx { namespace impl { +namespace +{ +std::string partGroupNumberText(int number) +{ + return number == api::NUMBER_LEVEL_UNSPECIFIED ? std::string{} : " number " + std::to_string(number); +} + +// A part-group without a number is number 1. +int effectivePartGroupNumber(int number) +{ + return number == api::NUMBER_LEVEL_UNSPECIFIED ? 1 : number; +} +} // namespace + ScoreReader::ScoreReader(const core::ScorePartwise &inScorePartwise, DiagnosticsContext diagnostics) : myScorePartwise{inScorePartwise}, myPartSet{inScorePartwise.part()}, myHeaderGroup{inScorePartwise.scoreHeader()}, myDiagnostics{diagnostics}, myMutex{}, myOutScoreData{}, myPartGroupStack{} @@ -74,32 +92,32 @@ ScoreReader::ReconciledParts ScoreReader::reconcileParts(const core::ScorePartwi const auto &partList = inScorePartwise.scoreHeader().partList(); const auto partwiseParts = inScorePartwise.part(); + // partIndex counts the parts that are read, so part groups index ScoreData::parts. + const auto reconcile = [&](const core::ScorePart &scorePart) { + const auto *partwisePart = findPartwisePart(scorePart, partwiseParts); + if (!partwisePart) + { + myDiagnostics.report(api::Severity::error, api::DiagnosticCode::droppedData, api::Location{}, + "score-part \"" + scorePart.id().value() + + "\" has no part with the same id; it is not read"); + return; + } + outParts.emplace_back(ReconciledPart{&scorePart, partwisePart}); + ++partIndex; + }; + for (const auto &preliminaryGroup : partList.partGroup()) { handlePartGroup(partIndex, preliminaryGroup); } - const auto *scorePart = &partList.scorePart(); - const auto *partwisePart = findPartwisePart(*scorePart, partwiseParts); - if (scorePart && partwisePart) - { - outParts.emplace_back(ReconciledPart{scorePart, partwisePart}); - } - - ++partIndex; + reconcile(partList.scorePart()); for (const auto &pgosp : partList.choice()) { if (pgosp.isScorePart()) { - scorePart = &pgosp.asScorePart(); - partwisePart = findPartwisePart(*scorePart, partwiseParts); - - if (scorePart && partwisePart) - { - outParts.emplace_back(ReconciledPart{scorePart, partwisePart}); - } - ++partIndex; + reconcile(pgosp.asScorePart()); } else if (pgosp.isPartGroup()) { @@ -107,6 +125,36 @@ ScoreReader::ReconciledParts ScoreReader::reconcileParts(const core::ScorePartwi } } + // the stack holds the most recent start first + for (auto iter = myPartGroupStack.crbegin(); iter != myPartGroupStack.crend(); ++iter) + { + api::Location location; + if (iter->firstPartIndex < partIndex) + { + location.partIndex = iter->firstPartIndex; + } + myDiagnostics.report(api::Severity::error, api::DiagnosticCode::droppedData, std::move(location), + "part-group start" + partGroupNumberText(iter->number) + " has no stop; it is not read"); + } + myPartGroupStack.clear(); + + for (const auto &part : partwiseParts) + { + const auto isPart = [&part](const ReconciledPart &reconciled) { return reconciled.second == ∂ }; + if (std::any_of(outParts.cbegin(), outParts.cend(), isPart)) + { + continue; + } + const auto isSameId = [&part](const ReconciledPart &reconciled) { + return reconciled.second->id().value() == part.id().value(); + }; + const bool isDuplicate = std::any_of(outParts.cbegin(), outParts.cend(), isSameId); + myDiagnostics.report(api::Severity::error, api::DiagnosticCode::droppedData, api::Location{}, + "part \"" + part.id().value() + "\"" + + (isDuplicate ? " has the same id as an earlier part; it is not read" + : " matches no score-part; it is not read")); + } + auto sortingCompare = [&](api::PartGroupData &a, api::PartGroupData b) { if (a.firstPartIndex < b.firstPartIndex) { @@ -270,7 +318,8 @@ api::ScoreData ScoreReader::getScoreData() const const auto &scorePart = *reconciledPart.first; const auto &partwisePart = *reconciledPart.second; const auto ticksPerQuarter = myOutScoreData.ticksPerQuarter; - PartReader reader{scorePart, partwisePart, ticksPerQuarter, myScorePartwise, divisionsValue, myDiagnostics}; + const auto partIndex = static_cast(myOutScoreData.parts.size()); + PartReader reader{scorePart, partwisePart, ticksPerQuarter, partIndex, divisionsValue, myDiagnostics}; myOutScoreData.parts.emplace_back(reader.getPartData()); const auto cursorReturn = reader.getCursor(); divisionsValue = cursorReturn.ticksPerQuarter; @@ -344,11 +393,15 @@ void ScoreReader::startPartGroup(int partIndex, const core::PartGroup &inPartGro void ScoreReader::stopPartGroup(int partIndex, const core::PartGroup &inPartGroup) const { + const int partGroupNumber = parsePartGroupNumber(inPartGroup); + if (myPartGroupStack.empty()) { + myDiagnostics.report(api::Severity::warning, api::DiagnosticCode::unmatchedSpanner, api::Location{}, + "part-group stop" + partGroupNumberText(partGroupNumber) + + " has no matching start; it is ignored"); return; } - const int partGroupNumber = parsePartGroupNumber(inPartGroup); api::PartGroupData grpData; @@ -359,12 +412,27 @@ void ScoreReader::stopPartGroup(int partIndex, const core::PartGroup &inPartGrou else { grpData = popMostRecentGroupFromStack(); + if (effectivePartGroupNumber(partGroupNumber) != effectivePartGroupNumber(grpData.number)) + { + api::Location location; + location.partIndex = grpData.firstPartIndex; + myDiagnostics.report(api::Severity::warning, api::DiagnosticCode::valueAdjusted, std::move(location), + "part-group stop" + partGroupNumberText(partGroupNumber) + + " matches no open group; closing the most recent part-group" + + partGroupNumberText(grpData.number)); + } } // A part-group stop arrives before the *next* score-part in the part-list walk, so the - // group's last member is the previously indexed part; partIndex==0 guards a malformed - // stop-before-any-part. - grpData.lastPartIndex = partIndex > 0 ? partIndex - 1 : partIndex; + // group's last member is the previously read part. + if (partIndex == grpData.firstPartIndex) + { + myDiagnostics.report(api::Severity::error, api::DiagnosticCode::droppedData, api::Location{}, + "part-group" + partGroupNumberText(grpData.number) + " contains no parts; it is not read"); + return; + } + + grpData.lastPartIndex = partIndex - 1; myOutScoreData.partGroups.emplace_back(std::move(grpData)); } @@ -416,10 +484,12 @@ int ScoreReader::parsePartGroupNumber(const core::PartGroup &inPartGroup) const if (inPartGroup.number().has_value()) { const auto str = *inPartGroup.number(); - bool isGroupNumberValid = utility::stringToInt(str, num); - - // TODO - support non-numeric group numbers if someone complains - MX_ASSERT(isGroupNumberValid); + if (!utility::stringToInt(str, num)) + { + num = api::NUMBER_LEVEL_UNSPECIFIED; + myDiagnostics.report(api::Severity::warning, api::DiagnosticCode::invalidValue, api::Location{}, + "part-group number \"" + str + "\" is not a number; reading it as unspecified"); + } } return num; @@ -496,6 +566,14 @@ void ScoreReader::scanForSystemInfo() const if (systemData.isUsed()) { auto &layout = myOutScoreData.layout[measureIndex]; + if (layout.system.isUsed()) + { + api::Location location; + location.partIndex = 0; + location.measureIndex = measureIndex; + myDiagnostics.report(api::Severity::error, api::DiagnosticCode::droppedData, std::move(location), + "a measure has more than one print with system layout; only the last is read"); + } layout.system = systemData; } } @@ -584,8 +662,15 @@ void ScoreReader::scanForPageInfo() const if (outPageData.isUsed()) { auto &layout = myOutScoreData.layout[measureIndex]; + if (layout.page.isUsed()) + { + api::Location location; + location.partIndex = 0; + location.measureIndex = measureIndex; + myDiagnostics.report(api::Severity::error, api::DiagnosticCode::droppedData, std::move(location), + "a measure has more than one print with page layout; only the last is read"); + } layout.page = outPageData; - // TODO break? } } // for each mdc ++measureIndex; @@ -617,16 +702,35 @@ int ScoreReader::findMaxDivisionsPerQuarter() const const auto tempDiv = attrs.divisions()->value().value(); // is a decimal in MusicXML but api ticksPerQuarter is an int: // round to nearest, halves down (ceil(x - 0.5)). + // Divisions that round to 0 read as 1, as MeasureReader reads them. const int tempDivInt = static_cast(std::ceil(tempDiv - 0.5)); - if (tempDivInt > 0) - { - foundDivisions.insert(tempDivInt); - } + foundDivisions.insert(std::max(tempDivInt, 1)); } } } - return mx::impl::leastCommonMultiple(foundDivisions); + if (foundDivisions.empty()) + { + return 0; + } + + // When the least common multiple does not fit an int, durations in parts with other divisions + // round to the largest divisions' ticks instead. + long long multiple = 1; + for (const int divisions : foundDivisions) + { + multiple = std::lcm(multiple, static_cast(divisions)); + if (multiple > std::numeric_limits::max()) + { + const int largest = *foundDivisions.crbegin(); + myDiagnostics.report(api::Severity::warning, api::DiagnosticCode::valueAdjusted, api::Location{}, + "the least common multiple of the divisions is too large; using the largest, " + + std::to_string(largest)); + return largest; + } + } + + return static_cast(multiple); } } // namespace impl diff --git a/src/private/mxtest/api/ReadDiagnosticsTest.cpp b/src/private/mxtest/api/ReadDiagnosticsTest.cpp new file mode 100644 index 000000000..5b11161ec --- /dev/null +++ b/src/private/mxtest/api/ReadDiagnosticsTest.cpp @@ -0,0 +1,247 @@ +// MusicXML Class Library +// Copyright (c) by Matthew James Briggs +// Distributed under the MIT License + +// getScore recoveries reported through Diagnostics. Each read produces the same +// score with or without a collection. + +#include "mxtest/control/CompileControl.h" +#ifdef MX_COMPILE_API_TESTS + +#include "cpul/cpulTestHarness.h" +#include "mx/api/Diagnostics.h" +#include "mx/api/MusicXml.h" +#include "mx/api/ScoreData.h" + +#include +#include + +using namespace mx::api; + +struct ReadDiagnosticsResult +{ + bool ok = false; + ScoreData score; + Diagnostics diagnostics; +}; + +inline ReadDiagnosticsResult readDiagnostics(const std::string &xml) +{ + ReadDiagnosticsResult out; + std::istringstream stream{xml}; + auto document = MusicXml::fromStream(stream); + REQUIRE(document.ok()); + auto score = getScore(document.value(), out.diagnostics); + out.ok = score.ok(); + if (score.ok()) + { + out.score = std::move(score).value(); + const auto silent = getScore(document.value()); + REQUIRE(silent.ok()); + CHECK(silent.value() == out.score); + } + return out; +} + +inline std::string readDiagnosticsPart(const std::string &id, const std::string &measureContent) +{ + return "" + measureContent + ""; +} + +inline std::string readDiagnosticsScorePart(const std::string &id) +{ + return "" + id + ""; +} + +inline std::string readDiagnosticsScore(const std::string &partList, const std::string &parts) +{ + return "" + partList + "" + parts + ""; +} + +inline std::string readDiagnosticsRest() +{ + return "1"; +} + +inline void readDiagnosticsCheck(const Diagnostic &diagnostic, DiagnosticCode code, const std::string &message) +{ + const Severity severity = code == DiagnosticCode::droppedData ? Severity::error : Severity::warning; + CHECK(severity == diagnostic.severity); + CHECK(code == diagnostic.code); + CHECK_EQUAL(message, diagnostic.message); +} + +TEST(unmatchedPartAndScorePartAreDropped, ReadDiagnostics) +{ + const std::string divisions = "1"; + const auto read = + readDiagnostics(readDiagnosticsScore(readDiagnosticsScorePart("P1") + readDiagnosticsScorePart("P2"), + readDiagnosticsPart("P1", divisions + readDiagnosticsRest()) + + readDiagnosticsPart("P3", divisions + readDiagnosticsRest()))); + REQUIRE(read.ok); + REQUIRE(read.score.parts.size() == 1); + REQUIRE(read.diagnostics.all().size() == 2); + readDiagnosticsCheck(read.diagnostics.all()[0], DiagnosticCode::droppedData, + "score-part \"P2\" has no part with the same id; it is not read"); + readDiagnosticsCheck(read.diagnostics.all()[1], DiagnosticCode::droppedData, + "part \"P3\" matches no score-part; it is not read"); +} + +T_END + +TEST(unbalancedPartGroupsAreReported, ReadDiagnostics) +{ + const auto read = readDiagnostics(readDiagnosticsScore( + "" + + readDiagnosticsScorePart("P1") + "" + + readDiagnosticsScorePart("P2") + "", + readDiagnosticsPart("P1", readDiagnosticsRest()) + readDiagnosticsPart("P2", readDiagnosticsRest()))); + REQUIRE(read.ok); + REQUIRE(read.score.partGroups.size() == 1); + CHECK_EQUAL(0, read.score.partGroups.front().firstPartIndex); + CHECK_EQUAL(1, read.score.partGroups.front().lastPartIndex); + REQUIRE(read.diagnostics.all().size() == 2); + readDiagnosticsCheck(read.diagnostics.all()[0], DiagnosticCode::unmatchedSpanner, + "part-group stop number 2 has no matching start; it is ignored"); + readDiagnosticsCheck(read.diagnostics.all()[1], DiagnosticCode::droppedData, + "part-group start number 3 has no stop; it is not read"); + CHECK_EQUAL(1, read.diagnostics.all()[1].location.partIndex); +} + +T_END + +TEST(nonNumericGroupNumberAndClefNumberAboveStavesRead, ReadDiagnostics) +{ + const auto read = readDiagnostics(readDiagnosticsScore( + "" + readDiagnosticsScorePart("P1") + + "", + readDiagnosticsPart("P1", "1F" + "4" + + readDiagnosticsRest()))); + REQUIRE(read.ok); + REQUIRE(read.score.partGroups.size() == 1); + CHECK_EQUAL(NUMBER_LEVEL_UNSPECIFIED, read.score.partGroups.front().number); + const auto &measure = read.score.parts.front().measures.front(); + REQUIRE(measure.staves.size() == 2); + CHECK(measure.staves[0].clefs.empty()); + CHECK_EQUAL(static_cast(1), measure.staves[1].clefs.size()); + + REQUIRE(read.diagnostics.all().size() == 3); + readDiagnosticsCheck(read.diagnostics.all()[0], DiagnosticCode::invalidValue, + "part-group number \"a\" is not a number; reading it as unspecified"); + readDiagnosticsCheck(read.diagnostics.all()[1], DiagnosticCode::invalidValue, + "part-group number \"a\" is not a number; reading it as unspecified"); + readDiagnosticsCheck(read.diagnostics.all()[2], DiagnosticCode::valueAdjusted, + "staff number 2 is above the staff count 1; reading the part with 2 staves"); + CHECK_EQUAL(0, read.diagnostics.all()[2].location.partIndex); +} + +T_END + +TEST(outOfRangeStaffAndClampedBackupHaveScorePositions, ReadDiagnostics) +{ + const auto read = readDiagnostics(readDiagnosticsScore( + readDiagnosticsScorePart("P1"), + readDiagnosticsPart("P1", "1C" + "410" + "2" + + readDiagnosticsRest()))); + REQUIRE(read.ok); + REQUIRE(read.diagnostics.all().size() == 2); + const auto &staff = read.diagnostics.all()[0]; + readDiagnosticsCheck(staff, DiagnosticCode::valueAdjusted, "note staff number 0 is out of range; using staff 1"); + CHECK_EQUAL(0, staff.location.partIndex); + CHECK_EQUAL(0, staff.location.measureIndex); + CHECK_EQUAL(0, staff.location.staffIndex); + CHECK_EQUAL(0, staff.location.tickTimePosition); + const auto &backup = read.diagnostics.all()[1]; + readDiagnosticsCheck(backup, DiagnosticCode::valueAdjusted, + "backup moves before the start of the measure; using the measure start"); + CHECK_EQUAL(0, backup.location.measureIndex); + CHECK_EQUAL(0, backup.location.tickTimePosition); +} + +T_END + +TEST(divisionsBelowOneHalfReadAsOne, ReadDiagnostics) +{ + const auto read = readDiagnostics(readDiagnosticsScore( + readDiagnosticsScorePart("P1"), + readDiagnosticsPart("P1", "0.25" + readDiagnosticsRest()))); + REQUIRE(read.ok); + CHECK_EQUAL(1, read.score.ticksPerQuarter); + REQUIRE(read.diagnostics.all().size() == 1); + readDiagnosticsCheck(read.diagnostics.all()[0], DiagnosticCode::valueAdjusted, "divisions 0.25 rounded to 1"); +} + +T_END + +TEST(overflowingDivisionsUseTheLargest, ReadDiagnostics) +{ + const auto part = [](const std::string &id, const std::string &divisions) { + return readDiagnosticsPart(id, "" + divisions + + "" + divisions + + ""); + }; + const auto read = readDiagnostics(readDiagnosticsScore( + readDiagnosticsScorePart("P1") + readDiagnosticsScorePart("P2"), part("P1", "65537") + part("P2", "65539"))); + REQUIRE(read.ok); + CHECK_EQUAL(65539, read.score.ticksPerQuarter); + REQUIRE(read.diagnostics.all().size() == 1); + readDiagnosticsCheck(read.diagnostics.all()[0], DiagnosticCode::valueAdjusted, + "the least common multiple of the divisions is too large; using the largest, 65539"); +} + +T_END + +TEST(timewisePartMatchingNoScorePartIsDropped, ReadDiagnostics) +{ + const auto read = + readDiagnostics("" + readDiagnosticsScorePart("P1") + + "" + readDiagnosticsRest() + + "" + readDiagnosticsRest() + ""); + REQUIRE(read.ok); + REQUIRE(read.diagnostics.all().size() == 1); + readDiagnosticsCheck(read.diagnostics.all()[0], DiagnosticCode::droppedData, + "part \"P9\" matches no score-part; it is not read"); + CHECK_EQUAL(0, read.diagnostics.all()[0].location.measureIndex); +} + +T_END + +TEST(snappedOctaveShiftAndTremoloAreReported, ReadDiagnostics) +{ + const auto read = readDiagnostics(readDiagnosticsScore( + readDiagnosticsScorePart("P1"), + readDiagnosticsPart("P1", "1" + "" + "C41" + "0" + ""))); + REQUIRE(read.ok); + REQUIRE(read.diagnostics.all().size() == 2); + readDiagnosticsCheck(read.diagnostics.all()[0], DiagnosticCode::valueAdjusted, + "octave-shift size 10 is not 8, 15 or 22; using 15"); + readDiagnosticsCheck(read.diagnostics.all()[1], DiagnosticCode::valueAdjusted, + "tremolo with 0 marks is not supported; using 3"); + CHECK_EQUAL(0, read.diagnostics.all()[1].location.staffIndex); +} + +T_END + +TEST(cleanDocumentReportsNothing, ReadDiagnostics) +{ + const auto read = readDiagnostics(readDiagnosticsScore( + "" + readDiagnosticsScorePart("P1") + readDiagnosticsScorePart("P2") + + "", + readDiagnosticsPart("P1", "22" + "22") + + readDiagnosticsPart("P2", "3" + "3"))); + REQUIRE(read.ok); + CHECK(read.diagnostics.all().empty()); +} + +T_END + +#endif From 32086ea169585e4dbb097c60086efb9d37bc09f4 Mon Sep 17 00:00:00 2001 From: Matthew James Briggs Date: Thu, 17 Sep 2026 18:29:52 +0200 Subject: [PATCH 7/8] feat: plumb write diagnostics and add a helper The write context now reaches the properties, direction and dynamics writers, the encoding and defaults functions and the timewise conversion. reportAdjusted reports when a core value built to write differs from the api value it came from. An Id remembers the text it scrubbed, so writing it can report the change. --- src/include/mx/api/Id.h | 5 +- src/private/mx/api/Id.cpp | 22 ++++- src/private/mx/api/IdAccess.h | 6 ++ src/private/mx/api/MusicXml.cpp | 6 +- src/private/mx/impl/DiagnosticsContext.h | 40 +++++++++ src/private/mx/impl/DirectionWriter.cpp | 8 +- src/private/mx/impl/DirectionWriter.h | 10 ++- src/private/mx/impl/DynamicsWriter.cpp | 11 +-- src/private/mx/impl/DynamicsWriter.h | 9 +- src/private/mx/impl/EncodingFunctions.cpp | 3 +- src/private/mx/impl/EncodingFunctions.h | 4 +- src/private/mx/impl/LayoutFunctions.cpp | 18 ++-- src/private/mx/impl/LayoutFunctions.h | 12 ++- src/private/mx/impl/MeasureWriter.cpp | 6 +- src/private/mx/impl/NotationsWriter.cpp | 2 +- src/private/mx/impl/PropertiesWriter.cpp | 6 +- src/private/mx/impl/PropertiesWriter.h | 7 +- src/private/mx/impl/ScoreConversions.cpp | 2 +- src/private/mx/impl/ScoreConversions.h | 2 +- src/private/mx/impl/ScoreWriter.cpp | 4 +- src/private/mx/impl/ScoreWriter.h | 6 ++ .../impl/WriteDiagnosticsHelperTest.cpp | 82 +++++++++++++++++++ 22 files changed, 222 insertions(+), 49 deletions(-) create mode 100644 src/private/mxtest/impl/WriteDiagnosticsHelperTest.cpp diff --git a/src/include/mx/api/Id.h b/src/include/mx/api/Id.h index c62124b02..7fdca905d 100644 --- a/src/include/mx/api/Id.h +++ b/src/include/mx/api/Id.h @@ -27,8 +27,9 @@ namespace api // becomes "X". Building the Id is the only place this happens: mx writes the id exactly as the Id // holds it. // -// Scrubbing is silent. To find out whether your text was already a legal id, compare it with the -// id you built: +// Writing the score with fromScore reports each id that building scrubbed, in the Diagnostics you +// pass it. To find out sooner whether your text was already a legal id, compare it with the id you +// built: // // const auto id = Id{myText}; // if (id.value() != myText) diff --git a/src/private/mx/api/Id.cpp b/src/private/mx/api/Id.cpp index 4d0fb41fe..dd1e08504 100644 --- a/src/private/mx/api/Id.cpp +++ b/src/private/mx/api/Id.cpp @@ -6,6 +6,8 @@ #include "mx/api/IdAccess.h" +#include +#include #include namespace mx @@ -25,11 +27,24 @@ class Id::Impl { } + explicit Impl(const std::string &text) + { + core::ValueParseOutcome outcome = core::ValueParseOutcome::valid; + token = core::Token::parse(text, outcome); + if (outcome != core::ValueParseOutcome::valid) + { + scrubbedText = text; + } + } + // What a moved-from Id is left holding. An Id always holds an Impl, so reading one that has // been moved from is harmless rather than undefined. static const std::shared_ptr &movedFrom(); core::Token token; + + // The text the Id was built from, when building it scrubbed the text. + std::optional scrubbedText; }; const std::shared_ptr &Id::Impl::movedFrom() @@ -38,7 +53,7 @@ const std::shared_ptr &Id::Impl::movedFrom() return value; } -Id::Id(std::string text) : myImpl{std::make_shared(core::Token{std::move(text)})} +Id::Id(std::string text) : myImpl{std::make_shared(text)} { } @@ -91,6 +106,11 @@ const core::Token &IdAccess::token(const Id &inId) return inId.myImpl->token; } +const std::optional &IdAccess::scrubbedText(const Id &inId) +{ + return inId.myImpl->scrubbedText; +} + Id IdAccess::make(core::Token inToken) { return Id{std::make_shared(std::move(inToken))}; diff --git a/src/private/mx/api/IdAccess.h b/src/private/mx/api/IdAccess.h index 004807ab0..713e6e98c 100644 --- a/src/private/mx/api/IdAccess.h +++ b/src/private/mx/api/IdAccess.h @@ -7,6 +7,9 @@ #include "mx/api/Id.h" #include "mx/core/Token.h" +#include +#include + namespace mx { namespace api @@ -20,6 +23,9 @@ struct IdAccess // The token an Id holds. Pass it straight to a core element's setID. static const core::Token &token(const Id &inId); + // The text an Id was built from, when building the Id scrubbed it; otherwise empty. + static const std::optional &scrubbedText(const Id &inId); + // An Id holding a token that mx::core already read from a file. static Id make(core::Token inToken); }; diff --git a/src/private/mx/api/MusicXml.cpp b/src/private/mx/api/MusicXml.cpp index 1c57741a9..3eb25f521 100644 --- a/src/private/mx/api/MusicXml.cpp +++ b/src/private/mx/api/MusicXml.cpp @@ -359,12 +359,14 @@ Result fromScore(const ScoreData &score, Diagnostics &diagnostics) { try { - impl::ScoreWriter writer{score, impl::DiagnosticsContext{diagnostics}}; + const impl::DiagnosticsContext context{diagnostics}; + impl::ScoreWriter writer{score, context}; core::ScorePartwise scorePartwise = writer.getScorePartwise(); if (score.musicXmlType == "timewise") { - return MusicXml{core::Document{impl::partwiseTimewise(scorePartwise)}, score.encoding.writeMxVersion}; + return MusicXml{core::Document{impl::partwiseTimewise(scorePartwise, context)}, + score.encoding.writeMxVersion}; } return MusicXml{core::Document{std::move(scorePartwise)}, score.encoding.writeMxVersion}; diff --git a/src/private/mx/impl/DiagnosticsContext.h b/src/private/mx/impl/DiagnosticsContext.h index d8dfd9501..96b442a1e 100644 --- a/src/private/mx/impl/DiagnosticsContext.h +++ b/src/private/mx/impl/DiagnosticsContext.h @@ -5,11 +5,14 @@ #pragma once #include "mx/api/Diagnostics.h" +#include "mx/core/Lexical.h" #include "mx/impl/MeasureCursor.h" +#include #include #include #include +#include #include namespace mx @@ -59,5 +62,42 @@ inline api::Location measureLocation(const MeasureCursor &cursor) location.tickTimePosition = cursor.tickTimePosition; return location; } + +// The part and measure of a cursor, for a report about a whole measure. +inline api::Location measureOnlyLocation(const MeasureCursor &cursor) +{ + api::Location location; + location.partIndex = cursor.partIndex; + location.measureIndex = cursor.measureIndex; + return location; +} + +inline std::string formatReportedNumber(double value) +{ + return core::formatDouble(value); +} + +inline std::string formatReportedNumber(long long value) +{ + return std::to_string(value); +} + +// Reports when a core value mx built to write differs from the api value it was built from, because +// the core type holds a narrower range. Pass the value read back from the built core value. +template +bool reportAdjusted(const DiagnosticsContext &diagnostics, api::Location location, const std::string &name, T apiValue, + T writtenValue) +{ + const bool isAdjusted = + std::is_floating_point_v ? std::abs(apiValue - writtenValue) > 1e-9 : apiValue != writtenValue; + if (isAdjusted) + { + using Format = std::conditional_t, double, long long>; + diagnostics.report(api::Severity::warning, api::DiagnosticCode::valueAdjusted, std::move(location), + name + " " + formatReportedNumber(static_cast(apiValue)) + + " is out of range; using " + formatReportedNumber(static_cast(writtenValue))); + } + return isAdjusted; +} } // namespace impl } // namespace mx diff --git a/src/private/mx/impl/DirectionWriter.cpp b/src/private/mx/impl/DirectionWriter.cpp index 3c3980dd5..69db68b71 100644 --- a/src/private/mx/impl/DirectionWriter.cpp +++ b/src/private/mx/impl/DirectionWriter.cpp @@ -145,10 +145,10 @@ static void applyBracketLineData(const api::LineData &lineData, core::Bracket &b } } -DirectionWriter::DirectionWriter(const api::DirectionData &inDirectionData, const Cursor &inCursor, - const SpannerResolver &inSpannerResolver) +DirectionWriter::DirectionWriter(const api::DirectionData &inDirectionData, const MeasureCursor &inCursor, + const SpannerResolver &inSpannerResolver, DiagnosticsContext diagnostics) : myDirectionData{inDirectionData}, myCursor{inCursor}, mySpannerResolver{inSpannerResolver}, myConverter{}, - myPlacements{}, myIsFirstDirectionTypeAdded{false} + myDiagnostics{std::move(diagnostics)}, myPlacements{}, myIsFirstDirectionTypeAdded{false} { } @@ -268,7 +268,7 @@ void DirectionWriter::emitMark(api::MarkData mark, core::Direction &direction) // if !isDirection( mark ) continue; if (isMarkDynamic(mark.markType)) { - DynamicsWriter dynamicsWriter{mark, myCursor}; + DynamicsWriter dynamicsWriter{mark, myCursor, myDiagnostics}; core::OneOrMore dynamicsSet{dynamicsWriter.getDynamics()}; core::DirectionType dt{}; dt.setChoice(core::DirectionTypeChoice::dynamics(dynamicsSet)); diff --git a/src/private/mx/impl/DirectionWriter.h b/src/private/mx/impl/DirectionWriter.h index a8c82913b..15b9f4422 100644 --- a/src/private/mx/impl/DirectionWriter.h +++ b/src/private/mx/impl/DirectionWriter.h @@ -10,7 +10,8 @@ #include "mx/core/generated/MusicDataChoice.h" #include "mx/core/generated/PercussionChoice.h" #include "mx/impl/Converter.h" -#include "mx/impl/Cursor.h" +#include "mx/impl/DiagnosticsContext.h" +#include "mx/impl/MeasureCursor.h" #include "mx/impl/SpannerResolver.h" #include @@ -26,8 +27,8 @@ class DirectionWriter // inSpannerResolver supplies the resolved 'number' for start/stop pairs such as wedge, // octave-shift, bracket, and dashes and stop semantics such as the size attribute of an // octave-shift (see SpannerResolver); it outlives this writer. - DirectionWriter(const api::DirectionData &inDirectionData, const Cursor &inCursor, - const SpannerResolver &inSpannerResolver); + DirectionWriter(const api::DirectionData &inDirectionData, const MeasureCursor &inCursor, + const SpannerResolver &inSpannerResolver, DiagnosticsContext diagnostics = {}); std::vector getDirectionLikeThings(); private: @@ -76,9 +77,10 @@ class DirectionWriter private: const api::DirectionData &myDirectionData; - const Cursor myCursor; + const MeasureCursor myCursor; const SpannerResolver &mySpannerResolver; const Converter myConverter; + DiagnosticsContext myDiagnostics; bool myIsFirstDirectionTypeAdded; std::set myPlacements; }; diff --git a/src/private/mx/impl/DynamicsWriter.cpp b/src/private/mx/impl/DynamicsWriter.cpp index 219022cd0..42dd1d264 100644 --- a/src/private/mx/impl/DynamicsWriter.cpp +++ b/src/private/mx/impl/DynamicsWriter.cpp @@ -89,15 +89,8 @@ core::DynamicsChoice dynamicsWriterMakeChoice(core::DynamicsChoice::Kind kind, c } } -DynamicsWriter::DynamicsWriter(const api::MarkData &inMark, impl::Cursor inCursor) - : myMarkData{inMark}, myCursor{inCursor}, myConverter{} -{ - MX_ASSERT(isMarkDynamic(inMark.markType)); -} - -DynamicsWriter::DynamicsWriter(const api::MarkData &inMark, impl::Cursor inCursor, - api::Placement /*directionPlacement*/) - : myMarkData{inMark}, myCursor{inCursor}, myConverter{} +DynamicsWriter::DynamicsWriter(const api::MarkData &inMark, MeasureCursor inCursor, DiagnosticsContext diagnostics) + : myMarkData{inMark}, myCursor{inCursor}, myConverter{}, myDiagnostics{std::move(diagnostics)} { MX_ASSERT(isMarkDynamic(inMark.markType)); } diff --git a/src/private/mx/impl/DynamicsWriter.h b/src/private/mx/impl/DynamicsWriter.h index f4d6ad621..abfa2ae77 100644 --- a/src/private/mx/impl/DynamicsWriter.h +++ b/src/private/mx/impl/DynamicsWriter.h @@ -7,7 +7,8 @@ #include "mx/api/MarkData.h" #include "mx/core/generated/Dynamics.h" #include "mx/impl/Converter.h" -#include "mx/impl/Cursor.h" +#include "mx/impl/DiagnosticsContext.h" +#include "mx/impl/MeasureCursor.h" namespace mx { @@ -16,14 +17,14 @@ namespace impl class DynamicsWriter { public: - DynamicsWriter(const api::MarkData &inMark, impl::Cursor inCursor); - DynamicsWriter(const api::MarkData &inMark, impl::Cursor inCursor, api::Placement directionPlacement); + DynamicsWriter(const api::MarkData &inMark, MeasureCursor inCursor, DiagnosticsContext diagnostics = {}); core::Dynamics getDynamics() const; private: const api::MarkData &myMarkData; - const impl::Cursor myCursor; + const MeasureCursor myCursor; const Converter myConverter; + DiagnosticsContext myDiagnostics; }; } // namespace impl } // namespace mx diff --git a/src/private/mx/impl/EncodingFunctions.cpp b/src/private/mx/impl/EncodingFunctions.cpp index cb8c065f3..ee30685cc 100644 --- a/src/private/mx/impl/EncodingFunctions.cpp +++ b/src/private/mx/impl/EncodingFunctions.cpp @@ -16,7 +16,8 @@ namespace mx { namespace impl { -void createEncoding(const api::EncodingData &inEncoding, core::ScoreHeaderGroup &header) +void createEncoding(const api::EncodingData &inEncoding, core::ScoreHeaderGroup &header, + const DiagnosticsContext &diagnostics) { // The old code mutated co-allocated identification/encoding through // shared pointers; under value semantics we build local copies and diff --git a/src/private/mx/impl/EncodingFunctions.h b/src/private/mx/impl/EncodingFunctions.h index 5bfa61f52..c2ed15210 100644 --- a/src/private/mx/impl/EncodingFunctions.h +++ b/src/private/mx/impl/EncodingFunctions.h @@ -7,12 +7,14 @@ #include "mx/api/EncodingData.h" #include "mx/core/generated/Encoding.h" #include "mx/core/generated/ScoreHeaderGroup.h" +#include "mx/impl/DiagnosticsContext.h" namespace mx { namespace impl { -void createEncoding(const api::EncodingData &inEncoding, core::ScoreHeaderGroup &header); +void createEncoding(const api::EncodingData &inEncoding, core::ScoreHeaderGroup &header, + const DiagnosticsContext &diagnostics); api::EncodingData createEncoding(const core::Encoding &inEncoding); } // namespace impl } // namespace mx diff --git a/src/private/mx/impl/LayoutFunctions.cpp b/src/private/mx/impl/LayoutFunctions.cpp index 3e8a260a9..99b097130 100644 --- a/src/private/mx/impl/LayoutFunctions.cpp +++ b/src/private/mx/impl/LayoutFunctions.cpp @@ -106,12 +106,13 @@ static core::PageLayout createPageLayout(const api::PageLayoutData &inPageLayout return outPageLayout; } -void addDefaultsData(const api::DefaultsData &inDefaults, core::ScoreHeaderGroup &outScoreHeaderGroup) +void addDefaultsData(const api::DefaultsData &inDefaults, core::ScoreHeaderGroup &outScoreHeaderGroup, + const DiagnosticsContext &diagnostics) { - addScaling(inDefaults, outScoreHeaderGroup); + addScaling(inDefaults, outScoreHeaderGroup, diagnostics); addPageLayout(inDefaults.pageLayout, outScoreHeaderGroup); - addSystemMargins(inDefaults, outScoreHeaderGroup); - addAppearance(inDefaults, outScoreHeaderGroup); + addSystemMargins(inDefaults, outScoreHeaderGroup, diagnostics); + addAppearance(inDefaults, outScoreHeaderGroup, diagnostics); addDefaultsFonts(inDefaults, outScoreHeaderGroup); } @@ -161,7 +162,8 @@ void addDefaultsFonts(const api::DefaultsData &inDefaults, core::ScoreHeaderGrou outScoreHeaderGroup.setDefaults(defaults); } -void addScaling(const api::DefaultsData &inDefaults, core::ScoreHeaderGroup &outScoreHeaderGroup) +void addScaling(const api::DefaultsData &inDefaults, core::ScoreHeaderGroup &outScoreHeaderGroup, + const DiagnosticsContext &diagnostics) { if (inDefaults.scalingMillimeters <= 0 && inDefaults.scalingTenths <= 0) { @@ -197,7 +199,8 @@ void addPageLayout(const api::PageLayoutData &inPageLayout, core::ScoreHeaderGro outScoreHeaderGroup.setDefaults(defaults); } -void addSystemMargins(const api::DefaultsData &inDefaults, core::ScoreHeaderGroup &outScoreHeaderGroup) +void addSystemMargins(const api::DefaultsData &inDefaults, core::ScoreHeaderGroup &outScoreHeaderGroup, + const DiagnosticsContext &diagnostics) { bool needsDefaults = false; auto defaults = outScoreHeaderGroup.defaults().value_or(core::Defaults{}); @@ -253,7 +256,8 @@ void addSystemMargins(const api::DefaultsData &inDefaults, core::ScoreHeaderGrou } } -void addAppearance(const api::DefaultsData &inDefaults, core::ScoreHeaderGroup &outScoreHeaderGroup) +void addAppearance(const api::DefaultsData &inDefaults, core::ScoreHeaderGroup &outScoreHeaderGroup, + const DiagnosticsContext &diagnostics) { if (inDefaults.appearance.empty()) { diff --git a/src/private/mx/impl/LayoutFunctions.h b/src/private/mx/impl/LayoutFunctions.h index 49e0da925..05b4f0dfa 100644 --- a/src/private/mx/impl/LayoutFunctions.h +++ b/src/private/mx/impl/LayoutFunctions.h @@ -14,11 +14,15 @@ namespace impl { //////////////////////////////////////////////////////////////////////////////////////////////////////////////// // api::DefaultsData -> core::ScoreHeaderGroup -void addDefaultsData(const api::DefaultsData &inDefaults, core::ScoreHeaderGroup &outScoreHeaderGroup); -void addScaling(const api::DefaultsData &inDefaults, core::ScoreHeaderGroup &outScoreHeaderGroup); +void addDefaultsData(const api::DefaultsData &inDefaults, core::ScoreHeaderGroup &outScoreHeaderGroup, + const DiagnosticsContext &diagnostics); +void addScaling(const api::DefaultsData &inDefaults, core::ScoreHeaderGroup &outScoreHeaderGroup, + const DiagnosticsContext &diagnostics); void addPageLayout(const api::PageLayoutData &inPageLayout, core::ScoreHeaderGroup &outScoreHeaderGroup); -void addSystemMargins(const api::DefaultsData &inDefaults, core::ScoreHeaderGroup &outScoreHeaderGroup); -void addAppearance(const api::DefaultsData &inDefaults, core::ScoreHeaderGroup &outScoreHeaderGroup); +void addSystemMargins(const api::DefaultsData &inDefaults, core::ScoreHeaderGroup &outScoreHeaderGroup, + const DiagnosticsContext &diagnostics); +void addAppearance(const api::DefaultsData &inDefaults, core::ScoreHeaderGroup &outScoreHeaderGroup, + const DiagnosticsContext &diagnostics); void addDefaultsFonts(const api::DefaultsData &inDefaults, core::ScoreHeaderGroup &outScoreHeaderGroup); //////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/private/mx/impl/MeasureWriter.cpp b/src/private/mx/impl/MeasureWriter.cpp index 1c2908b30..a56909419 100644 --- a/src/private/mx/impl/MeasureWriter.cpp +++ b/src/private/mx/impl/MeasureWriter.cpp @@ -60,7 +60,8 @@ MeasureWriter::MeasureWriter(const api::MeasureData &inMeasureData, const Measur core::PartwiseMeasure MeasureWriter::getPartwiseMeasure() { myOutMeasure = core::PartwiseMeasure{}; - myPropertiesWriter = std::unique_ptr{new PropertiesWriter{myOutMeasure}}; + myPropertiesWriter = std::unique_ptr{ + new PropertiesWriter{myOutMeasure, myScoreWriter.getDiagnostics(), measureOnlyLocation(myHistory.getCursor())}}; auto cursor = myHistory.getCursor(); cursor.reset(); myHistory = History{cursor}; @@ -824,7 +825,8 @@ void MeasureWriter::writeDirection(const api::DirectionData &inDirectionData) myPropertiesWriter->flushBuffer(); } - DirectionWriter directionWriter{inDirectionData, myHistory.getCursor(), myScoreWriter.getSpannerResolver()}; + DirectionWriter directionWriter{inDirectionData, myHistory.getCursor(), myScoreWriter.getSpannerResolver(), + myScoreWriter.getDiagnostics()}; auto mdcSet = directionWriter.getDirectionLikeThings(); for (const auto &mdc : mdcSet) { diff --git a/src/private/mx/impl/NotationsWriter.cpp b/src/private/mx/impl/NotationsWriter.cpp index aff3cd1c6..8faa6b021 100644 --- a/src/private/mx/impl/NotationsWriter.cpp +++ b/src/private/mx/impl/NotationsWriter.cpp @@ -317,7 +317,7 @@ core::Notations NotationsWriter::getNotations() const } else if (isMarkDynamic(mark.markType)) { - DynamicsWriter dynamicsWriter{mark, myCursor}; + DynamicsWriter dynamicsWriter{mark, myCursor, myScoreWriter.getDiagnostics()}; outNotations.addChoice(core::NotationsChoice::dynamics(dynamicsWriter.getDynamics())); } else if (isMarkFermata(mark.markType)) diff --git a/src/private/mx/impl/PropertiesWriter.cpp b/src/private/mx/impl/PropertiesWriter.cpp index 99bbe0a0d..89fb66b37 100644 --- a/src/private/mx/impl/PropertiesWriter.cpp +++ b/src/private/mx/impl/PropertiesWriter.cpp @@ -47,8 +47,10 @@ namespace mx namespace impl { -PropertiesWriter::PropertiesWriter(core::PartwiseMeasure &inPartwiseMeasure) - : myAttributes{}, myHasContent{false}, myPartwiseMeasure{inPartwiseMeasure} +PropertiesWriter::PropertiesWriter(core::PartwiseMeasure &inPartwiseMeasure, DiagnosticsContext diagnostics, + api::Location location) + : myAttributes{}, myHasContent{false}, myPartwiseMeasure{inPartwiseMeasure}, myDiagnostics{std::move(diagnostics)}, + myLocation{std::move(location)} { } diff --git a/src/private/mx/impl/PropertiesWriter.h b/src/private/mx/impl/PropertiesWriter.h index f37039804..bd4ca2f40 100644 --- a/src/private/mx/impl/PropertiesWriter.h +++ b/src/private/mx/impl/PropertiesWriter.h @@ -12,6 +12,7 @@ #include "mx/core/generated/Attributes.h" #include "mx/core/generated/Key.h" #include "mx/core/generated/PartwiseMeasure.h" +#include "mx/impl/DiagnosticsContext.h" namespace mx { @@ -29,7 +30,9 @@ namespace impl class PropertiesWriter { public: - explicit PropertiesWriter(core::PartwiseMeasure &inPartwiseMeasure); + // location is the part and measure written, for reports. + explicit PropertiesWriter(core::PartwiseMeasure &inPartwiseMeasure, DiagnosticsContext diagnostics = {}, + api::Location location = {}); // destroy and reallocate a new properties element // without inserting it into the measure @@ -68,6 +71,8 @@ class PropertiesWriter core::Attributes myAttributes; bool myHasContent; core::PartwiseMeasure &myPartwiseMeasure; + DiagnosticsContext myDiagnostics; + api::Location myLocation; }; } // namespace impl diff --git a/src/private/mx/impl/ScoreConversions.cpp b/src/private/mx/impl/ScoreConversions.cpp index e43fc44a3..7ff1721fa 100644 --- a/src/private/mx/impl/ScoreConversions.cpp +++ b/src/private/mx/impl/ScoreConversions.cpp @@ -42,7 +42,7 @@ std::vector headerPartList(const core::ScoreHeaderGroup } // namespace -core::ScoreTimewise partwiseTimewise(const core::ScorePartwise &inScore) +core::ScoreTimewise partwiseTimewise(const core::ScorePartwise &inScore, const DiagnosticsContext &diagnostics) { core::ScoreTimewise outScore; outScore.setScoreHeader(inScore.scoreHeader()); diff --git a/src/private/mx/impl/ScoreConversions.h b/src/private/mx/impl/ScoreConversions.h index ec756f705..76e3f2f0f 100644 --- a/src/private/mx/impl/ScoreConversions.h +++ b/src/private/mx/impl/ScoreConversions.h @@ -19,7 +19,7 @@ namespace impl // strictly safer, behavior-identical for this use. // Converts a 'score-partwise' to 'score-timewise'. -core::ScoreTimewise partwiseTimewise(const core::ScorePartwise &inScore); +core::ScoreTimewise partwiseTimewise(const core::ScorePartwise &inScore, const DiagnosticsContext &diagnostics); // Converts a 'score-timewise' to 'score-partwise'. core::ScorePartwise timewisePartwise(const core::ScoreTimewise &inScore, const DiagnosticsContext &diagnostics); diff --git a/src/private/mx/impl/ScoreWriter.cpp b/src/private/mx/impl/ScoreWriter.cpp index ea9f2f2c3..f21dacf52 100644 --- a/src/private/mx/impl/ScoreWriter.cpp +++ b/src/private/mx/impl/ScoreWriter.cpp @@ -157,8 +157,8 @@ core::ScorePartwise ScoreWriter::getScorePartwise() const header.setIdentification(identification); } - createEncoding(myScoreData.encoding, header); - addDefaultsData(myScoreData.defaults, header); + createEncoding(myScoreData.encoding, header, myDiagnostics); + addDefaultsData(myScoreData.defaults, header, myDiagnostics); createCredits(myScoreData, header); using PartPair = std::pair; diff --git a/src/private/mx/impl/ScoreWriter.h b/src/private/mx/impl/ScoreWriter.h index 8efa9a9e1..4a1637fbf 100644 --- a/src/private/mx/impl/ScoreWriter.h +++ b/src/private/mx/impl/ScoreWriter.h @@ -33,6 +33,12 @@ class ScoreWriter return myScoreData; } + // Where the writers report what they change, default or leave out. + inline const DiagnosticsContext &getDiagnostics() const + { + return myDiagnostics; + } + /// Finds the part in ScoreData and returns it. Throws if out-of-range. const api::PartData &getPart(int inPartIndex) const; diff --git a/src/private/mxtest/impl/WriteDiagnosticsHelperTest.cpp b/src/private/mxtest/impl/WriteDiagnosticsHelperTest.cpp new file mode 100644 index 000000000..aa1e3e164 --- /dev/null +++ b/src/private/mxtest/impl/WriteDiagnosticsHelperTest.cpp @@ -0,0 +1,82 @@ +// MusicXML Class Library +// Copyright (c) by Matthew James Briggs +// Distributed under the MIT License + +#include "mxtest/control/CompileControl.h" +#ifdef MX_COMPILE_IMPL_TESTS + +#include "cpul/cpulTestHarness.h" +#include "mx/api/Diagnostics.h" +#include "mx/api/IdAccess.h" +#include "mx/core/generated/MIDI16.h" +#include "mx/core/generated/Percent.h" +#include "mx/impl/DiagnosticsContext.h" + +using namespace mx; +using namespace mx::impl; + +TEST(reportAdjustedReportsAClampedInteger, WriteDiagnosticsHelper) +{ + api::Diagnostics diagnostics; + const DiagnosticsContext context{diagnostics}; + api::Location location; + location.partIndex = 2; + + const core::MIDI16 channel{17}; + CHECK(reportAdjusted(context, location, "midi-channel", 17, channel.value())); + + REQUIRE(diagnostics.all().size() == 1); + const auto &diagnostic = diagnostics.all().front(); + CHECK(api::Severity::warning == diagnostic.severity); + CHECK(api::DiagnosticCode::valueAdjusted == diagnostic.code); + CHECK_EQUAL(2, diagnostic.location.partIndex); + CHECK_EQUAL(std::string{"midi-channel 17 is out of range; using 16"}, diagnostic.message); +} + +T_END + +TEST(reportAdjustedReportsAClampedDecimal, WriteDiagnosticsHelper) +{ + api::Diagnostics diagnostics; + const DiagnosticsContext context{diagnostics}; + + const core::Percent volume{core::Decimal{100.5}}; + CHECK(reportAdjusted(context, api::Location{}, "volume", 100.5, volume.value().value())); + + REQUIRE(diagnostics.all().size() == 1); + CHECK_EQUAL(std::string{"volume 100.5 is out of range; using 100"}, diagnostics.all().front().message); +} + +T_END + +TEST(reportAdjustedIsSilentForAnUnchangedValue, WriteDiagnosticsHelper) +{ + api::Diagnostics diagnostics; + const DiagnosticsContext context{diagnostics}; + + const core::MIDI16 channel{16}; + CHECK(!reportAdjusted(context, api::Location{}, "midi-channel", 16, channel.value())); + CHECK(!reportAdjusted(context, api::Location{}, "volume", 50.25, 50.25)); + CHECK(diagnostics.all().empty()); +} + +T_END + +TEST(idRemembersTheTextItScrubbed, WriteDiagnosticsHelper) +{ + const api::Id scrubbed{"1 note"}; + CHECK_EQUAL(std::string{"note"}, scrubbed.value()); + REQUIRE(api::IdAccess::scrubbedText(scrubbed).has_value()); + CHECK_EQUAL(std::string{"1 note"}, *api::IdAccess::scrubbedText(scrubbed)); + + const api::Id copy = scrubbed; + REQUIRE(api::IdAccess::scrubbedText(copy).has_value()); + CHECK_EQUAL(std::string{"1 note"}, *api::IdAccess::scrubbedText(copy)); + + CHECK(!api::IdAccess::scrubbedText(api::Id{"note"}).has_value()); + CHECK(!api::IdAccess::scrubbedText(api::IdAccess::make(core::Token{"a b"})).has_value()); +} + +T_END + +#endif From d46c47ad76dfa0420232393083472dc4efb6bf1f Mon Sep 17 00:00:00 2001 From: Matthew James Briggs Date: Thu, 17 Sep 2026 18:44:54 +0200 Subject: [PATCH 8/8] feat: report write recoveries fromScore now reports scrubbed ids, clamped values, defaulted required values, dropped marks, curves, keys and part groups, duplicate part ids and unmatched spanners. --- src/private/mx/impl/CurveFunctions.h | 21 +- src/private/mx/impl/DiagnosticsContext.h | 37 +++- src/private/mx/impl/DirectionWriter.cpp | 108 ++++++++--- src/private/mx/impl/EncodingFunctions.cpp | 9 + src/private/mx/impl/GlissandoFunctions.h | 10 +- src/private/mx/impl/IdFunctions.h | 14 +- src/private/mx/impl/LayoutFunctions.cpp | 40 ++-- src/private/mx/impl/MeasureWriter.cpp | 43 +++- src/private/mx/impl/MeasureWriter.h | 3 + src/private/mx/impl/NotationsWriter.cpp | 112 ++++++++--- src/private/mx/impl/NoteWriter.cpp | 64 +++++- src/private/mx/impl/NoteWriter.h | 2 + src/private/mx/impl/PartWriter.cpp | 60 +++++- src/private/mx/impl/PartWriter.h | 7 + src/private/mx/impl/PropertiesWriter.cpp | 32 +-- src/private/mx/impl/PropertiesWriter.h | 2 +- src/private/mx/impl/ScoreConversions.cpp | 14 ++ src/private/mx/impl/ScoreWriter.cpp | 15 ++ src/private/mx/impl/SoundFunctions.cpp | 5 +- src/private/mx/impl/SoundFunctions.h | 4 +- src/private/mx/impl/SpannerFunctions.h | 10 +- src/private/mx/impl/SpannerResolver.cpp | 75 +++++++ .../mxtest/api/WriteDiagnosticsTest.cpp | 183 ++++++++++++++++++ 23 files changed, 734 insertions(+), 136 deletions(-) create mode 100644 src/private/mxtest/api/WriteDiagnosticsTest.cpp diff --git a/src/private/mx/impl/CurveFunctions.h b/src/private/mx/impl/CurveFunctions.h index 7e68f0aa9..2f27fecc7 100644 --- a/src/private/mx/impl/CurveFunctions.h +++ b/src/private/mx/impl/CurveFunctions.h @@ -168,11 +168,12 @@ template api::CurveStop parseCurveStop(const // never look at the SpannerNumber directly. template void writeAttributesFromCurveStart(const api::CurveStart inCurve, ATTRIBUTES_TYPE &outAttributes, - const std::optional &inResolvedNumber) + const std::optional &inResolvedNumber, + const DiagnosticsContext &diagnostics = {}, const api::Location &location = {}) { using CurveTypeAttribute = std::decay_t; outAttributes.setType(CurveTypeAttribute::start()); - impl::setId(inCurve.id, outAttributes); + impl::setId(inCurve.id, outAttributes, diagnostics, location); impl::setAttributesFromPositionData(inCurve.curvePoints.positionData, outAttributes); impl::setAttributesFromLineData(inCurve.lineData, outAttributes); @@ -212,11 +213,12 @@ void writeAttributesFromCurveStart(const api::CurveStart inCurve, ATTRIBUTES_TYP template void writeAttributesFromCurveContinue(const api::CurveContinue inCurve, ATTRIBUTES_TYPE &outAttributes, - const std::optional &inResolvedNumber) + const std::optional &inResolvedNumber, + const DiagnosticsContext &diagnostics = {}, const api::Location &location = {}) { using CurveTypeAttribute = std::decay_t; outAttributes.setType(CurveTypeAttribute::continue_()); - impl::setId(inCurve.id, outAttributes); + impl::setId(inCurve.id, outAttributes, diagnostics, location); impl::setAttributesFromPositionData(inCurve.curvePoints.positionData, outAttributes); if (inResolvedNumber.has_value()) @@ -258,11 +260,12 @@ void writeAttributesFromCurveContinue(const api::CurveContinue inCurve, ATTRIBUT template void writeAttributesFromCurveStop(const api::CurveStop inCurve, ATTRIBUTES_TYPE &outAttributes, - const std::optional &inResolvedNumber) + const std::optional &inResolvedNumber, + const DiagnosticsContext &diagnostics = {}, const api::Location &location = {}) { using CurveTypeAttribute = std::decay_t; outAttributes.setType(CurveTypeAttribute::stop()); - impl::setId(inCurve.id, outAttributes); + impl::setId(inCurve.id, outAttributes, diagnostics, location); impl::setAttributesFromPositionData(inCurve.curvePoints.positionData, outAttributes); if (inResolvedNumber.has_value()) @@ -289,11 +292,13 @@ void writeAttributesFromCurveStop(const api::CurveStop inCurve, ATTRIBUTES_TYPE // Emits a lone from an api::TieLetRing, carrying its // shared visual attributes (position, orientation, color). -inline void writeAttributesFromTieLetRing(const api::TieLetRing &inTie, core::Tied &outTied) +inline void writeAttributesFromTieLetRing(const api::TieLetRing &inTie, core::Tied &outTied, + const DiagnosticsContext &diagnostics = {}, + const api::Location &location = {}) { outTied.setType(core::TiedType::letRing()); impl::setAttributesFromPositionData(inTie.positionData, outTied); - impl::setId(inTie.id, outTied); + impl::setId(inTie.id, outTied, diagnostics, location); if (inTie.isColorSpecified) { diff --git a/src/private/mx/impl/DiagnosticsContext.h b/src/private/mx/impl/DiagnosticsContext.h index 96b442a1e..6f66ec295 100644 --- a/src/private/mx/impl/DiagnosticsContext.h +++ b/src/private/mx/impl/DiagnosticsContext.h @@ -38,21 +38,30 @@ class DiagnosticsContext } void report(api::Severity severity, api::DiagnosticCode code, const MeasureCursor &cursor, - std::string message) const - { - api::Location location; - location.partIndex = cursor.partIndex; - location.measureIndex = cursor.measureIndex; - location.staffIndex = cursor.staffIndex; - location.voiceIndex = cursor.voiceIndex; - location.tickTimePosition = cursor.tickTimePosition; - report(severity, code, std::move(location), std::move(message)); - } + std::string message) const; private: std::shared_ptr> myDiagnostics; }; +// The full score position of a cursor. +inline api::Location cursorLocation(const MeasureCursor &cursor) +{ + api::Location location; + location.partIndex = cursor.partIndex; + location.measureIndex = cursor.measureIndex; + location.staffIndex = cursor.staffIndex; + location.voiceIndex = cursor.voiceIndex; + location.tickTimePosition = cursor.tickTimePosition; + return location; +} + +inline void DiagnosticsContext::report(api::Severity severity, api::DiagnosticCode code, const MeasureCursor &cursor, + std::string message) const +{ + report(severity, code, cursorLocation(cursor), std::move(message)); +} + // The part, measure and tick of a cursor, for a report that is not about one staff or voice. inline api::Location measureLocation(const MeasureCursor &cursor) { @@ -72,6 +81,14 @@ inline api::Location measureOnlyLocation(const MeasureCursor &cursor) return location; } +// The location of a report about a whole part. +inline api::Location partLocation(int partIndex) +{ + api::Location location; + location.partIndex = partIndex; + return location; +} + inline std::string formatReportedNumber(double value) { return core::formatDouble(value); diff --git a/src/private/mx/impl/DirectionWriter.cpp b/src/private/mx/impl/DirectionWriter.cpp index 69db68b71..cbab43f73 100644 --- a/src/private/mx/impl/DirectionWriter.cpp +++ b/src/private/mx/impl/DirectionWriter.cpp @@ -172,7 +172,7 @@ std::vector DirectionWriter::getDirectionLikeThings() { direction.setDirective(myConverter.convert(myDirectionData.directive)); } - setId(myDirectionData.id, direction); + setId(myDirectionData.id, direction, myDiagnostics, cursorLocation(myCursor)); if (myDirectionData.isStaffValueSpecified || myCursor.staffIndex != 0) { @@ -225,7 +225,7 @@ std::vector DirectionWriter::getDirectionLikeThings() if (myDirectionData.isSoundDataSpecified && myDirectionData.soundData.isSpecified()) { core::Sound sound{}; - writeSoundData(myDirectionData.soundData, sound); + writeSoundData(myDirectionData.soundData, sound, myDiagnostics, cursorLocation(myCursor)); direction.setSound(std::move(sound)); } @@ -235,7 +235,7 @@ std::vector DirectionWriter::getDirectionLikeThings() { // The direction has no other content; emit a standalone element. core::Sound sound{}; - writeSoundData(myDirectionData.soundData, sound); + writeSoundData(myDirectionData.soundData, sound, myDiagnostics, cursorLocation(myCursor)); if (offset != 0) { @@ -301,6 +301,12 @@ void DirectionWriter::emitMark(api::MarkData mark, core::Direction &direction) dt.setChoice(core::DirectionTypeChoice::pedal(pedal)); addDirectionType(std::move(dt), direction); } + + if (!isMarkDynamic(mark.markType) && !isMarkPedal(mark.markType)) + { + myDiagnostics.report(api::Severity::error, api::DiagnosticCode::droppedData, cursorLocation(myCursor), + "a direction mark that is not a dynamic or pedal is not written"); + } } core::PedalType corePedalType(api::PedalLineKind kind) @@ -339,7 +345,7 @@ void DirectionWriter::emitPedal(const api::PedalLineData &item, core::Direction pedal.setType(corePedalType(item.kind)); pedal.setLine(core::YesNo::yes()); setAttributesFromPositionData(item.positionData, pedal); - setId(item.id, pedal); + setId(item.id, pedal, myDiagnostics, cursorLocation(myCursor)); core::DirectionType dt{}; dt.setChoice(core::DirectionTypeChoice::pedal(pedal)); addDirectionType(std::move(dt), direction); @@ -361,7 +367,7 @@ void DirectionWriter::emitWedgeStop(const api::WedgeStop &wedgeStop, const void wedge.setSpread(core::Tenths{core::Decimal{static_cast(wedgeStop.spread)}}); } setAttributesFromPositionData(wedgeStop.positionData, wedge); - setId(wedgeStop.id, wedge); + setId(wedgeStop.id, wedge, myDiagnostics, cursorLocation(myCursor)); core::DirectionType dt{}; dt.setChoice(core::DirectionTypeChoice::wedge(wedge)); addDirectionType(std::move(dt), direction); @@ -376,6 +382,11 @@ void DirectionWriter::emitWedgeStart(const api::WedgeStart &wedgeStart, const vo { wedge.setType(myConverter.convert(wedgeStart.wedgeType)); } + else + { + myDiagnostics.report(api::Severity::warning, api::DiagnosticCode::missingValueDefaulted, + cursorLocation(myCursor), "wedge type is unspecified; using crescendo"); + } const auto number = mySpannerResolver.emittedNumber(wedgeStart.number, inIdentity); if (number.has_value()) @@ -394,7 +405,7 @@ void DirectionWriter::emitWedgeStart(const api::WedgeStart &wedgeStart, const vo { setAttributesFromColorData(wedgeStart.colorData, wedge); } - setId(wedgeStart.id, wedge); + setId(wedgeStart.id, wedge, myDiagnostics, cursorLocation(myCursor)); core::DirectionType dt{}; dt.setChoice(core::DirectionTypeChoice::wedge(wedge)); addDirectionType(std::move(dt), direction); @@ -405,7 +416,8 @@ void DirectionWriter::emitOttavaStop(const api::OttavaStop &ottavaStop, const vo { core::OctaveShift os{}; setAttributesFromSpannerStop(ottavaStop.spannerStop, os, - mySpannerResolver.emittedNumber(ottavaStop.spannerStop.number, inIdentity)); + mySpannerResolver.emittedNumber(ottavaStop.spannerStop.number, inIdentity), + myDiagnostics, cursorLocation(myCursor)); os.setType(core::UpDownStopContinue::stop()); // The stop has no size of its own; it inherits the size of the start it closes, which the @@ -429,7 +441,7 @@ void DirectionWriter::emitOttavaStart(const api::OttavaStart &ottavaStart, const impl::setAttributesFromPositionData(ottavaStart.spannerStart.positionData, os); impl::setAttributesFromPrintData(ottavaStart.spannerStart.printData, os); impl::setAttributesFromLineData(ottavaStart.spannerStart.lineData, os); - impl::setId(ottavaStart.spannerStart.id, os); + impl::setId(ottavaStart.spannerStart.id, os, myDiagnostics, cursorLocation(myCursor)); const auto number = mySpannerResolver.emittedNumber(ottavaStart.spannerStart.number, inIdentity); if (number.has_value()) @@ -454,6 +466,8 @@ void DirectionWriter::emitOttavaStart(const api::OttavaStart &ottavaStart, const break; default: + myDiagnostics.report(api::Severity::warning, api::DiagnosticCode::missingValueDefaulted, + cursorLocation(myCursor), "octave-shift type is unspecified; using up"); break; } @@ -475,7 +489,8 @@ void DirectionWriter::emitBracketStart(const api::SpannerStart &item, const void core::Direction &direction) { core::Bracket bracket{}; - setAttributesFromSpannerStart(item, bracket, mySpannerResolver.emittedNumber(item.number, inIdentity)); + setAttributesFromSpannerStart(item, bracket, mySpannerResolver.emittedNumber(item.number, inIdentity), + myDiagnostics, cursorLocation(myCursor)); bracket.setType(core::StartStopContinue::start()); setAttributesFromPositionData(item.positionData, bracket); setAttributesFromPrintData(item.printData, bracket); @@ -488,7 +503,8 @@ void DirectionWriter::emitBracketStart(const api::SpannerStart &item, const void void DirectionWriter::emitBracketStop(const api::SpannerStop &item, const void *inIdentity, core::Direction &direction) { core::Bracket bracket{}; - setAttributesFromSpannerStop(item, bracket, mySpannerResolver.emittedNumber(item.number, inIdentity)); + setAttributesFromSpannerStop(item, bracket, mySpannerResolver.emittedNumber(item.number, inIdentity), myDiagnostics, + cursorLocation(myCursor)); bracket.setType(core::StartStopContinue::stop()); applyBracketLineData(item.lineData, bracket, myConverter); core::DirectionType dt{}; @@ -499,7 +515,8 @@ void DirectionWriter::emitBracketStop(const api::SpannerStop &item, const void * void DirectionWriter::emitDashesStart(const api::SpannerStart &item, const void *inIdentity, core::Direction &direction) { core::Dashes dashes{}; - setAttributesFromSpannerStart(item, dashes, mySpannerResolver.emittedNumber(item.number, inIdentity)); + setAttributesFromSpannerStart(item, dashes, mySpannerResolver.emittedNumber(item.number, inIdentity), myDiagnostics, + cursorLocation(myCursor)); dashes.setType(core::StartStopContinue::start()); setAttributesFromPositionData(item.positionData, dashes); setAttributesFromPrintData(item.printData, dashes); @@ -512,7 +529,8 @@ void DirectionWriter::emitDashesStart(const api::SpannerStart &item, const void void DirectionWriter::emitDashesStop(const api::SpannerStop &item, const void *inIdentity, core::Direction &direction) { core::Dashes dashes{}; - setAttributesFromSpannerStop(item, dashes, mySpannerResolver.emittedNumber(item.number, inIdentity)); + setAttributesFromSpannerStop(item, dashes, mySpannerResolver.emittedNumber(item.number, inIdentity), myDiagnostics, + cursorLocation(myCursor)); dashes.setType(core::StartStopContinue::stop()); core::DirectionType dt{}; dt.setChoice(core::DirectionTypeChoice::dashes(dashes)); @@ -696,7 +714,7 @@ void DirectionWriter::emitTempo(const api::TempoData &tempo, core::Direction &di { setAttributesFromColorData(*tempo.color, metronome); } - setId(tempo.id, metronome); + setId(tempo.id, metronome, myDiagnostics, cursorLocation(myCursor)); if (tempo.justify != api::HorizontalAlignment::unspecified) { metronome.setJustify(myConverter.convert(tempo.justify)); @@ -750,7 +768,7 @@ void DirectionWriter::emitWordsRun(const std::vector &inRun, c { outSymbol.setJustify(myConverter.convert(symbolData.justify)); } - setId(symbolData.id, outSymbol); + setId(symbolData.id, outSymbol, myDiagnostics, cursorLocation(myCursor)); choiceItem = core::DirectionTypeChoiceChoice::symbol(std::move(outSymbol)); } else @@ -772,7 +790,7 @@ void DirectionWriter::emitWordsRun(const std::vector &inRun, c { outWords.setJustify(myConverter.convert(wordsData.justify)); } - setId(wordsData.id, outWords); + setId(wordsData.id, outWords, myDiagnostics, cursorLocation(myCursor)); choiceItem = core::DirectionTypeChoiceChoice::words(std::move(outWords)); } @@ -805,7 +823,7 @@ void DirectionWriter::emitSegno(const api::SegnoData &item, core::Direction &dir { segno.setSmufl(core::SmuflSegnoGlyphName::parse(item.smufl)); } - setId(item.id, segno); + setId(item.id, segno, myDiagnostics, cursorLocation(myCursor)); core::DirectionType dt{}; dt.setChoice(core::DirectionTypeChoice::segno(core::OneOrMore{std::move(segno)})); addDirectionType(std::move(dt), direction); @@ -824,7 +842,7 @@ void DirectionWriter::emitCoda(const api::CodaData &item, core::Direction &direc { coda.setSmufl(core::SmuflCodaGlyphName::parse(item.smufl)); } - setId(item.id, coda); + setId(item.id, coda, myDiagnostics, cursorLocation(myCursor)); core::DirectionType dt{}; dt.setChoice(core::DirectionTypeChoice::coda(core::OneOrMore{std::move(coda)})); addDirectionType(std::move(dt), direction); @@ -848,7 +866,7 @@ void DirectionWriter::emitRehearsal(const api::RehearsalData &item, core::Direct { rehearsal.setJustify(myConverter.convert(item.justify)); } - setId(item.id, rehearsal); + setId(item.id, rehearsal, myDiagnostics, cursorLocation(myCursor)); core::DirectionType dt{}; dt.setChoice(core::DirectionTypeChoice::rehearsal(core::OneOrMore{std::move(rehearsal)})); addDirectionType(std::move(dt), direction); @@ -866,7 +884,7 @@ core::EmptyPrintStyleAlignID DirectionWriter::createEmptyPrintStyleAlign(const a { setAttributesFromColorData(*color, element); } - setId(id, element); + setId(id, element, myDiagnostics, cursorLocation(myCursor)); return element; } @@ -904,7 +922,7 @@ void DirectionWriter::emitStringMute(const api::StringMuteData &item, core::Dire { setAttributesFromColorData(*item.color, stringMute); } - setId(item.id, stringMute); + setId(item.id, stringMute, myDiagnostics, cursorLocation(myCursor)); core::DirectionType dt{}; dt.setChoice(core::DirectionTypeChoice::stringMute(std::move(stringMute))); addDirectionType(std::move(dt), direction); @@ -931,7 +949,7 @@ void DirectionWriter::emitStaffDivide(const api::StaffDivideData &item, core::Di { setAttributesFromColorData(*item.color, staffDivide); } - setId(item.id, staffDivide); + setId(item.id, staffDivide, myDiagnostics, cursorLocation(myCursor)); core::DirectionType dt{}; dt.setChoice(core::DirectionTypeChoice::staffDivide(std::move(staffDivide))); addDirectionType(std::move(dt), direction); @@ -964,7 +982,7 @@ void DirectionWriter::emitPrincipalVoice(const api::PrincipalVoiceData &item, co { setAttributesFromColorData(*item.color, principalVoice); } - setId(item.id, principalVoice); + setId(item.id, principalVoice, myDiagnostics, cursorLocation(myCursor)); core::DirectionType dt{}; dt.setChoice(core::DirectionTypeChoice::principalVoice(std::move(principalVoice))); addDirectionType(std::move(dt), direction); @@ -988,7 +1006,7 @@ void DirectionWriter::emitOtherDirection(const api::OtherDirectionData &item, co { setAttributesFromColorData(*item.color, otherDirection); } - setId(item.id, otherDirection); + setId(item.id, otherDirection, myDiagnostics, cursorLocation(myCursor)); core::DirectionType dt{}; dt.setChoice(core::DirectionTypeChoice::otherDirection(std::move(otherDirection))); addDirectionType(std::move(dt), direction); @@ -1027,7 +1045,7 @@ void DirectionWriter::emitImage(const api::ImageData &item, core::Direction &dir default: break; } - setId(item.id, image); + setId(item.id, image, myDiagnostics, cursorLocation(myCursor)); core::DirectionType dt{}; dt.setChoice(core::DirectionTypeChoice::image(std::move(image))); addDirectionType(std::move(dt), direction); @@ -1048,7 +1066,7 @@ void DirectionWriter::emitAccordionRegistration(const api::AccordionRegistration { setAttributesFromColorData(*item.color, accordion); } - setId(item.id, accordion); + setId(item.id, accordion, myDiagnostics, cursorLocation(myCursor)); core::DirectionType dt{}; dt.setChoice(core::DirectionTypeChoice::accordionRegistration(std::move(accordion))); addDirectionType(std::move(dt), direction); @@ -1067,6 +1085,11 @@ void DirectionWriter::emitHarpPedals(const api::HarpPedalsData &item, core::Dire for (const auto &tuning : item.pedalTunings) { core::PedalTuning pedalTuning{}; + if (tuning.step == api::Step::unspecified) + { + myDiagnostics.report(api::Severity::warning, api::DiagnosticCode::missingValueDefaulted, + cursorLocation(myCursor), "pedal-step is unspecified; using C"); + } pedalTuning.setPedalStep(myConverter.convert(tuning.step)); pedalTuning.setPedalAlter( core::Semitones{core::Decimal{Converter::convertToAlter(tuning.alter, tuning.cents)}}); @@ -1086,7 +1109,7 @@ void DirectionWriter::emitHarpPedals(const api::HarpPedalsData &item, core::Dire { setAttributesFromColorData(*item.color, harpPedals); } - setId(item.id, harpPedals); + setId(item.id, harpPedals, myDiagnostics, cursorLocation(myCursor)); core::DirectionType dt{}; dt.setChoice(core::DirectionTypeChoice::harpPedals(std::move(harpPedals))); addDirectionType(std::move(dt), direction); @@ -1110,13 +1133,21 @@ void DirectionWriter::emitScordatura(const api::ScordaturaData &item, core::Dire accord.setString(core::StringNumber{*accordData.stringNumber}); } core::TuningGroup tuning{}; + if (accordData.tuningStep == api::Step::unspecified) + { + myDiagnostics.report(api::Severity::warning, api::DiagnosticCode::missingValueDefaulted, + cursorLocation(myCursor), "accord tuning-step is unspecified; using C"); + } tuning.setTuningStep(myConverter.convert(accordData.tuningStep)); if (accordData.tuningAlter != 0 || accordData.tuningCents != 0.0) { tuning.setTuningAlter(core::Semitones{ core::Decimal{Converter::convertToAlter(accordData.tuningAlter, accordData.tuningCents)}}); } - tuning.setTuningOctave(core::Octave{accordData.tuningOctave}); + const core::Octave tuningOctave{accordData.tuningOctave}; + reportAdjusted(myDiagnostics, cursorLocation(myCursor), "accord tuning-octave", accordData.tuningOctave, + tuningOctave.value()); + tuning.setTuningOctave(tuningOctave); accord.setTuning(std::move(tuning)); if (!isFirstAccordAdded) { @@ -1128,7 +1159,7 @@ void DirectionWriter::emitScordatura(const api::ScordaturaData &item, core::Dire scordatura.addAccord(std::move(accord)); } } - setId(item.id, scordatura); + setId(item.id, scordatura, myDiagnostics, cursorLocation(myCursor)); core::DirectionType dt{}; dt.setChoice(core::DirectionTypeChoice::scordatura(std::move(scordatura))); addDirectionType(std::move(dt), direction); @@ -1258,7 +1289,7 @@ void DirectionWriter::emitPercussion(const api::PercussionData &item, core::Dire { setAttributesFromColorData(*item.color, percussion); } - setId(item.id, percussion); + setId(item.id, percussion, myDiagnostics, cursorLocation(myCursor)); core::DirectionType dt{}; dt.setChoice(core::DirectionTypeChoice::percussion(core::OneOrMore{std::move(percussion)})); addDirectionType(std::move(dt), direction); @@ -1501,6 +1532,11 @@ std::vector DirectionWriter::createHarmonyElements(int in } case api::HarmonyChordSource::root: default: { + if (chordIter->root == api::Step::unspecified) + { + myDiagnostics.report(api::Severity::warning, api::DiagnosticCode::missingValueDefaulted, + cursorLocation(myCursor), "harmony root-step is unspecified; using C"); + } auto step = chordIter->root == api::Step::unspecified ? api::Step::c : chordIter->root; core::Root root{}; @@ -1661,6 +1697,11 @@ std::vector DirectionWriter::createHarmonyElements(int in } // Note: ProcessingInstruction is not available in the new core; miscData is skipped. + if (!chordIter->miscData.empty()) + { + myDiagnostics.report(api::Severity::error, api::DiagnosticCode::droppedData, cursorLocation(myCursor), + "harmony misc data is not written"); + } if (chordIter->hasFrameData) { @@ -1792,7 +1833,7 @@ std::vector DirectionWriter::createFiguredBassElements() } } - setId(figuredBassData.id, figuredBass); + setId(figuredBassData.id, figuredBass, myDiagnostics, cursorLocation(myCursor)); if (figuredBassData.parentheses != api::Bool::unspecified) { @@ -1802,8 +1843,11 @@ std::vector DirectionWriter::createFiguredBassElements() if (figuredBassData.durationTimeTicks >= 0) { - figuredBass.setDuration( - core::PositiveDivisions{core::Decimal{static_cast(figuredBassData.durationTimeTicks)}}); + const core::PositiveDivisions duration{ + core::Decimal{static_cast(figuredBassData.durationTimeTicks)}}; + reportAdjusted(myDiagnostics, cursorLocation(myCursor), "figured-bass duration", + static_cast(figuredBassData.durationTimeTicks), duration.value().value()); + figuredBass.setDuration(duration); } output.push_back(core::MusicDataChoice::figuredBass(figuredBass)); diff --git a/src/private/mx/impl/EncodingFunctions.cpp b/src/private/mx/impl/EncodingFunctions.cpp index ee30685cc..81277b29c 100644 --- a/src/private/mx/impl/EncodingFunctions.cpp +++ b/src/private/mx/impl/EncodingFunctions.cpp @@ -53,6 +53,15 @@ void createEncoding(const api::EncodingData &inEncoding, core::ScoreHeaderGroup const bool isDayValid = inEncoding.encodingDate.day == tryDate.day(); if (isYearValid || isMonthValid || isDayValid) { + if (!isYearValid || !isMonthValid || !isDayValid) + { + const auto &date = inEncoding.encodingDate; + diagnostics.report(api::Severity::warning, api::DiagnosticCode::valueAdjusted, api::Location{}, + "encoding-date " + std::to_string(date.year) + "-" + std::to_string(date.month) + "-" + + std::to_string(date.day) + " is not a valid date; using " + + std::to_string(tryDate.year()) + "-" + std::to_string(tryDate.month()) + "-" + + std::to_string(tryDate.day())); + } hasIdentification = true; hasEncoding = true; encoding.addChoice(core::EncodingChoice::encodingDate(tryDate)); diff --git a/src/private/mx/impl/GlissandoFunctions.h b/src/private/mx/impl/GlissandoFunctions.h index 1cbfde7da..a3095a128 100644 --- a/src/private/mx/impl/GlissandoFunctions.h +++ b/src/private/mx/impl/GlissandoFunctions.h @@ -112,10 +112,11 @@ void parseGlissandoOrSlide(const GLISSANDO_OR_SLIDE_TYPE &inElement, api::NoteAt // writeAttributesFromCurveStart/Stop in CurveFunctions.h. template void writeAttributesFromGlissandoStart(const api::GlissandoStart &inStart, GLISSANDO_OR_SLIDE_TYPE &outElement, - const std::optional &inResolvedNumber) + const std::optional &inResolvedNumber, + const DiagnosticsContext &diagnostics = {}, const api::Location &location = {}) { outElement.setType(core::StartStop::start()); - setId(inStart.id, outElement); + setId(inStart.id, outElement, diagnostics, location); setAttributesFromPositionData(inStart.positionData, outElement); setAttributesFromPrintData(inStart.printData, outElement); setAttributesFromLineData(inStart.lineData, outElement); @@ -150,10 +151,11 @@ void writeAttributesFromGlissandoStart(const api::GlissandoStart &inStart, GLISS template void writeAttributesFromGlissandoStop(const api::GlissandoStop &inStop, GLISSANDO_OR_SLIDE_TYPE &outElement, - const std::optional &inResolvedNumber) + const std::optional &inResolvedNumber, + const DiagnosticsContext &diagnostics = {}, const api::Location &location = {}) { outElement.setType(core::StartStop::stop()); - setId(inStop.id, outElement); + setId(inStop.id, outElement, diagnostics, location); setAttributesFromPositionData(inStop.positionData, outElement); setAttributesFromLineData(inStop.lineData, outElement); diff --git a/src/private/mx/impl/IdFunctions.h b/src/private/mx/impl/IdFunctions.h index 42f49da50..23f57e4b8 100644 --- a/src/private/mx/impl/IdFunctions.h +++ b/src/private/mx/impl/IdFunctions.h @@ -6,6 +6,7 @@ #include "mx/api/Id.h" #include "mx/api/IdAccess.h" +#include "mx/impl/DiagnosticsContext.h" #include @@ -26,11 +27,20 @@ template std::optional getId(const CORE_TYPE &inCo } // Write the id attribute onto any core element that has one. An absent id writes no attribute. The -// element receives the token the Id already holds, so the text is not scrubbed again. -template void setId(const std::optional &inId, CORE_TYPE &outCoreElement) +// element receives the token the Id already holds, so the text is not scrubbed again; an Id whose text +// was scrubbed when it was built is reported at location. +template +void setId(const std::optional &inId, CORE_TYPE &outCoreElement, const DiagnosticsContext &diagnostics, + const api::Location &location) { if (inId.has_value()) { + const auto &scrubbedText = api::IdAccess::scrubbedText(*inId); + if (scrubbedText.has_value()) + { + diagnostics.report(api::Severity::warning, api::DiagnosticCode::invalidValue, location, + "id \"" + *scrubbedText + "\" is not a valid id; using \"" + inId->value() + "\""); + } outCoreElement.setID(api::IdAccess::token(*inId)); } } diff --git a/src/private/mx/impl/LayoutFunctions.cpp b/src/private/mx/impl/LayoutFunctions.cpp index 99b097130..1edf8ed2b 100644 --- a/src/private/mx/impl/LayoutFunctions.cpp +++ b/src/private/mx/impl/LayoutFunctions.cpp @@ -37,9 +37,11 @@ namespace mx namespace impl { -static core::Tenths toTenths(double value) +static core::Tenths toTenths(double value, const DiagnosticsContext &diagnostics, const char *name) { - return core::Tenths{core::Decimal{value > 0.0 ? value : 0.0}}; + const double written = value > 0.0 ? value : 0.0; + reportAdjusted(diagnostics, api::Location{}, name, value, written); + return core::Tenths{core::Decimal{written}}; } static std::vector createPageMargins(const api::PageMarginsData &inPageMargins) @@ -170,6 +172,13 @@ void addScaling(const api::DefaultsData &inDefaults, core::ScoreHeaderGroup &out return; } + if (inDefaults.scalingMillimeters <= 0 || inDefaults.scalingTenths <= 0) + { + diagnostics.report(api::Severity::warning, api::DiagnosticCode::missingValueDefaulted, api::Location{}, + inDefaults.scalingMillimeters <= 0 ? "scaling millimeters are unspecified; using 0" + : "scaling tenths are unspecified; using 0"); + } + auto defaults = outScoreHeaderGroup.defaults().value_or(core::Defaults{}); core::Scaling scaling{}; @@ -209,13 +218,15 @@ void addSystemMargins(const api::DefaultsData &inDefaults, core::ScoreHeaderGrou if (inDefaults.systemLayout.systemDistance) { - systemLayout.setSystemDistance(toTenths(inDefaults.systemLayout.systemDistance.value())); + systemLayout.setSystemDistance( + toTenths(inDefaults.systemLayout.systemDistance.value(), diagnostics, "system-distance")); needsDefaults = true; } if (inDefaults.systemLayout.topSystemDistance) { - systemLayout.setTopSystemDistance(toTenths(inDefaults.systemLayout.topSystemDistance.value())); + systemLayout.setTopSystemDistance( + toTenths(inDefaults.systemLayout.topSystemDistance.value(), diagnostics, "top-system-distance")); needsDefaults = true; } @@ -224,8 +235,8 @@ void addSystemMargins(const api::DefaultsData &inDefaults, core::ScoreHeaderGrou const auto &margins = inDefaults.systemLayout.margins.value(); core::SystemMargins sm; core::LeftRightMarginsGroup lrm; - lrm.setLeftMargin(toTenths(margins.left)); - lrm.setRightMargin(toTenths(margins.right)); + lrm.setLeftMargin(toTenths(margins.left, diagnostics, "left-margin")); + lrm.setRightMargin(toTenths(margins.right, diagnostics, "right-margin")); sm.setLeftRightMargins(lrm); systemLayout.setSystemMargins(sm); needsDefaults = true; @@ -234,7 +245,8 @@ void addSystemMargins(const api::DefaultsData &inDefaults, core::ScoreHeaderGrou if (inDefaults.systemLayout.staffDistance) { core::StaffLayout staffLayout; - staffLayout.setStaffDistance(toTenths(inDefaults.systemLayout.staffDistance.value())); + staffLayout.setStaffDistance( + toTenths(inDefaults.systemLayout.staffDistance.value(), diagnostics, "staff-distance")); layout.addStaffLayout(staffLayout); needsDefaults = true; } @@ -242,8 +254,10 @@ void addSystemMargins(const api::DefaultsData &inDefaults, core::ScoreHeaderGrou for (const auto &[staffIndex, staffDistance] : inDefaults.systemLayout.staffDistances) { core::StaffLayout staffLayout; - staffLayout.setNumber(core::StaffNumber{staffIndex + 1}); - staffLayout.setStaffDistance(toTenths(staffDistance)); + const core::StaffNumber staffNumber{staffIndex + 1}; + reportAdjusted(diagnostics, api::Location{}, "staff-layout number", staffIndex + 1, staffNumber.value()); + staffLayout.setNumber(staffNumber); + staffLayout.setStaffDistance(toTenths(staffDistance, diagnostics, "staff-distance")); layout.addStaffLayout(staffLayout); needsDefaults = true; } @@ -273,21 +287,23 @@ void addAppearance(const api::DefaultsData &inDefaults, core::ScoreHeaderGroup & { core::LineWidth lw; lw.setType(core::LineWidthType{appearanceData.appearanceSubType}); - lw.setValue(toTenths(appearanceData.value)); + lw.setValue(toTenths(appearanceData.value, diagnostics, "line-width")); appearance.addLineWidth(lw); } else if (appearanceData.appearanceType == api::AppearanceType::NoteSize) { core::NoteSize ns; ns.setType(core::NoteSizeType::parse(appearanceData.appearanceSubType)); - ns.setValue(core::NonNegativeDecimal{core::Decimal{appearanceData.value}}); + const core::NonNegativeDecimal noteSize{core::Decimal{appearanceData.value}}; + reportAdjusted(diagnostics, api::Location{}, "note-size", appearanceData.value, noteSize.value().value()); + ns.setValue(noteSize); appearance.addNoteSize(ns); } else if (appearanceData.appearanceType == api::AppearanceType::Distance) { core::Distance di; di.setType(core::DistanceType{appearanceData.appearanceSubType}); - di.setValue(toTenths(appearanceData.value)); + di.setValue(toTenths(appearanceData.value, diagnostics, "distance")); appearance.addDistance(di); } else if (appearanceData.appearanceType == api::AppearanceType::OtherAppearance) diff --git a/src/private/mx/impl/MeasureWriter.cpp b/src/private/mx/impl/MeasureWriter.cpp index a56909419..6510d1bc9 100644 --- a/src/private/mx/impl/MeasureWriter.cpp +++ b/src/private/mx/impl/MeasureWriter.cpp @@ -72,12 +72,33 @@ core::PartwiseMeasure MeasureWriter::getPartwiseMeasure() writeMeasureGlobals(); writeStaves(); + + for (; myMeasureKeysIter != myMeasureKeysEnd; ++myMeasureKeysIter) + { + auto location = measureOnlyLocation(myHistory.getCursor()); + location.tickTimePosition = myMeasureKeysIter->tickTimePosition; + myScoreWriter.getDiagnostics().report(api::Severity::error, api::DiagnosticCode::droppedData, + std::move(location), "a key in the middle of the measure is not written"); + } myPropertiesWriter->flushBuffer(); writeBarlines(api::TICK_TIME_INFINITY); myPropertiesWriter = nullptr; return myOutMeasure; } +void MeasureWriter::reportMidMeasureKeyStaff() const +{ + if (myMeasureKeysIter->staffIndex >= 0) + { + auto location = measureOnlyLocation(myHistory.getCursor()); + location.tickTimePosition = myMeasureKeysIter->tickTimePosition; + myScoreWriter.getDiagnostics().report(api::Severity::warning, api::DiagnosticCode::valueAdjusted, + std::move(location), + "a key for staff " + std::to_string(myMeasureKeysIter->staffIndex + 1) + + " in the middle of the measure is written for all staves"); + } +} + void MeasureWriter::writeMeasureGlobals() { writeBarlines(0); @@ -102,7 +123,7 @@ void MeasureWriter::writeMeasureGlobals() myOutMeasure.setWidth(core::Tenths{core::Decimal{static_cast(myMeasureData.width)}}); } - impl::setId(myMeasureData.id, myOutMeasure); + impl::setId(myMeasureData.id, myOutMeasure, myScoreWriter.getDiagnostics(), cursorLocation(myHistory.getCursor())); Converter converter; @@ -294,7 +315,10 @@ void MeasureWriter::writeSystemInfo() for (const auto &[staffIndex, staffDistance] : inSystemLayout.staffDistances) { core::StaffLayout outStaffLayout{}; - outStaffLayout.setNumber(core::StaffNumber{staffIndex + 1}); + const core::StaffNumber staffNumber{staffIndex + 1}; + reportAdjusted(myScoreWriter.getDiagnostics(), measureOnlyLocation(myHistory.getCursor()), + "staff-layout number", staffIndex + 1, staffNumber.value()); + outStaffLayout.setNumber(staffNumber); outStaffLayout.setStaffDistance(core::Tenths{core::Decimal{staffDistance}}); outLayoutGroup.addStaffLayout(outStaffLayout); outPrint.setLayout(outLayoutGroup); @@ -470,7 +494,10 @@ void MeasureWriter::writeMeasureNumbering() if (myMeasureData.measureNumberingStaffIndex.has_value()) { // the api index is zero-based; core staff numbers are one-based. - outMeasureNumbering.setStaff(core::StaffNumber{*myMeasureData.measureNumberingStaffIndex + 1}); + const core::StaffNumber staffNumber{*myMeasureData.measureNumberingStaffIndex + 1}; + reportAdjusted(myScoreWriter.getDiagnostics(), measureOnlyLocation(myHistory.getCursor()), + "measure-numbering staff", *myMeasureData.measureNumberingStaffIndex + 1, staffNumber.value()); + outMeasureNumbering.setStaff(staffNumber); } outPrint.setMeasureNumbering(std::move(outMeasureNumbering)); @@ -568,6 +595,7 @@ void MeasureWriter::writeVoices(const api::StaffData &inStaff) { if (myMeasureKeysIter->tickTimePosition <= myHistory.getCursor().tickTimePosition) { + reportMidMeasureKeyStaff(); myPropertiesWriter->writeKey(api::INDEX_UNSPECIFIED, *myMeasureKeysIter); ++myMeasureKeysIter; } @@ -636,6 +664,7 @@ void MeasureWriter::writeVoices(const api::StaffData &inStaff) { if (myMeasureKeysIter->tickTimePosition) { + reportMidMeasureKeyStaff(); myPropertiesWriter->writeKey(api::INDEX_UNSPECIFIED, *myMeasureKeysIter); ++myMeasureKeysIter; } @@ -858,6 +887,11 @@ void MeasureWriter::writeBarlines(int tickTimePosition) // number is a required attribute; an empty list serializes as number="", which is // MusicXML's blank ending. + for (const int number : endingData.numbers) + { + reportAdjusted(myScoreWriter.getDiagnostics(), measureOnlyLocation(myHistory.getCursor()), + "ending number", number, std::max(number, 1)); + } ending.setNumber(core::EndingNumber{endingData.numbers}); // The text is written only when the author supplied one. Left empty, the ending @@ -919,7 +953,8 @@ void MeasureWriter::writeBarlines(int tickTimePosition) barlineElement.setRepeat(repeatElement); } - impl::setId(myBarlinesIter->id, barlineElement); + impl::setId(myBarlinesIter->id, barlineElement, myScoreWriter.getDiagnostics(), + cursorLocation(myHistory.getCursor())); myOutMeasure.addMusicData(core::MusicDataChoice::barline(barlineElement)); myHistory.log("writeBarline"); } diff --git a/src/private/mx/impl/MeasureWriter.h b/src/private/mx/impl/MeasureWriter.h index 8276c35b3..30ebc7f3b 100644 --- a/src/private/mx/impl/MeasureWriter.h +++ b/src/private/mx/impl/MeasureWriter.h @@ -193,6 +193,9 @@ class MeasureWriter core::PartwiseMeasure myOutMeasure; MeasureCursor myPreviousCursor; const ScoreWriter &myScoreWriter; + + // Reports a mid-measure key whose staff is dropped because it is written for all staves. + void reportMidMeasureKeyStaff() const; std::unique_ptr myPropertiesWriter; const Converter myConverter; std::vector::const_iterator myBarlinesIter; diff --git a/src/private/mx/impl/NotationsWriter.cpp b/src/private/mx/impl/NotationsWriter.cpp index 8faa6b021..5cd53a701 100644 --- a/src/private/mx/impl/NotationsWriter.cpp +++ b/src/private/mx/impl/NotationsWriter.cpp @@ -97,15 +97,19 @@ void notationsWriterSetMordentSpecificAttributes(const api::MarkData &mark, core } } -core::NotationsChoice notationsWriterMakeTupletStop(const api::TupletStop &inTupletStop) +core::NotationsChoice notationsWriterMakeTupletStop(const api::TupletStop &inTupletStop, + const DiagnosticsContext &diagnostics, + const api::Location &location) { core::Tuplet tuplet; tuplet.setType(core::StartStop::stop()); - setId(inTupletStop.id, tuplet); + setId(inTupletStop.id, tuplet, diagnostics, location); if (inTupletStop.numberLevel > 0) { - tuplet.setNumber(core::NumberLevel{inTupletStop.numberLevel}); + const core::NumberLevel numberLevel{inTupletStop.numberLevel}; + reportAdjusted(diagnostics, location, "tuplet number", inTupletStop.numberLevel, numberLevel.value()); + tuplet.setNumber(numberLevel); } return core::NotationsChoice::tuplet(tuplet); @@ -130,19 +134,24 @@ core::Notations NotationsWriter::getNotations() const { if (curve.curveType != api::CurveType::tie && curve.curveType != api::CurveType::slur) { + myScoreWriter.getDiagnostics().report(api::Severity::error, api::DiagnosticCode::droppedData, + cursorLocation(myCursor), + "a curve with an unspecified type is not written"); continue; } const auto resolvedNumber = spannerResolver.emittedNumber(curve.number, &curve); if (curve.curveType == api::CurveType::tie) { core::Tied tied; - writeAttributesFromCurveStop(curve, tied, resolvedNumber); + writeAttributesFromCurveStop(curve, tied, resolvedNumber, myScoreWriter.getDiagnostics(), + cursorLocation(myCursor)); outNotations.addChoice(core::NotationsChoice::tied(tied)); } else if (curve.curveType == api::CurveType::slur) { core::Slur slur; - writeAttributesFromCurveStop(curve, slur, resolvedNumber); + writeAttributesFromCurveStop(curve, slur, resolvedNumber, myScoreWriter.getDiagnostics(), + cursorLocation(myCursor)); outNotations.addChoice(core::NotationsChoice::slur(slur)); } } @@ -151,19 +160,24 @@ core::Notations NotationsWriter::getNotations() const { if (curve.curveType != api::CurveType::tie && curve.curveType != api::CurveType::slur) { + myScoreWriter.getDiagnostics().report(api::Severity::error, api::DiagnosticCode::droppedData, + cursorLocation(myCursor), + "a curve with an unspecified type is not written"); continue; } const auto resolvedNumber = spannerResolver.emittedNumber(curve.number, &curve); if (curve.curveType == api::CurveType::tie) { core::Tied tied; - writeAttributesFromCurveContinue(curve, tied, resolvedNumber); + writeAttributesFromCurveContinue(curve, tied, resolvedNumber, myScoreWriter.getDiagnostics(), + cursorLocation(myCursor)); outNotations.addChoice(core::NotationsChoice::tied(tied)); } else if (curve.curveType == api::CurveType::slur) { core::Slur slur; - writeAttributesFromCurveContinue(curve, slur, resolvedNumber); + writeAttributesFromCurveContinue(curve, slur, resolvedNumber, myScoreWriter.getDiagnostics(), + cursorLocation(myCursor)); outNotations.addChoice(core::NotationsChoice::slur(slur)); } } @@ -172,19 +186,24 @@ core::Notations NotationsWriter::getNotations() const { if (curve.curveType != api::CurveType::tie && curve.curveType != api::CurveType::slur) { + myScoreWriter.getDiagnostics().report(api::Severity::error, api::DiagnosticCode::droppedData, + cursorLocation(myCursor), + "a curve with an unspecified type is not written"); continue; } const auto resolvedNumber = spannerResolver.emittedNumber(curve.number, &curve); if (curve.curveType == api::CurveType::tie) { core::Tied tied; - writeAttributesFromCurveStart(curve, tied, resolvedNumber); + writeAttributesFromCurveStart(curve, tied, resolvedNumber, myScoreWriter.getDiagnostics(), + cursorLocation(myCursor)); outNotations.addChoice(core::NotationsChoice::tied(tied)); } else if (curve.curveType == api::CurveType::slur) { core::Slur slur; - writeAttributesFromCurveStart(curve, slur, resolvedNumber); + writeAttributesFromCurveStart(curve, slur, resolvedNumber, myScoreWriter.getDiagnostics(), + cursorLocation(myCursor)); outNotations.addChoice(core::NotationsChoice::slur(slur)); } } @@ -195,7 +214,8 @@ core::Notations NotationsWriter::getNotations() const if (myNoteData.tieLetRing.has_value()) { core::Tied tied; - writeAttributesFromTieLetRing(*myNoteData.tieLetRing, tied); + writeAttributesFromTieLetRing(*myNoteData.tieLetRing, tied, myScoreWriter.getDiagnostics(), + cursorLocation(myCursor)); outNotations.addChoice(core::NotationsChoice::tied(tied)); } @@ -216,7 +236,7 @@ core::Notations NotationsWriter::getNotations() const { core::Tuplet tuplet; tuplet.setType(core::StartStop::start()); - setId(tupletStart.id, tuplet); + setId(tupletStart.id, tuplet, myScoreWriter.getDiagnostics(), cursorLocation(myCursor)); core::TupletPortion actual; core::TupletNumber tn1; @@ -246,7 +266,10 @@ core::Notations NotationsWriter::getNotations() const if (tupletStart.numberLevel > 0) { - tuplet.setNumber(core::NumberLevel{tupletStart.numberLevel}); + const core::NumberLevel numberLevel{tupletStart.numberLevel}; + reportAdjusted(myScoreWriter.getDiagnostics(), cursorLocation(myCursor), "tuplet number", + tupletStart.numberLevel, numberLevel.value()); + tuplet.setNumber(numberLevel); } if (tupletStart.bracket != api::Bool::unspecified) @@ -279,7 +302,8 @@ core::Notations NotationsWriter::getNotations() const { if (!tupletStopWritten[stopIndex] && tupletStops[stopIndex].numberLevel == tupletStart.numberLevel) { - outNotations.addChoice(notationsWriterMakeTupletStop(tupletStops[stopIndex])); + outNotations.addChoice(notationsWriterMakeTupletStop( + tupletStops[stopIndex], myScoreWriter.getDiagnostics(), cursorLocation(myCursor))); tupletStopWritten[stopIndex] = true; break; } @@ -290,7 +314,8 @@ core::Notations NotationsWriter::getNotations() const { if (!tupletStopWritten[stopIndex]) { - outNotations.addChoice(notationsWriterMakeTupletStop(tupletStops[stopIndex])); + outNotations.addChoice(notationsWriterMakeTupletStop(tupletStops[stopIndex], myScoreWriter.getDiagnostics(), + cursorLocation(myCursor))); } } @@ -415,9 +440,12 @@ core::Notations NotationsWriter::getNotations() const : core::TopBottom::top()); if (nonArpeggiateData.number.has_value()) { - nonArpeggiate.setNumber(core::NumberLevel{*nonArpeggiateData.number}); + const core::NumberLevel numberLevel{*nonArpeggiateData.number}; + reportAdjusted(myScoreWriter.getDiagnostics(), cursorLocation(myCursor), "non-arpeggiate number", + *nonArpeggiateData.number, numberLevel.value()); + nonArpeggiate.setNumber(numberLevel); } - setId(nonArpeggiateData.id, nonArpeggiate); + setId(nonArpeggiateData.id, nonArpeggiate, myScoreWriter.getDiagnostics(), cursorLocation(myCursor)); outNotations.addChoice(core::NotationsChoice::nonArpeggiate(nonArpeggiate)); } @@ -442,14 +470,17 @@ core::Notations NotationsWriter::getNotations() const const auto arpeggiateData = mark.choice.arpeggiate(); if (arpeggiateData.number.has_value()) { - arpeggiate.setNumber(core::NumberLevel{*arpeggiateData.number}); + const core::NumberLevel numberLevel{*arpeggiateData.number}; + reportAdjusted(myScoreWriter.getDiagnostics(), cursorLocation(myCursor), "arpeggiate number", + *arpeggiateData.number, numberLevel.value()); + arpeggiate.setNumber(numberLevel); } if (arpeggiateData.unbroken != api::Bool::unspecified) { Converter converter; arpeggiate.setUnbroken(converter.convert(arpeggiateData.unbroken)); } - setId(arpeggiateData.id, arpeggiate); + setId(arpeggiateData.id, arpeggiate, myScoreWriter.getDiagnostics(), cursorLocation(myCursor)); outNotations.addChoice(core::NotationsChoice::arpeggiate(arpeggiate)); } @@ -463,16 +494,25 @@ core::Notations NotationsWriter::getNotations() const other.setType(myConverter.convert(payload.type)); if (payload.number.has_value()) { - other.setNumber(core::NumberLevel{*payload.number}); + const core::NumberLevel numberLevel{*payload.number}; + reportAdjusted(myScoreWriter.getDiagnostics(), cursorLocation(myCursor), "other-notation number", + *payload.number, numberLevel.value()); + other.setNumber(numberLevel); } if (payload.smufl.has_value()) { other.setSmufl(core::SmuflGlyphName{*payload.smufl}); } - setId(payload.id, other); + setId(payload.id, other, myScoreWriter.getDiagnostics(), cursorLocation(myCursor)); outNotations.addChoice(core::NotationsChoice::otherNotation(other)); } + else if (isMarkPedal(mark.markType)) + { + myScoreWriter.getDiagnostics().report(api::Severity::error, api::DiagnosticCode::droppedData, + cursorLocation(myCursor), + "a pedal mark on a note is not written; write it in a direction"); + } } addWavyLineStarts(ornaments); @@ -521,13 +561,15 @@ void NotationsWriter::addGlissandoAndSlide(core::Notations &outNotations) const if (glissandoStart.glissandoType == api::GlissandoType::slide) { core::Slide slide; - writeAttributesFromGlissandoStart(glissandoStart, slide, resolvedNumber); + writeAttributesFromGlissandoStart(glissandoStart, slide, resolvedNumber, myScoreWriter.getDiagnostics(), + cursorLocation(myCursor)); outNotations.addChoice(core::NotationsChoice::slide(slide)); } else { core::Glissando glissando; - writeAttributesFromGlissandoStart(glissandoStart, glissando, resolvedNumber); + writeAttributesFromGlissandoStart(glissandoStart, glissando, resolvedNumber, myScoreWriter.getDiagnostics(), + cursorLocation(myCursor)); outNotations.addChoice(core::NotationsChoice::glissando(glissando)); } @@ -553,13 +595,15 @@ void NotationsWriter::addGlissandoStop(const api::GlissandoStop &inGlissandoStop if (inGlissandoStop.glissandoType == api::GlissandoType::slide) { core::Slide slide; - writeAttributesFromGlissandoStop(inGlissandoStop, slide, resolvedNumber); + writeAttributesFromGlissandoStop(inGlissandoStop, slide, resolvedNumber, myScoreWriter.getDiagnostics(), + cursorLocation(myCursor)); outNotations.addChoice(core::NotationsChoice::slide(slide)); } else { core::Glissando glissando; - writeAttributesFromGlissandoStop(inGlissandoStop, glissando, resolvedNumber); + writeAttributesFromGlissandoStop(inGlissandoStop, glissando, resolvedNumber, myScoreWriter.getDiagnostics(), + cursorLocation(myCursor)); outNotations.addChoice(core::NotationsChoice::glissando(glissando)); } } @@ -1035,23 +1079,39 @@ void NotationsWriter::addTechnical(const api::MarkData &mark, core::Technical &o case core::TechnicalChoice::Kind::fret: { core::Fret f; int fretValue = 0; + std::size_t length = 0; if (!mark.name.empty()) { try { - fretValue = std::stoi(mark.name); + fretValue = std::stoi(mark.name, &length); } catch (...) { } } + // reported outside the try so a throwing diagnostic handler is not swallowed + if (length != mark.name.size()) + { + myScoreWriter.getDiagnostics().report( + api::Severity::warning, api::DiagnosticCode::invalidValue, cursorLocation(myCursor), + "fret \"" + mark.name + "\" is not a number; using " + std::to_string(fretValue)); + } f.setValue(fretValue); outTechnical.addChoice(core::TechnicalChoice::fret(f)); break; } case core::TechnicalChoice::Kind::string: { core::String s; - s.setValue(core::StringNumber::parse(mark.name)); + core::ValueParseOutcome outcome = core::ValueParseOutcome::valid; + const auto stringNumber = core::StringNumber::parse(mark.name, outcome); + if (outcome != core::ValueParseOutcome::valid) + { + myScoreWriter.getDiagnostics().report( + api::Severity::warning, api::DiagnosticCode::invalidValue, cursorLocation(myCursor), + "string \"" + mark.name + "\" is not a string number; using " + std::to_string(stringNumber.value())); + } + s.setValue(stringNumber); outTechnical.addChoice(core::TechnicalChoice::string(s)); break; } diff --git a/src/private/mx/impl/NoteWriter.cpp b/src/private/mx/impl/NoteWriter.cpp index 5f140fac8..0637af0b4 100644 --- a/src/private/mx/impl/NoteWriter.cpp +++ b/src/private/mx/impl/NoteWriter.cpp @@ -106,7 +106,7 @@ core::Note NoteWriter::getNote(bool isStartOfChord) const setNotehead(); setStemDirection(); setMiscData(); - impl::setId(myNoteData.id, myOutNote); + impl::setId(myNoteData.id, myOutNote, myScoreWriter.getDiagnostics(), cursorLocation(myCursor)); NotationsWriter notationsWriter{myNoteData, myCursor, myScoreWriter}; impl::setAttributesFromPositionData(myNoteData.positionData, myOutNote); if (myNoteData.printData.printObject != api::Bool::unspecified) @@ -170,6 +170,11 @@ core::Note NoteWriter::getNote(bool isStartOfChord) const { core::Beam mxBeam; mxBeam.setNumber(core::BeamLevel{beamIndex + 1}); + if (beam == api::Beam::unspecified) + { + myScoreWriter.getDiagnostics().report(api::Severity::warning, api::DiagnosticCode::missingValueDefaulted, + cursorLocation(myCursor), "beam type is unspecified; using begin"); + } mxBeam.setValue(myConverter.convert(beam)); const auto added = myOutNote.addBeam(std::move(mxBeam)); if (!added) @@ -281,6 +286,11 @@ void NoteWriter::assembleNoteChoice() const { const auto duration = core::PositiveDivisions{core::Decimal{static_cast(myNoteData.durationData.durationTimeTicks)}}; + if (!myNoteData.isGrace) + { + reportAdjusted(myScoreWriter.getDiagnostics(), cursorLocation(myCursor), "note duration", + static_cast(myNoteData.durationData.durationTimeTicks), duration.value().value()); + } if (myNoteData.isGrace) { @@ -340,6 +350,19 @@ void NoteWriter::assembleNoteChoice() const } } +core::Octave NoteWriter::writtenOctave() const +{ + const auto &diagnostics = myScoreWriter.getDiagnostics(); + if (myNoteData.pitchData.step == api::Step::unspecified) + { + diagnostics.report(api::Severity::warning, api::DiagnosticCode::missingValueDefaulted, cursorLocation(myCursor), + "note step is unspecified; using C"); + } + const core::Octave octave{myNoteData.pitchData.octave}; + reportAdjusted(diagnostics, cursorLocation(myCursor), "note octave", myNoteData.pitchData.octave, octave.value()); + return octave; +} + void NoteWriter::setFullNoteTypeChoice() const { if (myNoteData.isRest) @@ -349,7 +372,7 @@ void NoteWriter::setFullNoteTypeChoice() const { core::DisplayStepOctaveGroup pitch; pitch.setDisplayStep(myConverter.convert(myNoteData.pitchData.step)); - pitch.setDisplayOctave(core::Octave{myNoteData.pitchData.octave}); + pitch.setDisplayOctave(writtenOctave()); rest.setDisplayStepOctave(std::move(pitch)); } @@ -367,7 +390,7 @@ void NoteWriter::setFullNoteTypeChoice() const { core::DisplayStepOctaveGroup pitch; pitch.setDisplayStep(myConverter.convert(myNoteData.pitchData.step)); - pitch.setDisplayOctave(core::Octave{myNoteData.pitchData.octave}); + pitch.setDisplayOctave(writtenOctave()); unpitched.setDisplayStepOctave(std::move(pitch)); } @@ -382,7 +405,7 @@ void NoteWriter::setFullNoteTypeChoice() const const auto alter = Converter::convertToAlter(myNoteData.pitchData.alter, myNoteData.pitchData.cents); pitch.setAlter(core::Semitones{core::Decimal{alter}}); } - pitch.setOctave(core::Octave{myNoteData.pitchData.octave}); + pitch.setOctave(writtenOctave()); myOutFullNoteGroup.setChoice(core::FullNoteGroupChoice::pitch(std::move(pitch))); } } @@ -445,6 +468,11 @@ void NoteWriter::setDurationNameAndDots() const const bool isMeasureRest = myNoteData.isRest && myNoteData.isMeasureRest; if (myNoteData.durationData.isDurationNameSpecified && !isMeasureRest) { + if (myNoteData.durationData.durationName == api::DurationName::unspecified) + { + myScoreWriter.getDiagnostics().report(api::Severity::warning, api::DiagnosticCode::missingValueDefaulted, + cursorLocation(myCursor), "note type is unspecified; using maxima"); + } core::NoteType noteType; noteType.setValue(myConverter.convert(myNoteData.durationData.durationName)); myOutNote.setType(std::move(noteType)); @@ -505,7 +533,16 @@ void NoteWriter::setLyrics() const core::Lyric lyric; if (!lyricData.verseNumber.empty()) { - lyric.setNumber(core::NameToken{lyricData.verseNumber}); + core::ValueParseOutcome outcome = core::ValueParseOutcome::valid; + const auto number = core::NameToken::parse(lyricData.verseNumber, outcome); + if (outcome != core::ValueParseOutcome::valid) + { + myScoreWriter.getDiagnostics().report( + api::Severity::warning, api::DiagnosticCode::invalidValue, cursorLocation(myCursor), + "lyric number \"" + lyricData.verseNumber + "\" is not a valid name token; using \"" + + number.value() + "\""); + } + lyric.setNumber(number); } if (!lyricData.verseName.empty()) @@ -514,7 +551,7 @@ void NoteWriter::setLyrics() const } impl::setAttributesFromPositionData(lyricData.positionData, lyric); - impl::setId(lyricData.id, lyric); + impl::setId(lyricData.id, lyric, myScoreWriter.getDiagnostics(), cursorLocation(myCursor)); if (lyricData.positionData.horizontalAlignment != api::HorizontalAlignment::unspecified) { lyric.setJustify(myConverter.convert(lyricData.positionData.horizontalAlignment)); @@ -631,11 +668,18 @@ void NoteWriter::setMiscData() const { // Comma is the item separator in the miscellaneous-field wire encoding, so commas // inside user misc-data are irreversibly replaced with underscores. - std::string::size_type position = 0; - while ((position = s.find(comma, position)) != std::string::npos) + if (s.find(comma) != std::string::npos) { - s.replace(position, comma.size(), underscore); - position++; + const auto original = s; + std::string::size_type position = 0; + while ((position = s.find(comma, position)) != std::string::npos) + { + s.replace(position, comma.size(), underscore); + position++; + } + myScoreWriter.getDiagnostics().report( + api::Severity::warning, api::DiagnosticCode::valueAdjusted, cursorLocation(myCursor), + "note misc data \"" + original + "\" contains a comma; using \"" + s + "\""); } if (isFirst) diff --git a/src/private/mx/impl/NoteWriter.h b/src/private/mx/impl/NoteWriter.h index 8ea602f0d..c17098245 100644 --- a/src/private/mx/impl/NoteWriter.h +++ b/src/private/mx/impl/NoteWriter.h @@ -49,6 +49,8 @@ class NoteWriter void addTie(bool isStart) const; void setNoteChoiceAndFullNoteGroup(bool isStartOfChord) const; void assembleNoteChoice() const; + // The note's octave, reporting a clamp and an unspecified step, which the caller writes as C. + core::Octave writtenOctave() const; void setFullNoteTypeChoice() const; void setStaffAndVoice() const; void setDurationNameAndDots() const; diff --git a/src/private/mx/impl/PartWriter.cpp b/src/private/mx/impl/PartWriter.cpp index f8c9edac5..1b5ceb7b4 100644 --- a/src/private/mx/impl/PartWriter.cpp +++ b/src/private/mx/impl/PartWriter.cpp @@ -74,10 +74,28 @@ PartWriter::PartWriter(const api::PartData &inPartData, int inPartIndex, int inT { } +const DiagnosticsContext &PartWriter::diagnostics() const +{ + return myScoreWriter.getDiagnostics(); +} + +core::Token PartWriter::writtenToken(const char *name, const std::string &text) const +{ + core::ValueParseOutcome outcome = core::ValueParseOutcome::valid; + auto token = core::Token::parse(text, outcome); + if (outcome != core::ValueParseOutcome::valid) + { + diagnostics().report(api::Severity::warning, api::DiagnosticCode::invalidValue, partLocation(myPartIndex), + std::string{name} + " \"" + text + "\" is not a valid id; using \"" + token.value() + + "\""); + } + return token; +} + core::ScorePart PartWriter::getScorePart() const { core::ScorePart scorePart{}; - scorePart.setID(core::Token{myPartData.uniqueId}); + scorePart.setID(writtenToken("part id", myPartData.uniqueId)); // is required, so always write it. print-object is round- // tripped from the model (not force-hidden); deprecated formatting is never @@ -115,7 +133,9 @@ core::ScorePart PartWriter::getScorePart() const core::ScoreInstrument scoreInstrument{}; bool addScoreInstrument = false; - scoreInstrument.setID(core::Token{myPartData.instrumentData.uniqueId}); + scoreInstrument.setID(myPartData.instrumentData.uniqueId.empty() + ? core::Token{} + : writtenToken("instrument id", myPartData.instrumentData.uniqueId)); if (myPartData.instrumentData.name.size() > 0) { @@ -195,7 +215,10 @@ core::ScorePart PartWriter::getScorePart() const if (apiMidiData.devicePort.has_value()) { - midiDevice.setPort(core::MIDI16{*apiMidiData.devicePort}); + const core::MIDI16 port{*apiMidiData.devicePort}; + reportAdjusted(diagnostics(), partLocation(myPartIndex), "midi-device port", *apiMidiData.devicePort, + port.value()); + midiDevice.setPort(port); } // The midi-device attaches to this part's instrument, the same instrument the @@ -218,37 +241,55 @@ core::ScorePart PartWriter::getScorePart() const if (myPartData.instrumentData.midiData.bank >= 0) { addMidiElement = true; - midiInstrument.setMIDIBank(core::MIDI16384{myPartData.instrumentData.midiData.bank}); + const core::MIDI16384 bank{myPartData.instrumentData.midiData.bank}; + reportAdjusted(diagnostics(), partLocation(myPartIndex), "midi-bank", myPartData.instrumentData.midiData.bank, + bank.value()); + midiInstrument.setMIDIBank(bank); } if (myPartData.instrumentData.midiData.channel >= 0) { addMidiElement = true; - midiInstrument.setMIDIChannel(core::MIDI16{myPartData.instrumentData.midiData.channel}); + const core::MIDI16 channel{myPartData.instrumentData.midiData.channel}; + reportAdjusted(diagnostics(), partLocation(myPartIndex), "midi-channel", + myPartData.instrumentData.midiData.channel, channel.value()); + midiInstrument.setMIDIChannel(channel); } if (myPartData.instrumentData.midiData.program >= 0) { addMidiElement = true; - midiInstrument.setMIDIProgram(core::MIDI128{myPartData.instrumentData.midiData.program}); + const core::MIDI128 program{myPartData.instrumentData.midiData.program}; + reportAdjusted(diagnostics(), partLocation(myPartIndex), "midi-program", + myPartData.instrumentData.midiData.program, program.value()); + midiInstrument.setMIDIProgram(program); } if (myPartData.instrumentData.midiData.isElevationSpecified) { addMidiElement = true; - midiInstrument.setElevation(core::RotationDegrees{core::Decimal{myPartData.instrumentData.midiData.elevation}}); + const core::RotationDegrees elevation{core::Decimal{myPartData.instrumentData.midiData.elevation}}; + reportAdjusted(diagnostics(), partLocation(myPartIndex), "elevation", + myPartData.instrumentData.midiData.elevation, elevation.value().value()); + midiInstrument.setElevation(elevation); } if (myPartData.instrumentData.midiData.isPanSpecified) { addMidiElement = true; - midiInstrument.setPan(core::RotationDegrees{core::Decimal{myPartData.instrumentData.midiData.pan}}); + const core::RotationDegrees pan{core::Decimal{myPartData.instrumentData.midiData.pan}}; + reportAdjusted(diagnostics(), partLocation(myPartIndex), "pan", myPartData.instrumentData.midiData.pan, + pan.value().value()); + midiInstrument.setPan(pan); } if (myPartData.instrumentData.midiData.isVolumeSpecified) { addMidiElement = true; - midiInstrument.setVolume(core::Percent{core::Decimal{myPartData.instrumentData.midiData.volume}}); + const core::Percent volume{core::Decimal{myPartData.instrumentData.midiData.volume}}; + reportAdjusted(diagnostics(), partLocation(myPartIndex), "volume", myPartData.instrumentData.midiData.volume, + volume.value().value()); + midiInstrument.setVolume(volume); } if (addMidiElement) @@ -280,6 +321,7 @@ core::ScorePart PartWriter::getScorePart() const core::PartwisePart PartWriter::getPartwisePart() const { core::PartwisePart partwisePart{}; + // getScorePart reports a scrubbed part id partwisePart.setID(core::Token{myPartData.uniqueId}); writeMeasures(partwisePart); return partwisePart; diff --git a/src/private/mx/impl/PartWriter.h b/src/private/mx/impl/PartWriter.h index 865c29c74..77a28835d 100644 --- a/src/private/mx/impl/PartWriter.h +++ b/src/private/mx/impl/PartWriter.h @@ -7,6 +7,7 @@ #include "mx/api/PartData.h" #include +#include namespace mx { @@ -14,10 +15,12 @@ namespace core { class PartwisePart; class ScorePart; +class Token; } // namespace core namespace impl { +class DiagnosticsContext; class ScoreWriter; class PartWriter @@ -35,6 +38,10 @@ class PartWriter mutable std::mutex myMutex; const ScoreWriter &myScoreWriter; + const DiagnosticsContext &diagnostics() const; + // Builds an id token from text, reporting text that is not a valid id. + core::Token writtenToken(const char *name, const std::string &text) const; + private: /// Writes all the measures from myPartData to outPart void writeMeasures(core::PartwisePart &outPart) const; diff --git a/src/private/mx/impl/PropertiesWriter.cpp b/src/private/mx/impl/PropertiesWriter.cpp index 89fb66b37..460a7c8d7 100644 --- a/src/private/mx/impl/PropertiesWriter.cpp +++ b/src/private/mx/impl/PropertiesWriter.cpp @@ -97,7 +97,7 @@ void PropertiesWriter::writeMultipleRest(int measureCount, api::Bool useSymbols) void PropertiesWriter::writeKey(int staffIndex, const api::KeyData &inKeyData) { core::Key key{}; - impl::setId(inKeyData.id, key); + impl::setId(inKeyData.id, key, myDiagnostics, myLocation); if (staffIndex >= 0) { @@ -117,7 +117,7 @@ void PropertiesWriter::writeKey(int staffIndex, const api::KeyData &inKeyData) myHasContent = true; } -void PropertiesWriter::writeNonTraditionalKey(const api::KeyData &inKeyData, core::Key &ioKey) +void PropertiesWriter::writeNonTraditionalKey(const api::KeyData &inKeyData, core::Key &ioKey) const { Converter converter; std::vector groups; @@ -131,6 +131,11 @@ void PropertiesWriter::writeNonTraditionalKey(const api::KeyData &inKeyData, cor nt.setKeyAccidental(ka); } const auto isUnknown = keyComponent.step == api::Step::unspecified; + if (isUnknown) + { + myDiagnostics.report(api::Severity::warning, api::DiagnosticCode::missingValueDefaulted, myLocation, + "key-step is unspecified; using C"); + } const auto step = isUnknown ? api::Step::c : keyComponent.step; nt.setKeyStep(converter.convert(step)); const auto alter = Converter::convertToAlter(keyComponent.alter, keyComponent.cents); @@ -172,7 +177,8 @@ void PropertiesWriter::writeTraditionalKey(const api::KeyData &inKeyData, core:: // converts a list of api fractions (a primary or interchangeable meter) to a core OneOrMore; // an (invalid) empty meter falls back to a single 4/4 pair static core::OneOrMore propertiesWriterTimeSignatureGroups( - const std::vector &inFractions) + const std::vector &inFractions, const DiagnosticsContext &diagnostics, + const api::Location &location) { std::vector groups; for (const auto &fraction : inFractions) @@ -184,6 +190,8 @@ static core::OneOrMore propertiesWriterTimeSignatureGr } if (groups.empty()) { + diagnostics.report(api::Severity::warning, api::DiagnosticCode::missingValueDefaulted, location, + "time signature has no fractions; using 4/4"); core::TimeSignatureGroup tsg{}; tsg.setBeats("4"); tsg.setBeatType("4"); @@ -197,16 +205,18 @@ static core::OneOrMore propertiesWriterTimeSignatureGr // builds the metered (group) TimeChoice from an api MeteredTimeSignature, and sets the meter's own // symbol/separator on the