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
|
#include "stack.h"
#include <stdlib.h>
#include <assert.h>
#include <err.h>
void
varbuf_begin(struct varbuf *var)
{
assert(var);
var->offset = var->buf.written;
assert(var->offset <= var->buf.mem.len);
}
void
varbuf_reset(struct varbuf *var)
{
assert(var);
var->offset = var->buf.written = 0;
}
void
varbuf_remove_last(struct varbuf *var)
{
assert(var);
assert(var->buf.written >= var->offset);
const size_t size = var->buf.written - var->offset;
assert(var->buf.written >= size);
var->buf.written -= size;
assert(var->buf.written <= var->buf.mem.len);
}
static void
stack_check_type(const struct stack *stack, const enum stack_type type)
{
assert(stack);
if (stack->type == type)
return;
const char *got = (type == STACK_STR ? "str" : "num"), *expected = (stack->type == STACK_STR ? "str" : "num");
errx(EXIT_FAILURE, "tried to get '%s' from stack, but the last pushed type was '%s'", got, expected);
}
const struct escpos_mem*
stack_get_str(const struct stack *stack)
{
stack_check_type(stack, STACK_STR);
return &stack->str;
}
uint8_t
stack_get_num(const struct stack *stack)
{
stack_check_type(stack, STACK_NUM);
return stack->num;
}
%%{
machine escpos_stack;
alphtype unsigned char;
action stack_num {
const char *byte = (char*)stack.var.buf.mem.data + stack.var.offset;
stack.type = STACK_NUM;
stack.num = *byte;
varbuf_remove_last(&stack.var);
}
action stack_str {
membuf_terminate(&stack.var.buf, (char[]){ 0 }, 1);
stack.type = STACK_STR;
stack.str = stack.var.buf.mem;
stack.str.len = stack.var.buf.written;
}
action store {
membuf_append(&stack.var.buf, fpc, 1);
}
action begin_num {
varbuf_begin(&stack.var);
}
action begin_str {
varbuf_reset(&stack.var);
}
NUL = 0x00;
TEXT = (32..244 - 192..193);
stack_num = 0..255 >begin_num $store %stack_num;
stack_str = TEXT* $store >begin_str :>> NUL %stack_str;
}%%
|