Barely working ansi color codes parser but I _really_ don't like this one. Too much code to just get it to process correctly which means it'll be brittle as hell later.

main
Zed A. Shaw 10 months ago
parent a44a9a04f9
commit f32b39afe2
  1. 1
      Makefile
  2. 302
      ansi_parser.cpp
  3. 4
      ansi_parser.hpp
  4. 99
      ansi_parser.rl
  5. 14
      meson.build
  6. 240
      scratchpad/testragel.cpp
  7. 52
      scratchpad/testragel.rl
  8. 2
      status.txt
  9. 59
      tests/ansi_parser.cpp

@ -5,6 +5,7 @@ reset:
ragel:
ragel -o .\scratchpad\testragel.cpp .\scratchpad\testragel.rl
ragel -o .\ansi_parser.cpp .\ansi_parser.rl
build:
meson compile -j 4 -C builddir

@ -0,0 +1,302 @@
#line 1 ".\\ansi_parser.rl"
#include <fmt/core.h>
#include <string_view>
#include <charconv>
#include "dbc.hpp"
using namespace fmt;
#line 80 ".\\ansi_parser.rl"
#line 11 ".\\ansi_parser.cpp"
static const char _foo_actions[] = {
0, 1, 0, 1, 1, 1, 8, 1,
9, 1, 10, 2, 1, 2, 2, 1,
3, 2, 1, 4, 2, 1, 5, 2,
6, 0, 2, 7, 0, 2, 9, 0,
2, 10, 8
};
static const char _foo_key_offsets[] = {
0, 0, 1, 2, 7, 11, 13, 16,
21, 25, 29, 33, 35, 38, 40, 43,
45, 48, 52, 54, 57, 59, 62, 67,
71, 75, 76
};
static const char _foo_trans_keys[] = {
27, 91, 51, 52, 109, 48, 57, 59,
109, 48, 57, 48, 57, 109, 48, 57,
56, 59, 109, 48, 57, 59, 109, 48,
57, 50, 53, 48, 57, 59, 109, 48,
57, 48, 57, 59, 48, 57, 48, 57,
59, 48, 57, 48, 57, 109, 48, 57,
59, 109, 48, 57, 48, 57, 59, 48,
57, 48, 57, 109, 48, 57, 56, 59,
109, 48, 57, 59, 109, 48, 57, 50,
53, 48, 57, 27, 27, 0
};
static const char _foo_single_lengths[] = {
0, 1, 1, 3, 2, 0, 1, 3,
2, 2, 2, 0, 1, 0, 1, 0,
1, 2, 0, 1, 0, 1, 3, 2,
2, 1, 1
};
static const char _foo_range_lengths[] = {
0, 0, 0, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 0
};
static const char _foo_index_offsets[] = {
0, 0, 2, 4, 9, 13, 15, 18,
23, 27, 31, 35, 37, 40, 42, 45,
47, 50, 54, 56, 59, 61, 64, 69,
73, 77, 79
};
static const char _foo_trans_targs[] = {
2, 1, 3, 0, 7, 22, 26, 4,
0, 5, 26, 4, 0, 6, 0, 26,
6, 0, 8, 5, 26, 4, 0, 9,
26, 4, 0, 10, 17, 6, 0, 11,
26, 6, 0, 12, 0, 13, 12, 0,
14, 0, 15, 14, 0, 16, 0, 26,
16, 0, 18, 26, 6, 0, 19, 0,
20, 19, 0, 21, 0, 26, 21, 0,
23, 5, 26, 4, 0, 24, 26, 4,
0, 10, 17, 6, 0, 2, 1, 2,
1, 0
};
static const char _foo_trans_actions[] = {
0, 5, 0, 0, 29, 29, 7, 29,
0, 3, 17, 0, 0, 1, 0, 20,
0, 0, 0, 3, 17, 0, 0, 3,
17, 0, 0, 26, 26, 1, 0, 0,
20, 0, 0, 1, 0, 3, 0, 0,
1, 0, 3, 0, 0, 1, 0, 14,
0, 0, 0, 20, 0, 0, 1, 0,
3, 0, 0, 1, 0, 11, 0, 0,
0, 3, 17, 0, 0, 3, 17, 0,
0, 23, 23, 1, 0, 0, 5, 9,
32, 0
};
static const char _foo_eof_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 9
};
static const int foo_start = 25;
static const int foo_first_final = 25;
static const int foo_error = 0;
static const int foo_en_main = 25;
#line 83 ".\\ansi_parser.rl"
bool parse_ansi(std::string_view codes) {
const char *start = NULL;
int cs = 0;
size_t value = 0;
const char *p = codes.data();
const char *pe = p + codes.size();
const char *eof = pe;
#line 111 ".\\ansi_parser.cpp"
{
cs = foo_start;
}
#line 94 ".\\ansi_parser.rl"
#line 114 ".\\ansi_parser.cpp"
{
int _klen;
unsigned int _trans;
const char *_acts;
unsigned int _nacts;
const char *_keys;
if ( p == pe )
goto _test_eof;
if ( cs == 0 )
goto _out;
_resume:
_keys = _foo_trans_keys + _foo_key_offsets[cs];
_trans = _foo_index_offsets[cs];
_klen = _foo_single_lengths[cs];
if ( _klen > 0 ) {
const char *_lower = _keys;
const char *_mid;
const char *_upper = _keys + _klen - 1;
while (1) {
if ( _upper < _lower )
break;
_mid = _lower + ((_upper-_lower) >> 1);
if ( (*p) < *_mid )
_upper = _mid - 1;
else if ( (*p) > *_mid )
_lower = _mid + 1;
else {
_trans += (unsigned int)(_mid - _keys);
goto _match;
}
}
_keys += _klen;
_trans += _klen;
}
_klen = _foo_range_lengths[cs];
if ( _klen > 0 ) {
const char *_lower = _keys;
const char *_mid;
const char *_upper = _keys + (_klen<<1) - 2;
while (1) {
if ( _upper < _lower )
break;
_mid = _lower + (((_upper-_lower) >> 1) & ~1);
if ( (*p) < _mid[0] )
_upper = _mid - 2;
else if ( (*p) > _mid[1] )
_lower = _mid + 2;
else {
_trans += (unsigned int)((_mid - _keys)>>1);
goto _match;
}
}
_trans += _klen;
}
_match:
cs = _foo_trans_targs[_trans];
if ( _foo_trans_actions[_trans] == 0 )
goto _again;
_acts = _foo_actions + _foo_trans_actions[_trans];
_nacts = (unsigned int) *_acts++;
while ( _nacts-- > 0 )
{
switch ( *_acts++ )
{
case 0:
#line 11 ".\\ansi_parser.rl"
{
start = p;
}
break;
case 1:
#line 15 ".\\ansi_parser.rl"
{
auto [ptr, ec] = std::from_chars(start, p, value);
dbc::check(ec == std::errc(), "error in number parsing");
println("NUM: {}", value);
}
break;
case 2:
#line 21 ".\\ansi_parser.rl"
{
println("COLOR256");
}
break;
case 3:
#line 25 ".\\ansi_parser.rl"
{
println("COLOR24B");
}
break;
case 4:
#line 29 ".\\ansi_parser.rl"
{
println("SINGLE");
}
break;
case 5:
#line 33 ".\\ansi_parser.rl"
{
println("BASIC");
}
break;
case 6:
#line 37 ".\\ansi_parser.rl"
{
println("BG");
}
break;
case 7:
#line 41 ".\\ansi_parser.rl"
{
println("FG");
}
break;
case 8:
#line 45 ".\\ansi_parser.rl"
{
println("ANY: {}:{}", int((*p)), (*p));
}
break;
case 9:
#line 49 ".\\ansi_parser.rl"
{
println("START");
}
break;
case 10:
#line 53 ".\\ansi_parser.rl"
{
println("END");
}
break;
#line 243 ".\\ansi_parser.cpp"
}
}
_again:
if ( cs == 0 )
goto _out;
if ( ++p != pe )
goto _resume;
_test_eof: {}
if ( p == eof )
{
const char *__acts = _foo_actions + _foo_eof_actions[cs];
unsigned int __nacts = (unsigned int) *__acts++;
while ( __nacts-- > 0 ) {
switch ( *__acts++ ) {
case 10:
#line 53 ".\\ansi_parser.rl"
{
println("END");
}
break;
#line 263 ".\\ansi_parser.cpp"
}
}
}
_out: {}
}
#line 95 ".\\ansi_parser.rl"
print("PROCESSED {} CHARS of {}", p - codes.data(), codes.size());
return true;
}

