diff options
| -rw-r--r-- | include/ql.h | 2 | ||||
| -rw-r--r-- | src/main.c | 2 | ||||
| -rw-r--r-- | src/ql.c | 135 |
3 files changed, 96 insertions, 43 deletions
diff --git a/include/ql.h b/include/ql.h index e1e2b11..bb4dcb6 100644 --- a/include/ql.h +++ b/include/ql.h @@ -149,7 +149,7 @@ bool ql_print_raster_image(ql_ctx_t ctx, const ql_status_t * status, // Caution: ql_decode_*() are *not* multi-thread safe const char *ql_decode_mode(const ql_status_t * status); -const char *ql_decode_errors(const ql_status_t * status); +const char *ql_decode_errors_human(const ql_status_t * status); const char *ql_decode_model(const ql_status_t * status); const char *ql_decode_media_type(const ql_status_t * status); #define QL_DECODE_MODEL 0x01 @@ -285,7 +285,7 @@ for(int i = 0; i < img->height; ++i) if (status.err_info_1 || status.err_info_2) bail_out(&json_ctx, "Printer reported error(s): %s", - ql_decode_errors(&status)); + ql_decode_errors_human(&status)); } while (status.status_type != QL_STATUS_TYPE_PRINTING_DONE); alarm(0); @@ -12,6 +12,7 @@ #include <stdlib.h> #include <string.h> #include <time.h> +#include <assert.h> #define QL_XMIT_SIZE 4096 #define QL_BUF_SIZE (QL_XMIT_SIZE * 2) @@ -315,52 +316,105 @@ const char *ql_decode_mode(const ql_status_t *status) return "no-auto-cut"; } -const char *ql_decode_errors(const ql_status_t *status) -{ - typedef struct { - uint16_t bit; - const char *str; - } strmap_t; +typedef struct { + uint16_t bit; + const char *str; +} strmap_t; #define ERR1(x) (x << 0) #define ERR2(x) (x << 8) - const strmap_t strmap[] = { - {ERR1(QL_ERR_1_NO_MEDIA), "no-media "}, - {ERR1(QL_ERR_1_END_OF_MEDIA), "end-of-media "}, - {ERR1(QL_ERR_1_CUTTER_JAM), "cutter-jam "}, - {ERR1(QL_ERR_1_PRINTER_IN_USE), "printer-in-use "}, - {ERR1(QL_ERR_1_PRINTER_TURNED_OFF), "printer-turned-off "}, - {ERR1(QL_ERR_1_HIGH_VOLTAGE_ADAPTER), "high-voltage-adapter "}, - {ERR1(QL_ERR_1_FAN_MOTOR_ERROR), "fan-motor-error "}, - - {ERR2(QL_ERR_2_REPLACE_MEDIA), "replace-media "}, - {ERR2(QL_ERR_2_EXPANSION_BUFFER_FULL), "expansion-buffer-full "}, - {ERR2(QL_ERR_2_COMMUNICATION_ERROR), "communication-error "}, - {ERR2(QL_ERR_2_COMMUNICATION_BUFFER_FULL), "communication-buffer-full "}, - {ERR2(QL_ERR_2_COVER_OPEN), "cover-open "}, - {ERR2(QL_ERR_2_CANCEL_KEY), "cancel-key-pressed "}, - {ERR2(QL_ERR_2_MEDIA_CANNOT_BE_FED), "media-cannot-be-fed "}, - {ERR2(QL_ERR_2_SYSTEM_ERROR), "system-error "} - }; +static const strmap_t strmap[] = { + {ERR1(QL_ERR_1_NO_MEDIA), "no-media"}, + {ERR1(QL_ERR_1_END_OF_MEDIA), "end-of-media"}, + {ERR1(QL_ERR_1_CUTTER_JAM), "cutter-jam"}, + {ERR1(QL_ERR_1_PRINTER_IN_USE), "printer-in-use"}, + {ERR1(QL_ERR_1_PRINTER_TURNED_OFF), "printer-turned-off"}, + {ERR1(QL_ERR_1_HIGH_VOLTAGE_ADAPTER), "high-voltage-adapter"}, + {ERR1(QL_ERR_1_FAN_MOTOR_ERROR), "fan-motor-error"}, + + {ERR2(QL_ERR_2_REPLACE_MEDIA), "replace-media"}, + {ERR2(QL_ERR_2_EXPANSION_BUFFER_FULL), "expansion-buffer-full"}, + {ERR2(QL_ERR_2_COMMUNICATION_ERROR), "communication-error"}, + {ERR2(QL_ERR_2_COMMUNICATION_BUFFER_FULL), "communication-buffer-full"}, + {ERR2(QL_ERR_2_COVER_OPEN), "cover-open"}, + {ERR2(QL_ERR_2_CANCEL_KEY), "cancel-key-pressed"}, + {ERR2(QL_ERR_2_MEDIA_CANNOT_BE_FED), "media-cannot-be-fed"}, + {ERR2(QL_ERR_2_SYSTEM_ERROR), "system-error"} +}; + +const char *ql_decode_errors_human(const ql_status_t *status) +{ + static char *buf = NULL; + unsigned int i; + uint16_t errs; + size_t len; + + errs = ERR1(status->err_info_1) | ERR2(status->err_info_2); + if (!errs) + return "none"; - static char *buf = 0; - if (!buf) { - int len = 0; - for (unsigned i = 0; i < (sizeof(strmap) / sizeof(strmap[0])); ++i) - len += strlen(strmap[i].str); - buf = malloc(len + 1); - if (!buf) - return "<host-out-of-memory>"; + len = 0; + for (i = 0; i < (sizeof(strmap) / sizeof(strmap[0])); ++i) + if (errs & strmap[i].bit) + len += strlen(strmap[i].str) + 1; /* space or terminating NULL byte */ + if (!len) + return "unknown-error"; + + buf = malloc(len); + if (!buf) + return "<host-out-of-memory>"; + + buf[0] = '\0'; + for (i = 0; i < (sizeof(strmap) / sizeof(strmap[0])); ++i) { + if (errs & strmap[i].bit) { + if (buf[0]) + strcat(buf, " "); + strcat(buf, strmap[i].str); + } } + assert(strlen(buf) == len - 1); + return buf; +} + +const char *ql_decode_errors_json(const ql_status_t *status) +{ + static char *buf = NULL; + unsigned int i; + uint16_t errs; + size_t len; - uint16_t errs = ERR1(status->err_info_1) | ERR2(status->err_info_2); - buf[0] = 0; - for (unsigned i = 0; i < (sizeof(strmap) / sizeof(strmap[0])); ++i) { + errs = ERR1(status->err_info_1) | ERR2(status->err_info_2); + if (!errs) + return "null"; + + len = 2; /* [] */ + for (i = 0; i < (sizeof(strmap) / sizeof(strmap[0])); ++i) if (errs & strmap[i].bit) + len += strlen(strmap[i].str) + 3; /* quotes + comma or terminating NULL byte */ + if (!len) + return "\"unknown-error\""; + + buf = malloc(len); + if (!buf) + return "\"<host-out-of-memory>\""; + + buf[0] = '['; + buf[1] = '\0'; + for (i = 0; i < (sizeof(strmap) / sizeof(strmap[0])); ++i) { + if (errs & strmap[i].bit) { + if (buf[1]) + strcat(buf, ","); + strcat(buf, "\""); strcat(buf, strmap[i].str); + strcat(buf, "\""); + } } - return (buf[0] == 0) ? "none" : buf; + strcat(buf, "]"); + assert(strlen(buf) == len - 1); + return buf; } +#undef ERR1 +#undef ERR2 const char *ql_decode_media_type(const ql_status_t *status) { @@ -391,7 +445,7 @@ static void ql_decode_print_status_human(FILE *f, const ql_status_t *status, uns if (flags & QL_DECODE_MODE) fprintf(f, fmt_s, "Mode", ql_decode_mode(status)); if (flags & QL_DECODE_ERROR) - fprintf(f, fmt_s, "Errors", ql_decode_errors(status)); + fprintf(f, fmt_s, "Errors", ql_decode_errors_human(status)); if (flags & QL_DECODE_MEDIA) { fprintf(f, fmt_s, "Media type", ql_decode_media_type(status)); fprintf(f, fmt_u, "Media width (mm)", status->media_width_mm); @@ -408,6 +462,7 @@ static void ql_decode_print_status_json(FILE *f, const ql_print_json_t *json_ctx const char *fmt_s = "\t\"%s\": \"%s\",\n"; const char *fmt_u = "\t\"%s\": %u,\n"; + const char *fmt_d = "\t\"%s\": %s,\n"; bool status_ok = true; fprintf(f, "{\n"); fprintf(f, fmt_s, "printer", ql_json_escape(json_ctx->printer)); @@ -416,11 +471,9 @@ static void ql_decode_print_status_json(FILE *f, const ql_print_json_t *json_ctx if (flags & QL_DECODE_MODE) fprintf(f, fmt_s, "mode", ql_decode_mode(status)); if (flags & QL_DECODE_ERROR) { - const char *errors = ql_decode_errors(status); - - if (strcmp(errors, "none") != 0) + if (status->err_info_1 || status->err_info_2) status_ok = false; - fprintf(f, fmt_s, "errors", ql_decode_errors(status)); + fprintf(f, fmt_d, "errors", ql_decode_errors_json(status)); } if (flags & QL_DECODE_MEDIA) { fprintf(f, fmt_s, "media_type", ql_decode_media_type(status)); |
