aboutsummaryrefslogtreecommitdiffstats
path: root/erts/test/erl_print_SUITE_data/erl_print_tests.c
diff options
context:
space:
mode:
Diffstat (limited to 'erts/test/erl_print_SUITE_data/erl_print_tests.c')
-rw-r--r--erts/test/erl_print_SUITE_data/erl_print_tests.c560
1 files changed, 560 insertions, 0 deletions
diff --git a/erts/test/erl_print_SUITE_data/erl_print_tests.c b/erts/test/erl_print_SUITE_data/erl_print_tests.c
new file mode 100644
index 0000000000..28ce78f4e1
--- /dev/null
+++ b/erts/test/erl_print_SUITE_data/erl_print_tests.c
@@ -0,0 +1,560 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2005-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+/*
+ * Description: Test suite for the ethread thread library.
+ * Author: Rickard Green
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <limits.h>
+#include <float.h>
+#ifndef __WIN32__
+#include <unistd.h>
+#endif
+
+#include "erl_printf.h"
+#ifdef THREAD_SAFE
+#include "ethread.h"
+#endif
+
+#ifdef __WIN32__
+#undef HAVE_VSNPRINTF
+#define HAVE_VSNPRINTF 1
+#define vsnprintf _vsnprintf
+#endif
+
+#ifdef __WIN32__
+#define signed_long_long LONGLONG
+#define unsigned_long_long ULONGLONG
+#else
+#define signed_long_long signed long long
+#define unsigned_long_long unsigned long long
+#endif
+
+/*
+ * Auxiliary functions
+ */
+
+#define PRINT_VA_LIST(FRMT) \
+do { \
+ if (FRMT && FRMT != '\0') { \
+ va_list args; \
+ va_start(args, FRMT); \
+ vfprintf(stderr, FRMT, args); \
+ va_end(args); \
+ } \
+} while (0)
+
+#define ASSERT(B) \
+do { \
+ if (!(B)) \
+ fail("%s:%d: Assertion \"%s\" failed!",__FILE__,__LINE__,#B); \
+} while (0)
+
+static void
+print_eol(void)
+{
+ fprintf(stderr, "\n");
+}
+
+static void print_line(char *frmt,...)
+{
+ PRINT_VA_LIST(frmt);
+ print_eol();
+}
+
+static void print(char *frmt,...)
+{
+ PRINT_VA_LIST(frmt);
+}
+
+static void fail(char *frmt,...)
+{
+ char *abrt_env;
+ print_eol();
+ fprintf(stderr, "EP-TEST-FAILURE");
+ PRINT_VA_LIST(frmt);
+ print_eol();
+ abrt_env = getenv("ERL_ABORT_ON_FAILURE");
+ if (abrt_env && strcmp("true", abrt_env) == 0)
+ abort();
+ else
+ exit(1);
+}
+
+static void skip(char *frmt,...)
+{
+ print_eol();
+ fprintf(stderr, "EP-TEST-SKIP");
+ PRINT_VA_LIST(frmt);
+ print_eol();
+ exit(0);
+}
+
+static void succeed(char *frmt,...)
+{
+ print_eol();
+ fprintf(stderr, "EP-TEST-SUCCESS");
+ PRINT_VA_LIST(frmt);
+ print_eol();
+ exit(0);
+}
+
+#if 0 /* Not used */
+
+static void
+do_sleep(unsigned secs)
+{
+#ifdef __WIN32__
+ Sleep((DWORD) secs*1000);
+#else
+ sleep(secs);
+#endif
+}
+
+#endif
+
+static void
+send_my_pid(void)
+{
+#ifndef __WIN32__
+ int pid = (int) getpid();
+ fprintf(stderr, "\nEP-TEST-PID%d\n", pid);
+#endif
+}
+
+#define BUF_SIZE (1024*1024)
+
+FILE *outfile = NULL;
+char **expected_result;
+
+#define FENCE_SIZE 512
+static void
+print_cmp_test(int n, char *frmt, ...)
+{
+ int res = -1;
+ static char clib_buf[BUF_SIZE];
+ static unsigned char the_erts_buf[BUF_SIZE];
+ char *erts_buf = (char *) &the_erts_buf[FENCE_SIZE];
+ va_list args;
+
+ if (outfile) {
+ char *fp, *tp;
+ va_start(args, frmt);
+ if (n < 0)
+ res = vsprintf(erts_buf, frmt, args);
+ else {
+#ifdef HAVE_VSNPRINTF
+ res = vsnprintf(erts_buf, (size_t) n, frmt, args);
+#else
+ fail("No vsnprintf()");
+#endif
+ }
+ va_end(args);
+ ASSERT(res >= 0);
+ fp = erts_buf;
+ tp = clib_buf;
+ while (*fp) {
+ switch (*fp) {
+ case '\a': *(tp++) = '\\'; *(tp++) = 'a'; break;
+ case '\b': *(tp++) = '\\'; *(tp++) = 'b'; break;
+ case '\f': *(tp++) = '\\'; *(tp++) = 'f'; break;
+ case '\n': *(tp++) = '\\'; *(tp++) = 'n'; break;
+ case '\r': *(tp++) = '\\'; *(tp++) = 'r'; break;
+ case '\t': *(tp++) = '\\'; *(tp++) = 't'; break;
+ case '\v': *(tp++) = '\\'; *(tp++) = 'v'; break;
+ case '\"': *(tp++) = '\\'; *(tp++) = '\"'; break;
+ case '\\': *(tp++) = '\\'; *(tp++) = '\\'; break;
+ default: *(tp++) = *fp; break;
+ }
+ fp++;
+ }
+ *tp = '\0';
+ res = fprintf(outfile, "\t\"%s\",\n", clib_buf);
+ ASSERT(res >= 0);
+ }
+ else {
+ char *xres;
+ va_start(args, frmt);
+ if (n < 0)
+ res = erts_vsprintf(erts_buf, frmt, args);
+ else {
+ int i;
+ int chk_sz = 2*FENCE_SIZE + n;
+ for (i = 0; i < chk_sz; i++)
+ the_erts_buf[i] = 0xeb;
+ res = erts_vsnprintf(erts_buf, (size_t) n, frmt, args);
+ for (i = 0; i < chk_sz; i++)
+ if ((((char *) &the_erts_buf[i]) < erts_buf
+ || erts_buf + n <= ((char *) &the_erts_buf[i]))
+ && the_erts_buf[i] != 0xeb) {
+ int j;
+ for (j = 0; j < chk_sz; j++)
+ print(j ? ",%x(%d)" : "%x(%d)",
+ (unsigned) the_erts_buf[j], j - FENCE_SIZE);
+ print_eol();
+ fail("Garbage written out of bounds (%d,%d)",
+ i - FENCE_SIZE, n);
+ }
+ }
+ va_end(args);
+ ASSERT(res >= 0);
+
+ if (expected_result) {
+ ASSERT(*expected_result);
+ xres = *expected_result;
+ expected_result++;
+ }
+ else {
+ va_start(args, frmt);
+ if (n < 0)
+ res = vsprintf(clib_buf, frmt, args);
+ else {
+#ifdef HAVE_VSNPRINTF
+ res = vsnprintf(clib_buf, (size_t) n, frmt, args);
+#else
+ fail("No vsnprintf()");
+#endif
+ }
+ va_end(args);
+ ASSERT(res >= 0);
+ xres = clib_buf;
+ }
+
+ if (strcmp(xres, erts_buf) != 0) {
+ print_line("expected result : \"%s\"", xres);
+ print_line("erts_buf : \"%s\"", erts_buf);
+ fail("\"%s\" != \"%s\" (format=\"%s\")", xres, erts_buf, frmt);
+ }
+
+ print_line("Checked format \"%s\" with result: \"%s\"", frmt, erts_buf);
+ }
+}
+
+/*
+ * The test-cases
+ */
+
+#include "integer_64_test.h"
+#include "integer_test.h"
+
+#define INT_SUB_BATCH_TEST(FRMT, TYPE) \
+ print_cmp_test(-1, FRMT, ((TYPE) 4711)); \
+ print_cmp_test(-1, FRMT, ~((TYPE) 4711)); \
+ print_cmp_test(-1, FRMT, (~((TYPE) 0))/2 + (~((TYPE) 0))/4);\
+ print_cmp_test(-1, FRMT, ((TYPE) - 1)); \
+ print_cmp_test(-1, FRMT, ((TYPE) 1)); \
+ print_cmp_test(-1, FRMT, ((TYPE) ((long) 0xabcdef01))); \
+
+#define INT_BATCH_TEST(P, X, S) \
+ print_line("%s:%d",__FILE__,__LINE__); \
+ INT_SUB_BATCH_TEST("%" P "h" X, S char); \
+ INT_SUB_BATCH_TEST("%" P "h" X, S short); \
+ INT_SUB_BATCH_TEST("%" P X, S int); \
+ INT_SUB_BATCH_TEST("%" P "l" X, S long); \
+ INT_SUB_BATCH_TEST("%" P "ll" X, S ## _long_long); \
+
+static void
+integer_test(void)
+{
+ /* This testcase should be rewritten. It assumes the following
+ sizes of types... */
+ if (sizeof(char) != 1
+ || sizeof(short) != 2
+ || sizeof(int) != 4
+ || sizeof(long) != (sizeof(void *) == 8 ? 8 : 4)
+ || sizeof(signed_long_long) != 8)
+ skip("Unexpected size of primitive datatype:"
+ " sizeof(char) == %d (expected 1);"
+ " sizeof(short) == %d (expected 2);"
+ " sizeof(int) == %d (expected 4);"
+ " sizeof(long) == %d (expected %d);"
+ " sizeof(signed_long_long) == %d (expected 8)",
+ sizeof(char),
+ sizeof(short),
+ sizeof(int),
+ sizeof(long), sizeof(void *) == 8 ? 8 : 4,
+ sizeof(signed_long_long));
+
+ expected_result = (sizeof(void *) == 8
+ ? integer_64_expected_result
+ : integer_expected_result);
+
+ INT_BATCH_TEST("", "i", signed);
+ INT_BATCH_TEST("", "d", signed);
+ INT_BATCH_TEST("", "u", unsigned);
+ INT_BATCH_TEST("", "o", unsigned);
+ INT_BATCH_TEST("", "x", unsigned);
+ INT_BATCH_TEST("", "X", unsigned);
+ INT_BATCH_TEST("010.5", "i", signed);
+ INT_BATCH_TEST("010.5", "d", signed);
+ INT_BATCH_TEST("010.5", "u", unsigned);
+ INT_BATCH_TEST("010.5", "o", unsigned);
+ INT_BATCH_TEST("010.5", "x", unsigned);
+ INT_BATCH_TEST("010.5", "X", unsigned);
+ INT_BATCH_TEST("-+29", "i", signed);
+ INT_BATCH_TEST("-+29", "d", signed);
+ INT_BATCH_TEST("-29", "u", unsigned);
+ INT_BATCH_TEST("-29", "o", unsigned);
+ INT_BATCH_TEST("-29", "x", unsigned);
+ INT_BATCH_TEST("-29", "X", unsigned);
+ INT_BATCH_TEST("22.8", "i", signed);
+ INT_BATCH_TEST("22.8", "d", signed);
+ INT_BATCH_TEST("22.8", "u", unsigned);
+ INT_BATCH_TEST("22.8", "o", unsigned);
+ INT_BATCH_TEST("22.8", "x", unsigned);
+ INT_BATCH_TEST("22.8", "X", unsigned);
+ INT_BATCH_TEST("-22.8", "i", signed);
+ INT_BATCH_TEST("-22.8", "d", signed);
+ INT_BATCH_TEST("-22.8", "u", unsigned);
+ INT_BATCH_TEST("-22.8", "o", unsigned);
+ INT_BATCH_TEST("-22.8", "x", unsigned);
+ INT_BATCH_TEST("-22.8", "X", unsigned);
+ INT_BATCH_TEST("-823.193", "i", signed);
+ INT_BATCH_TEST("-823.193", "d", signed);
+ INT_BATCH_TEST("-823.193", "u", unsigned);
+ INT_BATCH_TEST("-823.193", "o", unsigned);
+ INT_BATCH_TEST("-823.193", "x", unsigned);
+ INT_BATCH_TEST("-823.193", "X", unsigned);
+
+}
+
+static void
+float_test(void)
+{
+ expected_result = NULL;
+ print_cmp_test(-1, "%70.10f", DBL_MAX);
+ print_cmp_test(-1, "%500.10f", DBL_MAX);
+ print_cmp_test(-1, "%-500.10f", DBL_MAX);
+ print_cmp_test(-1, "%500.10e", DBL_MAX);
+ print_cmp_test(-1, "%-500.10e", DBL_MAX);
+ print_cmp_test(-1, "%500.10E", DBL_MAX);
+ print_cmp_test(-1, "%-500.10E", DBL_MAX);
+ print_cmp_test(-1, "%500.10g", DBL_MAX);
+ print_cmp_test(-1, "%-500.10g", DBL_MAX);
+ print_cmp_test(-1, "%500.10G", DBL_MAX);
+ print_cmp_test(-1, "%-500.10G", DBL_MAX);
+}
+
+char some_characters[] =
+"abcdefghijklmnopqrstuvwxyz���"
+"ABCDEFGHIJKLMNOPQRSTUVXYZ���"
+"1234567890"
+"()[]{}+-;,:.@�$!\"#�%&/\\=?'`�^~��|<>�*_"
+"\a\b\f\n\r\t\v";
+
+#include "string_test.h"
+
+static void
+string_test(void)
+{
+ expected_result = string_expected_result;
+ print_cmp_test(-1, "%s", "hej");
+ print_cmp_test(-1, "%-10.5s", "hopp");
+ print_cmp_test(-1, "%10.5s", "hopp");
+ print_cmp_test(-1, "%-500.500s", "hopp");
+ print_cmp_test(-1, "%500.500s", "hopp");
+ print_cmp_test(-1, "\t%10.4s", some_characters);
+ print_cmp_test(-1, "\t%500.500s", some_characters);
+}
+
+#include "character_test.h"
+
+static void
+character_test(void)
+{
+ char *cp;
+ expected_result = character_expected_result;
+ for (cp = some_characters; *cp; cp++) {
+ print_cmp_test(-1, "%c", *cp);
+ print_cmp_test(-1, "%-10.5c", *cp);
+ print_cmp_test(-1, "%10.5c", *cp);
+ print_cmp_test(-1, "%-500.500c", *cp);
+ print_cmp_test(-1, "%500.500c", *cp);
+ }
+}
+
+#include "snprintf_test.h"
+
+static void
+snprintf_test(void)
+{
+ expected_result = snprintf_expected_result;
+ print_cmp_test(6, "hej hopp");
+ print_cmp_test(7, "hej hopp");
+ print_cmp_test(8, "hej hopp");
+ print_cmp_test(9, "hej hopp");
+ print_cmp_test(10, "hej hopp");
+ print_cmp_test(6, "hej %d", 4711);
+ print_cmp_test(7, "hej %d", 4711);
+ print_cmp_test(8, "hej %d", 4711);
+ print_cmp_test(9, "hej %d", 4711);
+ print_cmp_test(10, "hej %d", 4711);
+ print_cmp_test(sizeof(some_characters)-2, "%s", some_characters);
+ print_cmp_test(sizeof(some_characters)-1, "%s", some_characters);
+ print_cmp_test(sizeof(some_characters), "%s", some_characters);
+ print_cmp_test(sizeof(some_characters)+1, "%s", some_characters);
+ print_cmp_test(sizeof(some_characters)+2, "%s", some_characters);
+ print_cmp_test(sizeof(some_characters)/2, "%s%s",
+ some_characters, some_characters);
+ print_cmp_test(sizeof(some_characters)*3, "%s%s",
+ some_characters, some_characters);
+}
+
+static void
+quote_test(void)
+{
+ expected_result = NULL;
+ print_cmp_test(-1, "\n");
+ print_cmp_test(-1, "\\n");
+ print_cmp_test(-1, "\r");
+ print_cmp_test(-1, "\\r");
+ print_cmp_test(-1, "\t");
+ print_cmp_test(-1, "\\t");
+ print_cmp_test(-1, "\v");
+ print_cmp_test(-1, "\\v");
+ print_cmp_test(-1, "\b");
+ print_cmp_test(-1, "\\b");
+ print_cmp_test(-1, "\f");
+ print_cmp_test(-1, "\\f");
+ print_cmp_test(-1, "\x80");
+ print_cmp_test(-1, "\\x80");
+ print_cmp_test(-1, "\x14");
+ print_cmp_test(-1, "\\x14");
+ print_cmp_test(-1, "\xff");
+ print_cmp_test(-1, "\\xff");
+ print_cmp_test(-1, "\043");
+ print_cmp_test(-1, "\\043");
+ print_cmp_test(-1, "\053");
+ print_cmp_test(-1, "\\053");
+ print_cmp_test(-1, "\0143");
+ print_cmp_test(-1, "\\0143");
+ print_cmp_test(-1, "\\lf");
+ print_cmp_test(-1, "\\msss");
+ print_cmp_test(-1, "\\ss");
+
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * The dispatcher *
+\* */
+
+int
+main(int argc, char *argv[])
+{
+ if (argc < 2)
+ fail("To few arguments for test case");
+
+ {
+ char *testcase;
+ int save_xres = 0;
+ int i;
+
+ send_my_pid();
+
+ testcase = argv[1];
+#ifdef THREAD_SAFE
+ {
+ int res = ethr_init(NULL);
+ if (res != 0)
+ fail("Failed to initialize the ethread library");
+ }
+#endif
+
+ for (i = 2; i < argc; i++) {
+ if (strcmp(argv[i], "save_expected_result") == 0) {
+ save_xres = 1;
+ break;
+ }
+ }
+
+ if (save_xres) {
+ char filename[100];
+ sprintf(filename,
+ "%s%s_test.h",
+ testcase,
+ sizeof(void *) == 8 ? "_64" : "");
+ printf("Saving expected result to %s\n", filename);
+ outfile = fopen(filename, "w");
+ ASSERT(outfile);
+ fprintf(outfile,
+ "/*\n"
+ " * %%CopyrightBegin%%\n"
+ " * Copyright Ericsson AB 1996-2009. All Rights Reserved.\n"
+ " * \n"
+ " * The contents of this file are subject to the Erlang Public License,\n"
+ " * Version 1.1, (the \"License\"); you may not use this file except in\n"
+ " * compliance with the License. You should have received a copy of the\n"
+ " * Erlang Public License along with this software. If not, it can be\n"
+ " * retrieved online at http://www.erlang.org/.\n"
+ " * \n"
+ " * Software distributed under the License is distributed on an \"AS IS\"\n"
+ " * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See\n"
+ " * the License for the specific language governing rights and limitations\n"
+ " * under the License.\n"
+ " * %%CopyrightEnd%%\n"
+ " */\n"
+ "\n");
+ fprintf(outfile,
+ "/* \n"
+ " * This file has been automatically generated. Do NOT edit it; instead,\n"
+ " * run '%s %s save_expected_result'%s.\n"
+ " */\n"
+ "\n",
+ argv[0],
+ testcase,
+ sizeof(void *) == 8 ? " on a 64-bit machine" : "");
+ fprintf(outfile,
+ "char *%s%s_expected_result[] = {\n",
+ testcase,
+ sizeof(void *) == 8 ? "_64" : "");
+ }
+
+ if (strcmp("integer", testcase) == 0)
+ integer_test();
+ else if (strcmp("float", testcase) == 0)
+ float_test();
+ else if (strcmp("string", testcase) == 0)
+ string_test();
+ else if (strcmp("character", testcase) == 0)
+ character_test();
+ else if (strcmp("snprintf", testcase) == 0)
+ snprintf_test();
+ else if (strcmp("quote", testcase) == 0)
+ quote_test();
+ else if (!save_xres)
+ skip("Test case \"%s\" not implemented yet", testcase);
+
+ if (save_xres) {
+ fprintf(outfile, "\tNULL};\n");
+ fclose(outfile);
+ }
+
+ succeed(NULL);
+ }
+
+ return 0;
+}
+
+
+