@ -0,0 +1,4 @@
#pragma once
#include <string_view>
bool parse_ansi(std::string_view codes);

@ -0,0 +1,99 @@
#include <fmt/core.h>
#include <string_view>
#include <charconv>
#include "dbc.hpp"
using namespace fmt;
%%{
machine foo;
action tstart {
start = fpc;
}
action number {
auto [ptr, ec] = std::from_chars(start, fpc, value);
dbc::check(ec == std::errc(), "error in number parsing");
println("NUM: {}", value);
}
action color256 {
println("COLOR256");
}
action color24b {
println("COLOR24B");
}
action colorSingle {
println("SINGLE");
}
action colorBasic {
println("BASIC");
}
action bg {
println("BG");
}
action fg {
println("FG");
}
action any {
println("ANY: {}:{}", int(fc), fc);
}
action start {
println("START");
}
action end {
println("END");
}
start = 0x1B "[";
fg = "38;" %fg;
bg = "48;" %bg;
num = digit+ >tstart %number;
color256 = "5;" num ";" num;
color24b = "2;" num ";" num ";" num;
basic = num ";" num;
single = num;
colorCode = (
start %start
(
(fg|bg) color256 %color256 |
(fg|bg) color24b %color24b |
single %colorSingle |
basic %colorBasic
)**
"m" %end
);
other = (any+ @any -- 0x1B)*;
main := (other :>> colorCode)**;
}%%
%% write data;
bool parse_ansi(std::string_view codes) {
const char *start = NULL;
int cs = 0;
size_t value = 0;
const char *p = codes.data();
const char *pe = p + codes.size();
const char *eof = pe;
%% write init;
%% write exec;
print("PROCESSED {} CHARS of {}", p - codes.data(), codes.size());
return true;
}

