libdoom-umapinfo  1.0.0
Parser for Doom UMAPINFO data
Documentation
Parser for Doom UMAPINFO data
=============================

This library provides a parser for Doom UMAPINFO data.

Official specification:
<https://github.com/kraflab/umapinfo/blob/master/docs/spec.md>

This library uses a liberal interpretation of the specification that
requires no special formating or whitespace between the tokens.
The implemented syntax is formally defined in the file "SYNTAX".

The development goals of this implementation are:
- C90 conformance
- Error tolerance


General
-------
The MAPINFO lump describes meta-data associated with levels (such as their
name, music, sky texture, par time, etc.):
<https://doomwiki.org/wiki/MAPINFO>

Different Doom source ports have adopted different MAPINFO systems.
UMAPINFO seeks to mitigate this problem by being a cross-port standard.


API
---
This library occupies the namespaces with "doom_umi1_" and "DOOM_UMI1_" prefix.
The namespaces with "doom_umi1_i_" and "DOOM_UMI1_I_" prefix are reserved for
internal use, never use it outside of the library (the shared library
may not even export such symbols).

Public data types of this library do not use the suffix "_t", because it is
reserved by POSIX for all header files:
<https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html>
(Section 2.2.2)

See HTML documentation of this library for API details and error codes.


Error handling
--------------
The API uses return values to indicate success or error. The return
value zero means success, negative values indicate an error.
Positive values are reserved for future use and should not be treated as
errors for this major version.

In general errors are reported to the caller without internal handling.
Eample: To check a negative return value for "out of memory" condition, use
(DOOM_UMI1_ERR_MEMORY == retval).

Some fatal errors can be internally handled via assert(). Such errors,
like internal data corruption, indicate bugs in the library or the
calling program. For maximum performance internal checks can be disabled
with:

   CPPFLAGS=-DNDEBUG

The build system of the library does not set this option by default.


Versioning scheme
-----------------
The release version contains 3 numbers "x.y.z":

- Major (x)
  The major number is incremented for every API/ABI change that is not
  backward compatible.
- Minor (y)
  The minor number is incremented for API/ABI extensions that are
  backward compatible.
- Patch (z)
  The patch number is incremented for changes that don't modify the
  API/ABI.

In other words:
Releases with the same major and minor numbers are drop-in replacements.
Up- and downgrades between such versions are possible without touching
programs that use the library.
Releases with the same major, but different minor numbers are backward,
but not forward compatible. Upgrades are possible, downgrades can break
programs that use the library.
Releases with different major numbers require changes in all programs that
use the library.

Versions with different major numbers can be installed in parallel
(including header files).

Binaries can be linked against multiple instances of the library with
different major versions (no problem if dependencies are using different
major versions).


Thread safety
-------------
The doom_umi1_create(), doom_umi1_destroy() and doom_umi1_register_mmanager()
API functions are not thread-safe.

All other API functions are thread-safe.

This means that importing multiple UMAPINFO lumps simultaneously is not
supported, but simultaneous access to existing data objects is allowed.


Known bugs
----------
Lexer:
- The code generated by flex allocates memory for internal structures of
  the lexer. If the memory allocation fails, the generated code directly
  calls exit().
  This means the library cannot handle such errors gracefully by returning
  the error code DOOM_UMI1_ERR_MEMORY from doom_umi1_create().

Parser:
- Some memory is not freed by doom_umi1_destroy() function after "make regen".
  Berkeley yacc must be compiled with "--disable-leaks" option to fix this.
  The distibuted code is generated with this option enabled.


EOF
Syntax for UMAPINFO Rev 2.2
===========================

Based on UMAPINFO specification:
<https://github.com/kraflab/umapinfo/blob/master/docs/spec.md>
Changelog for older revisions:
<https://doomwiki.org/wiki/UMAPINFO#Revisions>
No encoding for the data is defined, therefore the specification is interpreted
as US-ASCII according to RFC 20: <https://www.rfc-editor.org/rfc/rfc20>

Unfortunately the UMAPINFO specification provides no formal syntax definition.
The following, inofficial syntax is accepted by the parser of this library.
It uses ABNF notation according to RFC 5234:
<https://www.rfc-editor.org/rfc/rfc5234>
Note: Generators should always use a conservative, human readable subset (that
follows the example in the specification).

The data is processed by this library as octet stream with arbitrary terminal
values. This means that all octets are supported inside quoted strings (except
the delimiting double quote itself).
The C data type "unsigned int" is used by this library for the nonterminal
symbol <number>. This means the accepted range is at least 0...2^16-1.

Note that <white_space> contains all C0 control characters and is optional.

Toplevel map list
-----------------

    umapinfo_list  = *map    ; Empty list is valid
    map            = [white_space] "MAP" [white_space] map_name data_block
    white_space    = 1*(CTL / SP)
                     ; CTL and SP from RFC 5234 Appendix B
    map_name       =  map_name_doom1 | map_name_doom2
    map_name_doom1 = "MAP" number
    map_name_doom2 = "E" number "M" number
    number         = 1*DIGIT    ; DIGIT from RFC 5234 Appendix B

