#include "stack.h" #include #include #include 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; }%%