@ -19,13 +19,15 @@ runtests = executable('runtests', [
'rand.cpp',
'sound.cpp',
'collider.cpp',
'ansi_parser.cpp',
'render.cpp',
'tests/fsm.cpp',
'tests/dbc.cpp',
'tests/map.cpp',
'tests/collider.cpp',
'tests/sound.cpp',
'tests/dinkyecs.cpp',
#'tests/fsm.cpp',
#'tests/dbc.cpp',
#'tests/map.cpp',
#'tests/collider.cpp',
#'tests/sound.cpp',
#'tests/dinkyecs.cpp',
'tests/ansi_parser.cpp',
],
dependencies: dependencies)

@ -10,148 +10,121 @@
using namespace fmt;
#line 42 ".\\scratchpad\\testragel.rl"
#line 66 ".\\scratchpad\\testragel.rl"
#line 13 ".\\scratchpad\\testragel.cpp"
static const char _foo_actions[] = {
0, 1, 0, 1, 1, 1, 2, 1,
3, 1, 4, 2, 1, 5, 2, 1,
6, 2, 1, 7, 2, 1, 8, 2,
1, 9, 2, 1, 10
0, 1, 0, 1, 1, 1, 8, 1,
9, 2, 1, 2, 2, 1, 3, 2,
1, 4, 2, 1, 5, 2, 6, 0,
2, 7, 0, 2, 8, 0
};
static const char _foo_key_offsets[] = {
0, 0, 1, 5, 7, 10, 15, 19,
23, 27, 29, 32, 34, 37, 39, 42,
46, 48, 51, 53, 56, 61, 65, 69,
73, 75, 78, 80, 83, 85, 88, 92,
94, 97, 99, 102
0, 0, 1, 6, 10, 12, 15, 20,
24, 28, 32, 34, 37, 39, 42, 44,
47, 51, 53, 56, 58, 61, 66, 70,
74, 75
};
static const char _foo_trans_keys[] = {
91, 59, 109, 48, 57, 48, 57, 109,
48, 57, 56, 59, 109, 48, 57, 59,
109, 48, 57, 50, 53, 48, 57, 59,
91, 51, 52, 109, 48, 57, 59, 109,
48, 57, 48, 57, 109, 48, 57, 56,
59, 109, 48, 57, 59, 109, 48, 57,
50, 53, 48, 57, 59, 109, 48, 57,
48, 57, 59, 48, 57, 48, 57, 59,
48, 57, 48, 57, 109, 48, 57, 59,
109, 48, 57, 48, 57, 59, 48, 57,
48, 57, 59, 48, 57, 48, 57, 109,
48, 57, 59, 109, 48, 57, 48, 57,
59, 48, 57, 48, 57, 109, 48, 57,
56, 59, 109, 48, 57, 59, 109, 48,
57, 50, 53, 48, 57, 59, 109, 48,
57, 48, 57, 59, 48, 57, 48, 57,
59, 48, 57, 48, 57, 109, 48, 57,
59, 109, 48, 57, 48, 57, 59, 48,
57, 48, 57, 109, 48, 57, 27, 51,
52, 48, 57, 0
48, 57, 109, 48, 57, 56, 59, 109,
48, 57, 59, 109, 48, 57, 50, 53,
48, 57, 27, 27, 0
};
static const char _foo_single_lengths[] = {
0, 1, 2, 0, 1, 3, 2, 2,
2, 0, 1, 0, 1, 0, 1, 2,
0, 1, 0, 1, 3, 2, 2, 2,
0, 1, 0, 1, 0, 1, 2, 0,
1, 0, 1, 3
0, 1, 3, 2, 0, 1, 3, 2,
2, 2, 0, 1, 0, 1, 0, 1,
2, 0, 1, 0, 1, 3, 2, 2,
1, 1
};
static const char _foo_range_lengths[] = {
0, 0, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1
0, 0
};
static const unsigned char _foo_index_offsets[] = {
0, 0, 2, 6, 8, 11, 16, 20,
24, 28, 30, 33, 35, 38, 40, 43,
47, 49, 52, 54, 57, 62, 66, 70,
74, 76, 79, 81, 84, 86, 89, 93,
95, 98, 100, 103
static const char _foo_index_offsets[] = {
0, 0, 2, 7, 11, 13, 16, 21,
25, 29, 33, 35, 38, 40, 43, 45,
48, 52, 54, 57, 59, 62, 67, 71,
75, 77
};
static const char _foo_trans_targs[] = {
35, 0, 3, 35, 2, 0, 4, 0,
35, 4, 0, 6, 3, 35, 2, 0,
7, 35, 2, 0, 8, 15, 4, 0,
9, 35, 4, 0, 10, 0, 11, 10,
0, 12, 0, 13, 12, 0, 14, 0,
35, 14, 0, 16, 35, 4, 0, 17,
0, 18, 17, 0, 19, 0, 35, 19,
0, 21, 3, 35, 2, 0, 22, 35,
2, 0, 23, 30, 4, 0, 24, 35,
4, 0, 25, 0, 26, 25, 0, 27,
0, 28, 27, 0, 29, 0, 35, 29,
0, 31, 35, 4, 0, 32, 0, 33,
32, 0, 34, 0, 35, 34, 0, 1,
5, 20, 2, 0, 0
static const char _foo_indicies[] = {
0, 1, 3, 4, 5, 2, 1, 7,
8, 6, 1, 9, 1, 11, 10, 1,
12, 7, 8, 6, 1, 13, 8, 6,
1, 14, 15, 9, 1, 16, 11, 10,
1, 17, 1, 19, 18, 1, 20, 1,
22, 21, 1, 23, 1, 25, 24, 1,
26, 11, 10, 1, 27, 1, 29, 28,
1, 30, 1, 32, 31, 1, 33, 7,
8, 6, 1, 34, 8, 6, 1, 35,
36, 9, 1, 37, 1, 38, 1, 0
};
static const char _foo_trans_actions[] = {
9, 0, 3, 23, 0, 0, 1, 0,
26, 0, 0, 0, 3, 23, 0, 0,
3, 23, 0, 0, 1, 1, 1, 0,
0, 26, 0, 0, 1, 0, 3, 0,
0, 1, 0, 3, 0, 0, 1, 0,
17, 0, 0, 0, 26, 0, 0, 1,
0, 3, 0, 0, 1, 0, 11, 0,
0, 0, 3, 23, 0, 0, 3, 23,
0, 0, 1, 1, 1, 0, 0, 26,
0, 0, 1, 0, 3, 0, 0, 1,
0, 3, 0, 0, 1, 0, 20, 0,
0, 0, 26, 0, 0, 1, 0, 3,
0, 0, 1, 0, 14, 0, 0, 0,
1, 1, 1, 0, 0
static const char _foo_trans_targs[] = {
2, 0, 3, 6, 21, 25, 3, 4,
25, 5, 5, 25, 7, 8, 9, 16,
10, 11, 11, 12, 13, 13, 14, 15,
15, 25, 17, 18, 18, 19, 20, 20,
25, 22, 23, 9, 16, 1, 1
};
static const char _foo_to_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 5
static const char _foo_trans_actions[] = {
0, 0, 27, 27, 27, 5, 0, 3,
15, 1, 0, 18, 0, 3, 24, 24,
0, 1, 0, 3, 1, 0, 3, 1,
0, 12, 0, 1, 0, 3, 1, 0,
9, 0, 3, 21, 21, 0, 7
};
static const char _foo_from_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
static const char _foo_eof_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 7
0, 7
};
static const int foo_start = 35;
static const int foo_first_final = 35;
static const int foo_start = 24;
static const int foo_first_final = 24;
static const int foo_error = 0;
static const int foo_en_main = 35;
static const int foo_en_main = 24;
#line 45 ".\\scratchpad\\testragel.rl"
#line 69 ".\\scratchpad\\testragel.rl"
void parse_ansi(std::string_view &codes) {
const char *start = NULL;
int cs = 0;
size_t act = 0;
size_t value = 0;
const char *p = codes.data();
const char *pe = p + codes.size();
const char *ts = p;
const char *te = pe;
const char *eof = pe;
#line 136 ".\\scratchpad\\testragel.cpp"
#line 112 ".\\scratchpad\\testragel.cpp"
{
cs = foo_start;
ts = 0;
te = 0;
act = 0;
}
#line 57 ".\\scratchpad\\testragel.rl"
#line 79 ".\\scratchpad\\testragel.rl"
#line 142 ".\\scratchpad\\testragel.cpp"
#line 115 ".\\scratchpad\\testragel.cpp"
{
int _klen;
unsigned int _trans;
@ -164,18 +137,6 @@ void parse_ansi(std::string_view &codes) {
if ( cs == 0 )
goto _out;
_resume:
_acts = _foo_actions + _foo_from_state_actions[cs];
_nacts = (unsigned int) *_acts++;
while ( _nacts-- > 0 ) {
switch ( *_acts++ ) {
case 3:
#line 1 "NONE"
{ts = p;}
break;
#line 161 ".\\scratchpad\\testragel.cpp"
}
}
_keys = _foo_trans_keys + _foo_key_offsets[cs];
_trans = _foo_index_offsets[cs];
@ -225,6 +186,7 @@ _resume:
}
_match:
_trans = _foo_indicies[_trans];
cs = _foo_trans_targs[_trans];
if ( _foo_trans_actions[_trans] == 0 )
@ -245,66 +207,84 @@ _match:
case 1:
#line 17 ".\\scratchpad\\testragel.rl"
{
size_t value = 0;
auto [ptr, ec] = std::from_chars(start, p, value);
dbc::check(ec == std::errc(), "error in number parsing");
println("NUMBER {}", value);
}
break;
case 2:
#line 23 ".\\scratchpad\\testragel.rl"
{
println("256 color");
}
break;
case 3:
#line 27 ".\\scratchpad\\testragel.rl"
{
println("true color");
}
break;
case 4:
#line 34 ".\\scratchpad\\testragel.rl"
{te = p+1;{ println("START"); }}
#line 31 ".\\scratchpad\\testragel.rl"
{
println("single color");
}
break;
case 5:
#line 35 ".\\scratchpad\\testragel.rl"
{te = p+1;{ println("fg 256 color"); }}
{
println("basic color");
}
break;
case 6:
#line 36 ".\\scratchpad\\testragel.rl"
{te = p+1;{ println("bg 256 color"); }}
#line 39 ".\\scratchpad\\testragel.rl"
{
println("BG");
}
break;
case 7:
#line 37 ".\\scratchpad\\testragel.rl"
{te = p+1;{ println("fg true color"); }}
#line 43 ".\\scratchpad\\testragel.rl"
{
println("FG");
}
break;
case 8:
#line 38 ".\\scratchpad\\testragel.rl"
{te = p+1;{ println("bg true color"); }}
#line 57 ".\\scratchpad\\testragel.rl"
{ println("START"); }
break;
case 9:
#line 39 ".\\scratchpad\\testragel.rl"
{te = p+1;{ println("single"); }}
break;
case 10:
#line 40 ".\\scratchpad\\testragel.rl"
{te = p+1;{ println("basic"); }}
#line 64 ".\\scratchpad\\testragel.rl"
{ println("END"); }
break;
#line 258 ".\\scratchpad\\testragel.cpp"
#line 236 ".\\scratchpad\\testragel.cpp"
}
}
_again:
_acts = _foo_actions + _foo_to_state_actions[cs];
_nacts = (unsigned int) *_acts++;
while ( _nacts-- > 0 ) {
switch ( *_acts++ ) {
case 2:
#line 1 "NONE"
{ts = 0;}
break;
#line 269 ".\\scratchpad\\testragel.cpp"
}
}
if ( cs == 0 )
goto _out;
if ( ++p != pe )
goto _resume;
_test_eof: {}
if ( p == eof )
{
const char *__acts = _foo_actions + _foo_eof_actions[cs];
unsigned int __nacts = (unsigned int) *__acts++;
while ( __nacts-- > 0 ) {
switch ( *__acts++ ) {
case 9:
#line 64 ".\\scratchpad\\testragel.rl"
{ println("END"); }
break;
#line 254 ".\\scratchpad\\testragel.cpp"
}
}
}
_out: {}
}
#line 58 ".\\scratchpad\\testragel.rl"
#line 80 ".\\scratchpad\\testragel.rl"
}
int main() {

@ -15,30 +15,54 @@ using namespace fmt;
}
action number {
size_t value = 0;
auto [ptr, ec] = std::from_chars(start, fpc, value);
dbc::check(ec == std::errc(), "error in number parsing");
println("NUMBER {}", value);
}
action color256 {
println("256 color");
}
action color24b {
println("true color");
}
action colorSingle {
println("single color");
}
action colorBasic {
println("basic color");
}
action bg {
println("BG");
}
action fg {
println("FG");
}
start = 0x1B "[";
fg = "38;";
bg = "48;";
fg = "38;" %fg;
bg = "48;" %bg;
num = digit+ >tstart %number;
color256 = "5;" num ";" num;
color24b = "2;" num ";" num ";" num;
basic = num ";" num;
single = num;
main := |*
start => { println("START"); };
fg color256 "m" => { println("fg 256 color"); };
bg color256 "m" => { println("bg 256 color"); };
fg color24b "m" => { println("fg true color"); };
bg color24b "m" => { println("bg true color"); };
single "m" => { println("single"); };
basic "m" => { println("basic"); };
*|;
main := (
start %{ println("START"); }
(
(fg|bg) color256 %color256 |
(fg|bg) color24b %color24b |
single %colorSingle |
basic %colorBasic
)**
"m" %{ println("END"); }
)**;
}%%
%% write data;
@ -46,11 +70,9 @@ using namespace fmt;
void parse_ansi(std::string_view &codes) {
const char *start = NULL;
int cs = 0;
size_t act = 0;
size_t value = 0;
const char *p = codes.data();
const char *pe = p + codes.size();
const char *ts = p;
const char *te = pe;
const char *eof = pe;
%% write init;

@ -14,6 +14,7 @@ A a(my_enum);
TODO:
* Actually render FTXUI ansi output instead of the gui.cpp hack.
* Rewrite collider to return a real struct not tuple.
* Write a test that generates a ton of maps then confirms there's a path from one room to every other room?
* Lua integration?
@ -21,5 +22,4 @@ TODO:
* BUG: If map is < 90 zome out crashes.
* Simple loot system.
* Actually render FTXUI ansi output instead of the gui.cpp hack.
* Bring back sounds, check out SoLoud.

@ -0,0 +1,59 @@
#include <catch2/catch_test_macros.hpp>
#include <fmt/core.h>
#include <string>
#include "ansi_parser.hpp"
#include "ftxui/dom/elements.hpp" // for text, bgcolor, color, vbox, hbox, separator, operator|, Elements, Element, Fit, border
#include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/color.hpp" // for Color, Color::Black, Color::Blue, Color::BlueLight, Color::Cyan, Color::CyanLight, Color::Default, Color::GrayDark, Color::GrayLight, Color::Green, Color::GreenLight, Color::Magenta, Color::MagentaLight, Color::Red, Color::RedLight, Color::White, Color::Yellow, Color::YellowLight, Color::Palette256, ftxui
#include <ftxui/screen/color_info.hpp> // for ColorInfo
#include <ftxui/screen/screen.hpp> // for Full, Screen
#include <ftxui/screen/terminal.hpp> // for ColorSupport, Color, Palette16, Palette256, TrueColor
using namespace fmt;
using namespace ftxui;
std::string generate_colors() {
const int max_value = 255;
const int value_increment = 8;
const int hue_increment = 6;
int saturation = max_value;
Elements array;
int count = 0;
for (int value = 0; value < max_value; value += 2 * value_increment) {
Elements line;
for (int hue = 0; hue < max_value; hue += hue_increment) {
line.push_back(
text("#") //
| color(Color::HSV(hue, saturation, value)) //
| bgcolor(Color::HSV(hue, saturation, value + value_increment)));
count++;
}
array.push_back(hbox(std::move(line)));
break; /// UNDO ME
}
println("MADE {} CHARS", count);
auto true_color_display = vbox({
vbox(std::move(array)),
});
auto document = vbox({hbox({
true_color_display,
})});
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
Render(screen, document);
return screen.ToString();
}
TEST_CASE("test out ragel parser", "[gui]") {
std::string colors = generate_colors();
println("--- PARSING");
REQUIRE(parse_ansi(colors));
}