]> git.draconx.ca Git - cdecl99.git/blobdiff - t/cdeclerr.c
Port to use getline.h from dxcommon.
[cdecl99.git] / t / cdeclerr.c
index 80193e434d389a13f2dafeecb7f83d182f5bc5aa..2120e24c8c1dd1f847ac3841baffcdfffdc51db3 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Helper application to test internal library error reporting.
- * Copyright © 2023 Nick Bowler
+ * Copyright © 2023-2024 Nick Bowler
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 
 #include "cdecl-internal.h"
 #include "cdecl.h"
+#include "errmsg.h"
 #include "tap.h"
 
-#if ENABLE_NLS
-void cdecl__init_i18n(void) { }
-#endif
+/*
+ * Function called from output.c but not needed for error messaging.
+ */
+const char *cdecl__token_name(unsigned token)
+{
+       tap_bail_out("stub cdecl__token_name called");
+}
 
 static char *fmt_char(int c, char *buf)
 {
@@ -56,6 +61,15 @@ static char *fmt_char(int c, char *buf)
        return buf;
 }
 
+static void check_code(const struct cdecl_error *err, unsigned expect)
+{
+       if (!tap_result(err->code == expect, "returned error code")) {
+               tap_diag("Failed, unexpected result");
+               tap_diag("   Received: %u", err->code);
+               tap_diag("   Expected: %u", expect);
+       }
+}
+
 static void check_fixed_string(size_t len)
 {
        const struct cdecl_error *err;
@@ -72,15 +86,11 @@ static void check_fixed_string(size_t len)
        memset(work2, 'X', len - 1);
 
        tap_diag("cdecl__err w/ %lu-byte string", (unsigned long)len);
-       cdecl__err(1234, work1);
+       cdecl__err(work1, "XX");
        memset(work1, 0, len);
        err = cdecl_get_error();
 
-       if (!tap_result(err->code == 1234, "returned error code")) {
-               tap_diag("Failed, unexpected result");
-               tap_diag("   Received: %u", err->code);
-               tap_diag("   Expected: 1234");
-       }
+       check_code(err, CDECL_ENOPARSE);
 
        errlen = strlen(err->str);
        if (!tap_result(errlen == len-1, "returned string length")) {
@@ -106,21 +116,42 @@ static void check_fixed_string(size_t len)
        free(work1);
 }
 
-static void check_enomem()
+static void check_format_string(const char *fmt, const char *arg)
 {
-       const char expmsg[] = "failed to allocate memory";
+       size_t sz = strlen(fmt) + strlen(arg);
        const struct cdecl_error *err;
+       char *work;
 
-       tap_diag("cdecl__err(CDECL_ENOMEM)");
-       cdecl__err(CDECL_ENOMEM);
+       work = malloc(sz + 1);
+       if (!work)
+               abort();
+       sprintf(work, fmt, arg);
+
+       cdecl__err(fmt, arg);
        err = cdecl_get_error();
 
-       if (!tap_result(err->code == CDECL_ENOMEM, "returned error code")) {
+       tap_diag("cdecl__err(\"%s\", \"%s\")", fmt, arg);
+       check_code(err, CDECL_ENOPARSE);
+
+       if (!tap_result(!strcmp(err->str, work), "returned string")) {
                tap_diag("Failed, unexpected result");
-               tap_diag("   Received: %u", err->code);
-               tap_diag("   Expected: %d", CDECL_ENOMEM);
+               tap_diag("   Received: %.*s", (int)sz, err->str);
+               tap_diag("   Expected: %s", work);
        }
 
+       free(work);
+}
+
+static void check_enomem()
+{
+       const char expmsg[] = "failed to allocate memory";
+       const struct cdecl_error *err;
+
+       tap_diag("cdecl__errmsg(CDECL__ENOMEM)");
+       cdecl__errmsg(CDECL__ENOMEM);
+       err = cdecl_get_error();
+
+       check_code(err, CDECL_ENOMEM);
        if (!tap_result(!strcmp(err->str, "failed to allocate memory"),
                        "returned string"))
        {
@@ -137,14 +168,23 @@ static void check_enomem()
        }
 }
 
+#define IFNLS(a, b) (ENABLE_NLS ? (a) : (b))
+
 int main(void)
 {
-       tap_plan(3*3 + 2);
+       tap_plan(3*3 + 2 + 2);
 
        check_fixed_string(50);
        check_fixed_string(500);
        check_fixed_string(5000);
 
+       /*
+        * When NLS is disabled, for implementation simplicity only format
+        * strings ending with %s are supported as this is sufficient.
+        * Otherwise, %s may appear anywhere.
+        */
+       check_format_string(IFNLS("hello %s world", "hello world %s"), "za");
+
        check_enomem();
 
        tap_done();