Data block associated with each map list entry
----------------------------------------------

    data_block  = [white_space] obrace expr_list cbrace [white_space]
    obrace      = %x7B    ; Opening brace
    cbrace      = %x7D    ; Closing brace
    expr_list   = *assign_expr    ; Empty list is valid
    assign_expr = [white_space] keyword equal value_list [white_space]
    keyword     = "levelname" / "label" / "author" / "levelpic" / "next" /
                  "nextsecret" / "skytexture" / "music" / "exitpic" /
                  "enterpic" / "partime" / "endgame" / "endpic" / "endbunny" /
                  "endcast" / "nointermission" / "intertext" /
                  "intertextsecret" / "interbackdrop" / "intermusic" /
                  "episode" / "bossaction"
    equal       = [white_space] %x3D [white_space]
    value_list  = value *(comma value)    ; Empty list is invalid
    value       = string / number / identifier
    comma       = [white_space] %x2C [white_space]

Values for keys
---------------

    string        = 1*quoted_string    ; Concatenation is allowed
    quoted_string = DQUOTE *string_octet DQUOTE
                    ; DQUOTE from RFC 5234 Appendix B
    string_octet  = %x00-21 / %x23-FF    ; All octets except DQUOTE
    identifier    = "true" / "false" / "clear" / thing_type

Thingtypes
----------

    thing_type = "DoomPlayer" / "ZombieMan" / "ShotgunGuy" / "Archvile" /
                 "ArchvileFire" / "Revenant" / "RevenantTracer" /
                 "RevenantTracerSmoke" / "Fatso" / "FatShot" / "ChaingunGuy" /
                 "DoomImp" / "Demon" / "Spectre" / "Cacodemon" / "BaronOfHell" /
                 "BaronBall" / "HellKnight" / "LostSoul" / "SpiderMastermind" /
                 "Arachnotron" / "Cyberdemon" / "PainElemental" /
                 "WolfensteinSS" / "CommanderKeen" / "BossBrain" / "BossEye" /
                 "BossTarget" / "SpawnShot" / "SpawnFire" / "ExplosiveBarrel" /
                 "DoomImpBall" / "CacodemonBall" / "Rocket" / "PlasmaBall" /
                 "BFGBall" / "ArachnotronPlasma" / "BulletPuff" / "Blood" /
                 "TeleportFog" / "ItemFog" / "TeleportDest" / "BFGExtra" /
                 "GreenArmor" / "BlueArmor" / "HealthBonus" / "ArmorBonus" /
                 "BlueCard" / "RedCard" / "YellowCard" / "YellowSkull" /
                 "RedSkull" / "BlueSkull" / "Stimpack" / "Medikit" /
                 "Soulsphere" / "InvulnerabilitySphere" / "Berserk" /
                 "BlurSphere" / "RadSuit" / "Allmap" / "Infrared" /
                 "Megasphere" / "Clip" / "ClipBox" / "RocketAmmo" /
                 "RocketBox" / "Cell" / "CellPack" / "Shell" / "ShellBox" /
                 "Backpack" / "BFG9000" / "Chaingun" / "Chainsaw" /
                 "RocketLauncher" / "PlasmaRifle" / "Shotgun" / "SuperShotgun" /
                 "TechLamp" / "TechLamp2" / "Column" / "TallGreenColumn" /
                 "ShortGreenColumn" / "TallRedColumn" / "ShortRedColumn" /
                 "SkullColumn" / "HeartColumn" / "EvilEye" / "FloatingSkull" /
                 "TorchTree" / "BlueTorch" / "GreenTorch" / "RedTorch" /
                 "ShortBlueTorch" / "ShortGreenTorch" / "ShortRedTorch" /
                 "Stalagtite" / "TechPillar" / "CandleStick" / "Candelabra" /
                 "BloodyTwitch" / "Meat2" / "Meat3" / "Meat4" / "Meat5" /
                 "NonsolidMeat2" / "NonsolidMeat4" / "NonsolidMeat3" /
                 "NonsolidMeat5" / "NonsolidTwitch" / "DeadCacodemon" /
                 "DeadMarine" / "DeadZombieMan" / "DeadDemon" / "DeadLostSoul" /
                 "DeadDoomImp" / "DeadShotgunGuy" / "GibbedMarine" /
                 "GibbedMarineExtra" / "HeadsOnAStick" / "Gibs" /
                 "HeadOnAStick" / "HeadCandles" / "DeadStick" / "LiveStick" /
                 "BigTree" / "BurningBarrel" / "HangNoGuts" / "HangBNoBrain" /
                 "HangTLookingDown" / "HangTSkull" / "HangTLookingUp" /
                 "HangTNoBrain" / "ColonGibs" / "SmallBloodPool" / "BrainStem" /
                 "PointPusher" / "PointPuller" / "MBFHelperDog" /
                 "PlasmaBall1" / "PlasmaBall2" / "EvilSceptre" / "UnholyBible" /
                 "MusicChanger" / deh_actor
    deh_actor  = "Deh_Actor_" deh_num
    deh_num    = (%x31 %x34 %x35-39) / (%x31 %x35-39 %x30-39) /
                 (%x32 %x30-34 %x30-39)    ; DEH actor number range: 145-249

EOF

Generated using  doxygen