~rbdr/wmap-parser-c

A parser for wmap formatted Wardley Map files in ANSI C #library
924d5bcc — Ruben Beltran del Rio 2 months ago
Fix a issues with assumptions regarding coordinate system
4c222dd2 — Ruben Beltran del Rio 3 months ago
Update README
1fec7e9f — Ruben Beltran del Rio 3 months ago
Improve performance

clone

read-only
https://git.sr.ht/~rbdr/wmap-parser-c
read/write
git@git.sr.ht:~rbdr/wmap-parser-c

You can also use your local clone with git send-email.

#WMAP Parser for C

A parser for wmap formatted Wardley Map files in ANSI C.

#Features

  • ANSI C Compatible. Should work with ANSI compatible compilers. (e.g THINK C 5 for 68k macs)
  • Single .h/.c that's easy to include.
  • Free software.
  • Reasonably Fast.

#Usage

#include <wmap_parser.h>

int main() {
    // Parse from file. (See also: wmap_parse_string)
    wmap_map_t* map = wmap_parse_file("example.wmap");
    if (!map) {
        printf("Failed to parse file\n");
        return 1;
    }

    // Access parsed data
    printf("Components: %d\n", map->component_count);
    printf("Dependencies: %d\n", map->dependency_count);

    // Access individual components
    for (int i = 0; i < map->component_count; i++) {
        printf("Component: %s at (%.2f, %.2f)\n",
               map->components[i].name,
               map->components[i].x,
               map->components[i].y);
    }

    // Clean up
    wmap_map_free(map);
    return 0;
}

#Build Instructions

make              # Build release version -> ./build/release/
make debug        # Build debug version -> ./build/debug/

#Format Specification

See The map website for more information on the format.

#Reasonably Fast

Benchmarked on an M1 Pro mac. A map with around 120 entities parses in 7µs. While a larger map with slightly under 2000 entities does so in 155µs.

You can run the benchmarks by using:

make benchmark

You can specify how many iterations.

make -e ITERATIONS=1000 benchmark  # Custom iteration count

#Running Tests

make test

#More Commands

make memtest      # Memory leak testing (uses debug build)
make clean        # Remove all build artifacts (./build/ directory)
make info         # Show build configuration and available targets

#Memory Limits

Entity Type Maximum Count
Components 1024
Dependencies 2048
Notes 256
Groups 128
Inertias 256
Evolutions 256
Name Length 64 characters
Text Length 256 characters

#API Reference

#Core Functions

// Parse from string
wmap_map_t* wmap_parse_string(const char* input);

// Parse from file
wmap_map_t* wmap_parse_file(const char* filename);

// Free parsed map
void wmap_map_free(wmap_map_t* map);

// Validate input size and format
int wmap_validate_input(const char* input, size_t max_size);

#Data Structures

typedef struct {
    wmap_component_t components[WMAP_MAX_COMPONENTS];
    wmap_dependency_t dependencies[WMAP_MAX_DEPENDENCIES];
    wmap_note_t notes[WMAP_MAX_NOTES];
    wmap_stage_data_t stages[WMAP_MAX_STAGES];
    wmap_group_t groups[WMAP_MAX_GROUPS];
    wmap_inertia_t inertias[WMAP_MAX_INERTIAS];
    wmap_evolution_t evolutions[WMAP_MAX_EVOLUTIONS];

    int component_count;
    int dependency_count;
    // ... other counts
} wmap_map_t;

#Component Structure

typedef struct {
    char name[64];        // Component name
    float x, y;           // Position coordinates
    wmap_shape_t shape;   // Shape (NONE, X, SQUARE, TRIANGLE, CIRCLE)
} wmap_component_t;

#Dependency Structure

typedef struct {
    char from[64];        // Source component name
    char to[64];          // Target component name
    int is_arrow;         // 1 for ->, 0 for --
} wmap_dependency_t;

#Error Handling

  • Functions return NULL on failure
  • Input validation prevents buffer overflows
  • Malformed lines are skipped, parsing continues
  • File size limits prevent excessive memory usage

#See Also