aboutsummaryrefslogtreecommitdiff
path: root/README.md
blob: cbba1418d07b50077d1c5c519bbf4eb91a76e119 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# 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

```c
#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

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


## Format Specification

See [The map website](https://map.tranquil.systems) 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:

```bash
make benchmark
```

You can specify how many iterations.

```bash
make -e ITERATIONS=1000 benchmark  # Custom iteration count
```
## Running Tests

```bash
make test
```

## More Commands
```bash
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

```c
// 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

```c
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
```c
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
```c
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

- [wmap specification](doc/wmap-spec.ebnf) - Formal grammar
- [wmap specification](https://git.sr.ht:~rbdr/wmap-parser-js) - Javascript wmap-parser
- [wmap specification](https://git.sr.ht:~rbdr/wmap-parser-rust) - Rust wmap-parser
- [wmap specification](https://git.sr.ht:~rbdr/wmap-parser-swift) - Swift wmap-parser
- [Wardley Maps](https://wardleymaps.com/) - Learn about Wardley Mapping