summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAsbjørn Sloth Tønnesen <ast@2e8.dk>2026-01-12 19:04:08 +0000
committerAsbjørn Sloth Tønnesen <ast@2e8.dk>2026-01-12 19:06:14 +0000
commit916ad16dfa5e61f79b8c16a6e5bb6a288f3f1015 (patch)
tree1d9d89b5e8cb2d330c03cfdec07e81fb64fa9e75 /src
parenta8c1c1f01c0443e5ed884316da618634c7aebe93 (diff)
downloadqlprint-916ad16dfa5e61f79b8c16a6e5bb6a288f3f1015.tar.gz
qlprint-916ad16dfa5e61f79b8c16a6e5bb6a288f3f1015.tar.xz
qlprint-916ad16dfa5e61f79b8c16a6e5bb6a288f3f1015.zip
Improve error code formattingfixes
For text output, allocate exactly the right buffer size. For JSON output, return error codes as an array, not just a concatinated text string.
Diffstat (limited to 'src')
-rw-r--r--src/main.c2
-rw-r--r--src/ql.c135
2 files changed, 95 insertions, 42 deletions
diff --git a/src/main.c b/src/main.c
index a66c6a6..4ab43f7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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);
diff --git a/src/ql.c b/src/ql.c
index 3a94c03..02ac3cb 100644
--- a/src/ql.c
+++ b/src/ql.c
@@ -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));