summaryrefslogtreecommitdiff
path: root/src/escpos/stack.rl
diff options
context:
space:
mode:
Diffstat (limited to 'src/escpos/stack.rl')
-rw-r--r--src/escpos/stack.rl92
1 files changed, 92 insertions, 0 deletions
diff --git a/src/escpos/stack.rl b/src/escpos/stack.rl
new file mode 100644
index 0000000..a051318
--- /dev/null
+++ b/src/escpos/stack.rl
@@ -0,0 +1,92 @@
+#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;
+
+ 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..127;
+
+ stack_num = -128..127 >begin_num $store %stack_num;
+ stack_str = TEXT* $store >begin_str :>> NUL %stack_str;
+}%%