ndtypes 0.2.0dev4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.md +50 -0
  3. data/Gemfile +2 -0
  4. data/History.md +0 -0
  5. data/README.md +19 -0
  6. data/Rakefile +125 -0
  7. data/ext/ruby_ndtypes/extconf.rb +55 -0
  8. data/ext/ruby_ndtypes/gc_guard.c +36 -0
  9. data/ext/ruby_ndtypes/gc_guard.h +12 -0
  10. data/ext/ruby_ndtypes/ndtypes/AUTHORS.txt +5 -0
  11. data/ext/ruby_ndtypes/ndtypes/INSTALL.txt +101 -0
  12. data/ext/ruby_ndtypes/ndtypes/LICENSE.txt +29 -0
  13. data/ext/ruby_ndtypes/ndtypes/MANIFEST.in +3 -0
  14. data/ext/ruby_ndtypes/ndtypes/Makefile.in +87 -0
  15. data/ext/ruby_ndtypes/ndtypes/README.rst +47 -0
  16. data/ext/ruby_ndtypes/ndtypes/config.guess +1530 -0
  17. data/ext/ruby_ndtypes/ndtypes/config.h.in +67 -0
  18. data/ext/ruby_ndtypes/ndtypes/config.sub +1782 -0
  19. data/ext/ruby_ndtypes/ndtypes/configure +5260 -0
  20. data/ext/ruby_ndtypes/ndtypes/configure.ac +161 -0
  21. data/ext/ruby_ndtypes/ndtypes/doc/Makefile +14 -0
  22. data/ext/ruby_ndtypes/ndtypes/doc/_static/copybutton.js +66 -0
  23. data/ext/ruby_ndtypes/ndtypes/doc/conf.py +26 -0
  24. data/ext/ruby_ndtypes/ndtypes/doc/grammar/grammar.rst +27 -0
  25. data/ext/ruby_ndtypes/ndtypes/doc/index.rst +56 -0
  26. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/context.rst +131 -0
  27. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/encodings.rst +68 -0
  28. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/fields-values.rst +175 -0
  29. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/functions.rst +72 -0
  30. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/index.rst +43 -0
  31. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/init.rst +48 -0
  32. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/io.rst +100 -0
  33. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/memory.rst +124 -0
  34. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/predicates.rst +110 -0
  35. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/typedef.rst +31 -0
  36. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/types.rst +594 -0
  37. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/util.rst +166 -0
  38. data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/buffer-protocol.rst +27 -0
  39. data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/index.rst +21 -0
  40. data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/pattern-matching.rst +330 -0
  41. data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/quickstart.rst +144 -0
  42. data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/types.rst +544 -0
  43. data/ext/ruby_ndtypes/ndtypes/doc/releases/index.rst +35 -0
  44. data/ext/ruby_ndtypes/ndtypes/install-sh +527 -0
  45. data/ext/ruby_ndtypes/ndtypes/libndtypes/Makefile.in +271 -0
  46. data/ext/ruby_ndtypes/ndtypes/libndtypes/Makefile.vc +269 -0
  47. data/ext/ruby_ndtypes/ndtypes/libndtypes/alloc.c +230 -0
  48. data/ext/ruby_ndtypes/ndtypes/libndtypes/attr.c +268 -0
  49. data/ext/ruby_ndtypes/ndtypes/libndtypes/attr.h +109 -0
  50. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/Makefile.in +73 -0
  51. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/Makefile.vc +70 -0
  52. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/README.txt +16 -0
  53. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.c +2179 -0
  54. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.h +134 -0
  55. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.y +428 -0
  56. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.c +2543 -0
  57. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.h +735 -0
  58. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.l +176 -0
  59. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/export.c +543 -0
  60. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/import.c +110 -0
  61. data/ext/ruby_ndtypes/ndtypes/libndtypes/context.c +228 -0
  62. data/ext/ruby_ndtypes/ndtypes/libndtypes/copy.c +634 -0
  63. data/ext/ruby_ndtypes/ndtypes/libndtypes/encodings.c +116 -0
  64. data/ext/ruby_ndtypes/ndtypes/libndtypes/equal.c +288 -0
  65. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.c +3067 -0
  66. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.h +180 -0
  67. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.y +417 -0
  68. data/ext/ruby_ndtypes/ndtypes/libndtypes/io.c +1658 -0
  69. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.c +2773 -0
  70. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.h +734 -0
  71. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.l +222 -0
  72. data/ext/ruby_ndtypes/ndtypes/libndtypes/match.c +1132 -0
  73. data/ext/ruby_ndtypes/ndtypes/libndtypes/ndtypes.c +2323 -0
  74. data/ext/ruby_ndtypes/ndtypes/libndtypes/ndtypes.h.in +893 -0
  75. data/ext/ruby_ndtypes/ndtypes/libndtypes/overflow.h +161 -0
  76. data/ext/ruby_ndtypes/ndtypes/libndtypes/parsefuncs.c +473 -0
  77. data/ext/ruby_ndtypes/ndtypes/libndtypes/parsefuncs.h +92 -0
  78. data/ext/ruby_ndtypes/ndtypes/libndtypes/parser.c +246 -0
  79. data/ext/ruby_ndtypes/ndtypes/libndtypes/seq.c +269 -0
  80. data/ext/ruby_ndtypes/ndtypes/libndtypes/seq.h +197 -0
  81. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/Makefile.in +48 -0
  82. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/Makefile.vc +46 -0
  83. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/deserialize.c +1007 -0
  84. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/serialize.c +442 -0
  85. data/ext/ruby_ndtypes/ndtypes/libndtypes/slice.h +42 -0
  86. data/ext/ruby_ndtypes/ndtypes/libndtypes/substitute.c +238 -0
  87. data/ext/ruby_ndtypes/ndtypes/libndtypes/substitute.h +50 -0
  88. data/ext/ruby_ndtypes/ndtypes/libndtypes/symtable.c +371 -0
  89. data/ext/ruby_ndtypes/ndtypes/libndtypes/symtable.h +100 -0
  90. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/Makefile.in +55 -0
  91. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/Makefile.vc +45 -0
  92. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/alloc_fail.c +82 -0
  93. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/alloc_fail.h +49 -0
  94. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/runtest.c +1657 -0
  95. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test.h +85 -0
  96. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_array.c +115 -0
  97. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_buffer.c +137 -0
  98. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_indent.c +201 -0
  99. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_match.c +2397 -0
  100. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_numba.c +57 -0
  101. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_parse.c +349 -0
  102. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_parse_error.c +27839 -0
  103. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_parse_roundtrip.c +350 -0
  104. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_record.c +231 -0
  105. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_typecheck.c +375 -0
  106. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_typedef.c +65 -0
  107. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/valgrind.supp +30 -0
  108. data/ext/ruby_ndtypes/ndtypes/libndtypes/tools/bench.c +79 -0
  109. data/ext/ruby_ndtypes/ndtypes/libndtypes/tools/indent.c +94 -0
  110. data/ext/ruby_ndtypes/ndtypes/libndtypes/tools/print_ast.c +96 -0
  111. data/ext/ruby_ndtypes/ndtypes/libndtypes/util.c +474 -0
  112. data/ext/ruby_ndtypes/ndtypes/libndtypes/values.c +228 -0
  113. data/ext/ruby_ndtypes/ndtypes/python/bench.py +49 -0
  114. data/ext/ruby_ndtypes/ndtypes/python/ndt_randtype.py +409 -0
  115. data/ext/ruby_ndtypes/ndtypes/python/ndt_support.py +14 -0
  116. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/__init__.py +70 -0
  117. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/_ndtypes.c +1332 -0
  118. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/docstrings.h +319 -0
  119. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/pyndtypes.h +154 -0
  120. data/ext/ruby_ndtypes/ndtypes/python/test_ndtypes.py +1977 -0
  121. data/ext/ruby_ndtypes/ndtypes/setup.py +288 -0
  122. data/ext/ruby_ndtypes/ndtypes/vcbuild/INSTALL.txt +41 -0
  123. data/ext/ruby_ndtypes/ndtypes/vcbuild/runtest32.bat +15 -0
  124. data/ext/ruby_ndtypes/ndtypes/vcbuild/runtest64.bat +13 -0
  125. data/ext/ruby_ndtypes/ndtypes/vcbuild/vcbuild32.bat +38 -0
  126. data/ext/ruby_ndtypes/ndtypes/vcbuild/vcbuild64.bat +38 -0
  127. data/ext/ruby_ndtypes/ndtypes/vcbuild/vcclean.bat +13 -0
  128. data/ext/ruby_ndtypes/ndtypes/vcbuild/vcdistclean.bat +14 -0
  129. data/ext/ruby_ndtypes/ruby_ndtypes.c +1003 -0
  130. data/ext/ruby_ndtypes/ruby_ndtypes.h +37 -0
  131. data/ext/ruby_ndtypes/ruby_ndtypes_internal.h +28 -0
  132. data/lib/ndtypes.rb +45 -0
  133. data/lib/ndtypes/errors.rb +2 -0
  134. data/lib/ndtypes/version.rb +6 -0
  135. data/ndtypes.gemspec +47 -0
  136. data/spec/gc_table_spec.rb +10 -0
  137. data/spec/ndtypes_spec.rb +289 -0
  138. data/spec/spec_helper.rb +241 -0
  139. metadata +242 -0
@@ -0,0 +1,100 @@
1
+ /*
2
+ * BSD 3-Clause License
3
+ *
4
+ * Copyright (c) 2017-2018, plures
5
+ * All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions are met:
9
+ *
10
+ * 1. Redistributions of source code must retain the above copyright notice,
11
+ * this list of conditions and the following disclaimer.
12
+ *
13
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
14
+ * this list of conditions and the following disclaimer in the documentation
15
+ * and/or other materials provided with the distribution.
16
+ *
17
+ * 3. Neither the name of the copyright holder nor the names of its
18
+ * contributors may be used to endorse or promote products derived from
19
+ * this software without specific prior written permission.
20
+ *
21
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ */
32
+
33
+
34
+ #ifndef SYMTABLE_H
35
+ #define SYMTABLE_H
36
+
37
+
38
+ /*****************************************************************************/
39
+ /* Symbol tables used in type matching */
40
+ /*****************************************************************************/
41
+
42
+ enum symtable_entry {
43
+ Unbound,
44
+ Shape,
45
+ Symbol,
46
+ Type,
47
+ BroadcastSeq,
48
+ FixedSeq,
49
+ VarSeq
50
+ };
51
+
52
+ typedef struct {
53
+ int size;
54
+ const ndt_t *dims[NDT_MAX_DIM];
55
+ } dim_list_t;
56
+
57
+ typedef struct {
58
+ int size;
59
+ int64_t dims[NDT_MAX_DIM];
60
+ } broadcast_list_t;
61
+
62
+ typedef struct {
63
+ enum symtable_entry tag;
64
+ union {
65
+ int64_t Shape;
66
+ const char *Symbol;
67
+ const ndt_t *Type;
68
+ broadcast_list_t BroadcastSeq;
69
+ dim_list_t FixedSeq;
70
+ dim_list_t VarSeq;
71
+ };
72
+ } symtable_entry_t;
73
+
74
+ typedef struct symtable {
75
+ symtable_entry_t entry;
76
+ struct symtable *next[];
77
+ } symtable_t;
78
+
79
+
80
+ /* LOCAL SCOPE */
81
+ NDT_PRAGMA(NDT_HIDE_SYMBOLS_START)
82
+
83
+
84
+ symtable_t *symtable_new(ndt_context_t *ctx);
85
+ void symtable_free_entry(symtable_entry_t entry);
86
+ void symtable_del(symtable_t *t);
87
+ int symtable_add(symtable_t *t, const char *key, const symtable_entry_t entry,
88
+ ndt_context_t *ctx);
89
+ symtable_entry_t symtable_find(const symtable_t *t, const char *key);
90
+ symtable_entry_t *symtable_find_ptr(symtable_t *t, const char *key);
91
+ int64_t symtable_find_shape(const symtable_t *tbl, const char *key, ndt_context_t *ctx);
92
+ const ndt_t *symtable_find_typevar(const symtable_t *tbl, const char *key, ndt_context_t *ctx);
93
+ const ndt_t *symtable_find_var_dim(const symtable_t *tbl, int ndim, ndt_context_t *ctx);
94
+
95
+
96
+ /* END LOCAL SCOPE */
97
+ NDT_PRAGMA(NDT_HIDE_SYMBOLS_END)
98
+
99
+
100
+ #endif /* SYMTABLE_H */
@@ -0,0 +1,55 @@
1
+
2
+ SRCDIR = ..
3
+
4
+ CC = @CC@
5
+
6
+ LIBSTATIC = @LIBSTATIC@
7
+ LIBSHARED = @LIBSHARED@
8
+
9
+ CONFIGURE_CFLAGS = @CONFIGURE_CFLAGS@
10
+ NDT_CFLAGS = $(strip $(CONFIGURE_CFLAGS) $(CFLAGS))
11
+
12
+ CONFIGURE_COV_CFLAGS = @CONFIGURE_COV_CFLAGS@
13
+ CONFIGURE_COV_LDFLAGS = @CONFIGURE_COV_LDFLAGS@
14
+ ifeq ($(MAKECMDGOALS), coverage)
15
+ NDT_CFLAGS = $(strip $(CONFIGURE_COV_CFLAGS) $(CFLAGS))
16
+ NDT_LDFLAGS = $(strip $(CONFIGURE_COV_LDFLAGS) $(LDFLAGS))
17
+ endif
18
+
19
+
20
+ default: runtest runtest_shared
21
+
22
+ coverage: runtest runtest_shared
23
+
24
+
25
+ runtest:\
26
+ Makefile runtest.c alloc_fail.c test_parse.c test_parse_error.c test_parse_roundtrip.c \
27
+ test_indent.c test_typecheck.c test_numba.c test_typedef.c test_match.c test_record.c \
28
+ test_buffer.c test.h alloc_fail.h \
29
+ $(SRCDIR)/ndtypes.h $(SRCDIR)/$(LIBSTATIC)
30
+ $(CC) -DTEST_ALLOC $(NDT_CFLAGS) -o runtest runtest.c \
31
+ alloc_fail.c test_parse.c test_parse_error.c test_parse_roundtrip.c \
32
+ test_indent.c test_typedef.c test_match.c test_typecheck.c test_numba.c \
33
+ test_record.c test_array.c test_buffer.c $(SRCDIR)/$(LIBSTATIC)
34
+
35
+ runtest_shared:\
36
+ Makefile runtest.c alloc_fail.c test_parse.c test_parse_error.c test_parse_roundtrip.c \
37
+ test_indent.c test_typecheck.c test_numba.c test_typedef.c test_match.c test_record.c \
38
+ test_buffer.c test.h alloc_fail.h \
39
+ $(SRCDIR)/ndtypes.h $(SRCDIR)/$(LIBSHARED)
40
+ $(CC) -L$(SRCDIR) -DTEST_ALLOC $(NDT_CFLAGS) -o runtest_shared runtest.c \
41
+ alloc_fail.c test_parse.c test_parse_error.c test_parse_roundtrip.c \
42
+ test_indent.c test_typedef.c test_match.c test_typecheck.c test_numba.c \
43
+ test_record.c test_array.c test_buffer.c -lndtypes
44
+
45
+
46
+ FORCE:
47
+
48
+ clean: FORCE
49
+ rm -f *.o *.gch *.gcda *.gcno *.gcov *.dyn *.dpi *.lock
50
+ rm -f runtest runtest_shared
51
+
52
+ distclean: clean
53
+ rm -rf Makefile
54
+
55
+
@@ -0,0 +1,45 @@
1
+
2
+ SRCDIR = ..
3
+
4
+ LIBSTATIC = libndtypes-0.2.0dev3.lib
5
+ LIBSHARED = libndtypes-0.2.0dev3.dll.lib
6
+
7
+
8
+ CC = cl.exe
9
+ CFLAGS = /nologo /MT /Ox /GS /EHsc
10
+ CFLAGS_SHARED = /nologo /DNDT_IMPORT /MD /Ox /GS /EHsc
11
+
12
+ default: runtest runtest_shared
13
+
14
+
15
+ runtest:\
16
+ Makefile runtest.c alloc_fail.c test_parse.c test_parse_error.c test_parse_roundtrip.c \
17
+ test_indent.c test_typecheck.c test_numba.c test_typedef.c test_match.c test_buffer.c \
18
+ test.h alloc_fail.h \
19
+ $(SRCDIR)\ndtypes.h $(SRCDIR)\$(LIBSTATIC)
20
+ $(CC) -I$(SRCDIR) $(CFLAGS) -DTEST_ALLOC /Feruntest runtest.c \
21
+ alloc_fail.c test_parse.c test_parse_error.c test_parse_roundtrip.c \
22
+ test_indent.c test_typecheck.c test_numba.c test_typedef.c test_match.c \
23
+ test_buffer.c \
24
+ $(SRCDIR)\$(LIBSTATIC)
25
+
26
+ runtest_shared:\
27
+ Makefile runtest.c alloc_fail.c test_parse.c test_parse_error.c test_parse_roundtrip.c \
28
+ test_indent.c test_typedef.c test_match.c test.h alloc_fail.h \
29
+ $(SRCDIR)\ndtypes.h $(SRCDIR)\$(LIBSHARED)
30
+ $(CC) -I$(SRCDIR) $(CFLAGS_SHARED) -DTEST_ALLOC /Feruntest_shared runtest.c \
31
+ alloc_fail.c test_parse.c test_parse_error.c test_parse_roundtrip.c \
32
+ test_indent.c test_typecheck.c test_numba.c test_typedef.c test_match.c \
33
+ test_buffer.c \
34
+ $(SRCDIR)\$(LIBSHARED)
35
+
36
+
37
+ FORCE:
38
+
39
+ clean: FORCE
40
+ del /q /f *.exe *.obj *.lib *.dll *.exp *.manifest 2>NUL
41
+
42
+ distclean: clean
43
+ del /q /f Makefile 2>NUL
44
+
45
+
@@ -0,0 +1,82 @@
1
+ /*
2
+ * BSD 3-Clause License
3
+ *
4
+ * Copyright (c) 2017-2018, plures
5
+ * All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions are met:
9
+ *
10
+ * 1. Redistributions of source code must retain the above copyright notice,
11
+ * this list of conditions and the following disclaimer.
12
+ *
13
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
14
+ * this list of conditions and the following disclaimer in the documentation
15
+ * and/or other materials provided with the distribution.
16
+ *
17
+ * 3. Neither the name of the copyright holder nor the names of its
18
+ * contributors may be used to endorse or promote products derived from
19
+ * this software without specific prior written permission.
20
+ *
21
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ */
32
+
33
+
34
+ #include <stdlib.h>
35
+ #include "ndtypes.h"
36
+ #include "alloc_fail.h"
37
+
38
+
39
+ /* Test allocation failures */
40
+ int alloc_fail;
41
+ int alloc_idx;
42
+
43
+
44
+ void *
45
+ ndt_alloc_fail(size_t size)
46
+ {
47
+ #ifdef TEST_ALLOC
48
+ if (++alloc_idx >= alloc_fail) {
49
+ return NULL;
50
+ }
51
+ #endif
52
+ return malloc(size);
53
+ }
54
+
55
+ void *
56
+ ndt_realloc_fail(void *ptr, size_t size)
57
+ {
58
+ #ifdef TEST_ALLOC
59
+ if (++alloc_idx >= alloc_fail) {
60
+ return NULL;
61
+ }
62
+ #endif
63
+ return realloc(ptr, size);
64
+ }
65
+
66
+ void
67
+ ndt_set_alloc_fail(void)
68
+ {
69
+ ndt_mallocfunc = ndt_alloc_fail;
70
+ ndt_reallocfunc = ndt_realloc_fail;
71
+ alloc_idx = 0;
72
+ }
73
+
74
+ void
75
+ ndt_set_alloc(void)
76
+ {
77
+ ndt_mallocfunc = malloc;
78
+ ndt_reallocfunc = realloc;
79
+ }
80
+
81
+
82
+
@@ -0,0 +1,49 @@
1
+ /*
2
+ * BSD 3-Clause License
3
+ *
4
+ * Copyright (c) 2017-2018, plures
5
+ * All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions are met:
9
+ *
10
+ * 1. Redistributions of source code must retain the above copyright notice,
11
+ * this list of conditions and the following disclaimer.
12
+ *
13
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
14
+ * this list of conditions and the following disclaimer in the documentation
15
+ * and/or other materials provided with the distribution.
16
+ *
17
+ * 3. Neither the name of the copyright holder nor the names of its
18
+ * contributors may be used to endorse or promote products derived from
19
+ * this software without specific prior written permission.
20
+ *
21
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ */
32
+
33
+
34
+ #ifndef ALLOC_FAIL_H
35
+ #define ALLOC_FAIL_H
36
+
37
+
38
+ #include <stdio.h>
39
+
40
+ extern int alloc_fail;
41
+ extern int alloc_idx;
42
+
43
+ void *ndt_alloc_fail(size_t size);
44
+ void *ndt_realloc_fail(void *ptr, size_t size);
45
+ void ndt_set_alloc_fail(void);
46
+ void ndt_set_alloc(void);
47
+
48
+
49
+ #endif /* ALLOC_FAIL_H */
@@ -0,0 +1,1657 @@
1
+ /*
2
+ * BSD 3-Clause License
3
+ *
4
+ * Copyright (c) 2017-2018, plures
5
+ * All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions are met:
9
+ *
10
+ * 1. Redistributions of source code must retain the above copyright notice,
11
+ * this list of conditions and the following disclaimer.
12
+ *
13
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
14
+ * this list of conditions and the following disclaimer in the documentation
15
+ * and/or other materials provided with the distribution.
16
+ *
17
+ * 3. Neither the name of the copyright holder nor the names of its
18
+ * contributors may be used to endorse or promote products derived from
19
+ * this software without specific prior written permission.
20
+ *
21
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ */
32
+
33
+
34
+ #include <stdio.h>
35
+ #include <stdlib.h>
36
+ #include <inttypes.h>
37
+ #include <string.h>
38
+ #include <assert.h>
39
+
40
+ #ifdef __linux__
41
+ #include <sys/types.h>
42
+ #include <sys/stat.h>
43
+ #include <fcntl.h>
44
+ #include <unistd.h>
45
+ #endif
46
+
47
+ #include "ndtypes.h"
48
+ #include "test.h"
49
+ #include "alloc_fail.h"
50
+
51
+
52
+ static int
53
+ init_tests(void)
54
+ {
55
+ ndt_context_t *ctx;
56
+ ndt_t *t = NULL;
57
+
58
+ ctx = ndt_context_new();
59
+ if (ctx == NULL) {
60
+ fprintf(stderr, "error: out of memory");
61
+ return -1;
62
+ }
63
+
64
+ if (ndt_init(ctx) < 0) {
65
+ ndt_err_fprint(stderr, ctx);
66
+ ndt_context_del(ctx);
67
+ return -1;
68
+ }
69
+
70
+ t = ndt_from_string("{a: size_t, b: ref(string)}", ctx);
71
+ if (t == NULL) {
72
+ ndt_err_fprint(stderr, ctx);
73
+ ndt_context_del(ctx);
74
+ return -1;
75
+ }
76
+ if (ndt_typedef("defined_t", t, NULL, ctx) < 0) {
77
+ ndt_err_fprint(stderr, ctx);
78
+ ndt_context_del(ctx);
79
+ return -1;
80
+ }
81
+
82
+ t = ndt_from_string("(10 * 2 * defined_t)", ctx);
83
+ if (t == NULL) {
84
+ ndt_err_fprint(stderr, ctx);
85
+ ndt_context_del(ctx);
86
+ return -1;
87
+ }
88
+ if (ndt_typedef("foo_t", t, NULL, ctx) < 0) {
89
+ ndt_err_fprint(stderr, ctx);
90
+ ndt_context_del(ctx);
91
+ return -1;
92
+ }
93
+
94
+ ndt_context_del(ctx);
95
+ return 0;
96
+ }
97
+
98
+ static int
99
+ test_parse(void)
100
+ {
101
+ const char **c;
102
+ ndt_context_t *ctx;
103
+ ndt_t *t;
104
+ char *s;
105
+ int count = 0;
106
+
107
+ ctx = ndt_context_new();
108
+ if (ctx == NULL) {
109
+ fprintf(stderr, "error: out of memory");
110
+ return -1;
111
+ }
112
+
113
+ for (c = parse_tests; *c != NULL; c++) {
114
+ for (alloc_fail = 1; alloc_fail < INT_MAX; alloc_fail++) {
115
+ ndt_err_clear(ctx);
116
+
117
+ ndt_set_alloc_fail();
118
+ t = ndt_from_string(*c, ctx);
119
+ ndt_set_alloc();
120
+
121
+ if (ctx->err != NDT_MemoryError) {
122
+ break;
123
+ }
124
+
125
+ if (t != NULL) {
126
+ ndt_del(t);
127
+ ndt_context_del(ctx);
128
+ fprintf(stderr, "test_parse: parse: FAIL: t != NULL after MemoryError\n");
129
+ fprintf(stderr, "test_parse: parse: FAIL: %s\n", *c);
130
+ return -1;
131
+ }
132
+ }
133
+ if (t == NULL) {
134
+ fprintf(stderr, "test_parse: parse: FAIL: expected success: \"%s\"\n", *c);
135
+ fprintf(stderr, "test_parse: parse: FAIL: got: %s: %s\n\n",
136
+ ndt_err_as_string(ctx->err),
137
+ ndt_context_msg(ctx));
138
+ ndt_context_del(ctx);
139
+ return -1;
140
+ }
141
+
142
+ for (alloc_fail = 1; alloc_fail < INT_MAX; alloc_fail++) {
143
+ ndt_err_clear(ctx);
144
+
145
+ ndt_set_alloc_fail();
146
+ s = ndt_as_string(t, ctx);
147
+ ndt_set_alloc();
148
+
149
+ if (ctx->err != NDT_MemoryError) {
150
+ break;
151
+ }
152
+
153
+ if (s != NULL) {
154
+ ndt_free(s);
155
+ ndt_del(t);
156
+ ndt_context_del(ctx);
157
+ fprintf(stderr, "test_parse: convert: FAIL: s != NULL after MemoryError\n");
158
+ fprintf(stderr, "test_parse: parse: FAIL: %s\n", *c);
159
+ return -1;
160
+ }
161
+ }
162
+ if (s == NULL) {
163
+ fprintf(stderr, "test_parse: convert: FAIL: expected success: \"%s\"\n", *c);
164
+ fprintf(stderr, "test_parse: convert: FAIL: got: %s: %s\n\n",
165
+ ndt_err_as_string(ctx->err),
166
+ ndt_context_msg(ctx));
167
+ ndt_del(t);
168
+ ndt_context_del(ctx);
169
+ return -1;
170
+ }
171
+
172
+ ndt_free(s);
173
+ ndt_del(t);
174
+ count++;
175
+ }
176
+ fprintf(stderr, "test_parse (%d test cases)\n", count);
177
+
178
+ ndt_context_del(ctx);
179
+ return 0;
180
+ }
181
+
182
+ static int
183
+ test_parse_roundtrip(void)
184
+ {
185
+ const char **c;
186
+ ndt_context_t *ctx;
187
+ ndt_t *t;
188
+ char *s;
189
+ int count = 0;
190
+
191
+ ctx = ndt_context_new();
192
+ if (ctx == NULL) {
193
+ fprintf(stderr, "error: out of memory");
194
+ return -1;
195
+ }
196
+
197
+ for (c = parse_roundtrip_tests; *c != NULL; c++) {
198
+ t = ndt_from_string(*c, ctx);
199
+ if (t == NULL) {
200
+ fprintf(stderr, "test_parse_roundtrip: parse: FAIL: expected success: \"%s\"\n", *c);
201
+ fprintf(stderr, "test_parse_roundtrip: parse: FAIL: got: %s: %s\n\n",
202
+ ndt_err_as_string(ctx->err),
203
+ ndt_context_msg(ctx));
204
+ ndt_context_del(ctx);
205
+ return -1;
206
+ }
207
+
208
+ s = ndt_as_string(t, ctx);
209
+ if (s == NULL) {
210
+ fprintf(stderr, "test_parse_roundtrip: convert: FAIL: expected success: \"%s\"\n", *c);
211
+ fprintf(stderr, "test_parse_roundtrip: convert: FAIL: got: %s: %s\n\n",
212
+ ndt_err_as_string(ctx->err),
213
+ ndt_context_msg(ctx));
214
+ ndt_del(t);
215
+ ndt_context_del(ctx);
216
+ return -1;
217
+ }
218
+
219
+ if (strcmp(s, *c) != 0) {
220
+ fprintf(stderr, "test_parse_roundtrip: convert: FAIL: input: \"%s\"\n", *c);
221
+ fprintf(stderr, "test_parse_roundtrip: convert: FAIL: roundtrip: \"%s\"\n", s);
222
+ ndt_free(s);
223
+ ndt_del(t);
224
+ ndt_context_del(ctx);
225
+ return -1;
226
+ }
227
+
228
+ ndt_free(s);
229
+ ndt_del(t);
230
+ count++;
231
+ }
232
+ fprintf(stderr, "test_parse_roundtrip (%d test cases)\n", count);
233
+
234
+ ndt_context_del(ctx);
235
+ return 0;
236
+ }
237
+
238
+ static int
239
+ test_parse_error(void)
240
+ {
241
+ const char **c;
242
+ ndt_context_t *ctx;
243
+ ndt_t *t;
244
+ int count = 0;
245
+
246
+ ctx = ndt_context_new();
247
+ if (ctx == NULL) {
248
+ fprintf(stderr, "error: out of memory");
249
+ return -1;
250
+ }
251
+
252
+ for (c = parse_error_tests; *c != NULL; c++) {
253
+ for (alloc_fail = 1; alloc_fail < INT_MAX; alloc_fail++) {
254
+ ndt_err_clear(ctx);
255
+
256
+ ndt_set_alloc_fail();
257
+ t = ndt_from_string(*c, ctx);
258
+ ndt_set_alloc();
259
+
260
+ if (ctx->err != NDT_MemoryError) {
261
+ break;
262
+ }
263
+
264
+ if (t != NULL) {
265
+ ndt_del(t);
266
+ ndt_context_del(ctx);
267
+ fprintf(stderr, "test_parse_error: FAIL: t != NULL after MemoryError\n");
268
+ fprintf(stderr, "test_parse_error: FAIL: input: %s\n", *c);
269
+ return -1;
270
+ }
271
+ }
272
+ if (t != NULL) {
273
+ fprintf(stderr, "test_parse_error: FAIL: unexpected success: \"%s\"\n", *c);
274
+ fprintf(stderr, "test_parse_error: FAIL: t != NULL after %s: %s\n",
275
+ ndt_err_as_string(ctx->err),
276
+ ndt_context_msg(ctx));
277
+ ndt_del(t);
278
+ ndt_context_del(ctx);
279
+ return -1;
280
+ }
281
+ count++;
282
+ }
283
+ fprintf(stderr, "test_parse_error (%d test cases)\n", count);
284
+
285
+ ndt_context_del(ctx);
286
+ return 0;
287
+ }
288
+
289
+ static int
290
+ test_indent(void)
291
+ {
292
+ const indent_testcase_t *tc;
293
+ const char **c;
294
+ ndt_context_t *ctx;
295
+ ndt_t *t;
296
+ char *s;
297
+ int count = 0;
298
+
299
+ ctx = ndt_context_new();
300
+ if (ctx == NULL) {
301
+ fprintf(stderr, "error: out of memory");
302
+ return -1;
303
+ }
304
+
305
+ for (c = parse_tests; *c != NULL; c++) {
306
+ t = ndt_from_string(*c, ctx);
307
+ if (t == NULL) {
308
+ fprintf(stderr, "test_indent: parse: FAIL: expected success: \"%s\"\n", *c);
309
+ fprintf(stderr, "test_indent: parse: FAIL: got: %s: %s\n\n",
310
+ ndt_err_as_string(ctx->err),
311
+ ndt_context_msg(ctx));
312
+ ndt_context_del(ctx);
313
+ return -1;
314
+ }
315
+
316
+ for (alloc_fail = 1; alloc_fail < INT_MAX; alloc_fail++) {
317
+ ndt_err_clear(ctx);
318
+
319
+ ndt_set_alloc_fail();
320
+ s = ndt_indent(t, ctx);
321
+ ndt_set_alloc();
322
+
323
+ if (ctx->err != NDT_MemoryError) {
324
+ break;
325
+ }
326
+
327
+ if (s != NULL) {
328
+ ndt_free(s);
329
+ ndt_del(t);
330
+ ndt_context_del(ctx);
331
+ fprintf(stderr, "test_indent: convert: FAIL: s != NULL after MemoryError\n");
332
+ fprintf(stderr, "test_indent: convert: FAIL: %s\n", *c);
333
+ return -1;
334
+ }
335
+ }
336
+ if (s == NULL) {
337
+ fprintf(stderr, "test_indent: convert: FAIL: expected success: \"%s\"\n", *c);
338
+ fprintf(stderr, "test_indent: convert: FAIL: got: %s: %s\n\n",
339
+ ndt_err_as_string(ctx->err),
340
+ ndt_context_msg(ctx));
341
+ ndt_del(t);
342
+ ndt_context_del(ctx);
343
+ return -1;
344
+ }
345
+
346
+ ndt_free(s);
347
+ ndt_del(t);
348
+ count++;
349
+ }
350
+
351
+ for (tc = indent_tests; tc->input != NULL; tc++) {
352
+ t = ndt_from_string(tc->input, ctx);
353
+ if (t == NULL) {
354
+ fprintf(stderr, "test_indent: parse: FAIL: expected success: \"%s\"\n", tc->input);
355
+ fprintf(stderr, "test_indent: parse: FAIL: got: %s: %s\n\n",
356
+ ndt_err_as_string(ctx->err),
357
+ ndt_context_msg(ctx));
358
+ ndt_context_del(ctx);
359
+ return -1;
360
+ }
361
+
362
+ for (alloc_fail = 1; alloc_fail < INT_MAX; alloc_fail++) {
363
+ ndt_err_clear(ctx);
364
+
365
+ ndt_set_alloc_fail();
366
+ s = ndt_indent(t, ctx);
367
+ ndt_set_alloc();
368
+
369
+ if (ctx->err != NDT_MemoryError) {
370
+ break;
371
+ }
372
+
373
+ if (s != NULL) {
374
+ ndt_free(s);
375
+ ndt_del(t);
376
+ ndt_context_del(ctx);
377
+ fprintf(stderr, "test_indent: convert: FAIL: s != NULL after MemoryError\n");
378
+ fprintf(stderr, "test_indent: convert: FAIL: %s\n", tc->input);
379
+ return -1;
380
+ }
381
+ }
382
+ if (s == NULL) {
383
+ fprintf(stderr, "test_indent: convert: FAIL: expected success: \"%s\"\n", tc->input);
384
+ fprintf(stderr, "test_indent: convert: FAIL: got: %s: %s\n\n",
385
+ ndt_err_as_string(ctx->err),
386
+ ndt_context_msg(ctx));
387
+ ndt_del(t);
388
+ ndt_context_del(ctx);
389
+ return -1;
390
+ }
391
+
392
+ if (strcmp(s, tc->indented) != 0) {
393
+ fprintf(stderr, "test_indent: convert: FAIL: expected success: \"%s\"\n", tc->input);
394
+ fprintf(stderr, "test_indent: convert: FAIL: got: %s: %s\n\n",
395
+ ndt_err_as_string(ctx->err),
396
+ ndt_context_msg(ctx));
397
+ ndt_del(t);
398
+ ndt_context_del(ctx);
399
+ return -1;
400
+ }
401
+
402
+ ndt_free(s);
403
+ ndt_del(t);
404
+ count++;
405
+ }
406
+
407
+ fprintf(stderr, "test_indent (%d test cases)\n", count);
408
+
409
+ ndt_context_del(ctx);
410
+ return 0;
411
+ }
412
+
413
+ static int
414
+ test_typedef(void)
415
+ {
416
+ const char **c;
417
+ ndt_context_t *ctx;
418
+ ndt_t *t;
419
+ int count = 0;
420
+
421
+ ctx = ndt_context_new();
422
+ if (ctx == NULL) {
423
+ fprintf(stderr, "error: out of memory");
424
+ return -1;
425
+ }
426
+
427
+ for (c = typedef_tests; *c != NULL; c++) {
428
+ for (alloc_fail = 1; alloc_fail < INT_MAX; alloc_fail++) {
429
+ ndt_err_clear(ctx);
430
+
431
+ t = ndt_from_string("10 * 20 * {a : int64, b : ref(float64)}", ctx);
432
+
433
+ ndt_set_alloc_fail();
434
+ (void)ndt_typedef(*c, t, NULL, ctx);
435
+ ndt_set_alloc();
436
+
437
+ if (ctx->err != NDT_MemoryError) {
438
+ break;
439
+ }
440
+
441
+ if (ndt_typedef_find(*c, ctx) != NULL) {
442
+ fprintf(stderr, "test_typedef: FAIL: key in map after MemoryError\n");
443
+ fprintf(stderr, "test_typedef: FAIL: input: %s\n", *c);
444
+ ndt_context_del(ctx);
445
+ return -1;
446
+ }
447
+ }
448
+
449
+ if (ndt_typedef_find(*c, ctx) == NULL) {
450
+ fprintf(stderr, "test_typedef: FAIL: key not found: \"%s\"\n", *c);
451
+ fprintf(stderr, "test_typedef: FAIL: lookup failed after %s: %s\n",
452
+ ndt_err_as_string(ctx->err),
453
+ ndt_context_msg(ctx));
454
+ ndt_context_del(ctx);
455
+ return -1;
456
+ }
457
+
458
+ count++;
459
+ }
460
+
461
+ fprintf(stderr, "test_typedef (%d test cases)\n", count);
462
+
463
+ ndt_context_del(ctx);
464
+ return 0;
465
+ }
466
+
467
+ static int
468
+ test_typedef_duplicates(void)
469
+ {
470
+ const char **c;
471
+ ndt_context_t *ctx;
472
+ ndt_t *t;
473
+ int count = 0;
474
+
475
+ ctx = ndt_context_new();
476
+ if (ctx == NULL) {
477
+ fprintf(stderr, "error: out of memory");
478
+ return -1;
479
+ }
480
+
481
+ for (c = typedef_tests; *c != NULL; c++) {
482
+ for (alloc_fail = 1; alloc_fail < INT_MAX; alloc_fail++) {
483
+ ndt_err_clear(ctx);
484
+
485
+ t = ndt_from_string("10 * 20 * {a : int64, b : ref(float64)}", ctx);
486
+
487
+ ndt_set_alloc_fail();
488
+ (void)ndt_typedef(*c, t, NULL, ctx);
489
+ ndt_set_alloc();
490
+
491
+ if (ctx->err != NDT_MemoryError) {
492
+ break;
493
+ }
494
+
495
+ if (ndt_typedef_find(*c, ctx) == NULL) {
496
+ fprintf(stderr, "test_typedef: FAIL: key should be in map\n");
497
+ fprintf(stderr, "test_typedef: FAIL: input: %s\n", *c);
498
+ ndt_context_del(ctx);
499
+ return -1;
500
+ }
501
+ }
502
+
503
+ if (ctx->err != NDT_ValueError) {
504
+ fprintf(stderr, "test_typedef: FAIL: no value error after duplicate key\n");
505
+ fprintf(stderr, "test_typedef: FAIL: input: %s\n", *c);
506
+ ndt_context_del(ctx);
507
+ return -1;
508
+ }
509
+
510
+ count++;
511
+ }
512
+
513
+ fprintf(stderr, "test_typedef_duplicates (%d test cases)\n", count);
514
+
515
+ ndt_context_del(ctx);
516
+ return 0;
517
+ }
518
+
519
+ static int
520
+ test_typedef_error(void)
521
+ {
522
+ const char **c;
523
+ ndt_context_t *ctx;
524
+ ndt_t *t;
525
+ int count = 0;
526
+
527
+ ctx = ndt_context_new();
528
+ if (ctx == NULL) {
529
+ fprintf(stderr, "error: out of memory");
530
+ return -1;
531
+ }
532
+
533
+ for (c = typedef_error_tests; *c != NULL; c++) {
534
+ for (alloc_fail = 1; alloc_fail < INT_MAX; alloc_fail++) {
535
+ ndt_err_clear(ctx);
536
+
537
+ t = ndt_from_string("10 * 20 * {a : int64, b : ref(float64)}", ctx);
538
+
539
+ ndt_set_alloc_fail();
540
+ (void)ndt_typedef(*c, t, NULL, ctx);
541
+ ndt_set_alloc();
542
+
543
+ if (ctx->err != NDT_MemoryError) {
544
+ break;
545
+ }
546
+
547
+ if (ndt_typedef_find(*c, ctx) != NULL) {
548
+ fprintf(stderr, "test_typedef_error: FAIL: key in map after MemoryError\n");
549
+ fprintf(stderr, "test_typedef: FAIL: input: %s\n", *c);
550
+ ndt_context_del(ctx);
551
+ return -1;
552
+ }
553
+ }
554
+
555
+ if (ndt_typedef_find(*c, ctx) != NULL) {
556
+ fprintf(stderr, "test_typedef_error: FAIL: unexpected success: \"%s\"\n", *c);
557
+ fprintf(stderr, "test_typedef_error: FAIL: key in map after %s: %s\n",
558
+ ndt_err_as_string(ctx->err),
559
+ ndt_context_msg(ctx));
560
+ ndt_context_del(ctx);
561
+ return -1;
562
+ }
563
+
564
+ count++;
565
+ }
566
+
567
+ fprintf(stderr, "test_typedef_error (%d test cases)\n", count);
568
+
569
+ ndt_context_del(ctx);
570
+ return 0;
571
+ }
572
+
573
+ static int
574
+ test_equal(void)
575
+ {
576
+ const char **c;
577
+ ndt_context_t *ctx;
578
+ ndt_t *t, *u;
579
+ int count = 0;
580
+
581
+ ctx = ndt_context_new();
582
+ if (ctx == NULL) {
583
+ fprintf(stderr, "error: out of memory");
584
+ return -1;
585
+ }
586
+
587
+ for (c = parse_roundtrip_tests; *c && *(c+1); c++) {
588
+ ndt_err_clear(ctx);
589
+
590
+ t = ndt_from_string(*c, ctx);
591
+ if (t == NULL) {
592
+ ndt_context_del(ctx);
593
+ fprintf(stderr, "test_equal: FAIL: could not parse \"%s\"\n", *c);
594
+ return -1;
595
+ }
596
+
597
+ u = ndt_from_string(*(c+1), ctx);
598
+ if (u == NULL) {
599
+ ndt_del(t);
600
+ ndt_context_del(ctx);
601
+ fprintf(stderr, "test_equal: FAIL: could not parse \"%s\"\n", *(c+1));
602
+ return -1;
603
+ }
604
+
605
+ if (!ndt_equal(t, t)) {
606
+ ndt_del(t);
607
+ ndt_del(u);
608
+ ndt_context_del(ctx);
609
+ fprintf(stderr, "test_equal: FAIL: \"%s\" != \"%s\"\n", *c, *c);
610
+ return -1;
611
+ }
612
+
613
+ if (ndt_equal(t, u)) {
614
+ ndt_del(t);
615
+ ndt_del(u);
616
+ fprintf(stderr, "test_equal: FAIL: \"%s\" == \"%s\"\n", *c, *(c+1));
617
+ return -1;
618
+ }
619
+
620
+ ndt_del(t);
621
+ ndt_del(u);
622
+ count++;
623
+ }
624
+
625
+ fprintf(stderr, "test_equal (%d test cases)\n", count);
626
+
627
+ ndt_context_del(ctx);
628
+ return 0;
629
+ }
630
+
631
+ static int
632
+ test_match(void)
633
+ {
634
+ const match_testcase_t *t;
635
+ ndt_context_t *ctx;
636
+ ndt_t *p;
637
+ ndt_t *c;
638
+ int ret, count = 0;
639
+
640
+ ctx = ndt_context_new();
641
+ if (ctx == NULL) {
642
+ fprintf(stderr, "error: out of memory");
643
+ return -1;
644
+ }
645
+
646
+ for (t = match_tests; t->pattern != NULL; t++) {
647
+ p = ndt_from_string(t->pattern, ctx);
648
+ if (p == NULL) {
649
+ fprintf(stderr, "test_match: FAIL: could not parse \"%s\"\n", t->pattern);
650
+ ndt_context_del(ctx);
651
+ return -1;
652
+ }
653
+
654
+ c = ndt_from_string(t->candidate, ctx);
655
+ if (c == NULL) {
656
+ ndt_del(p);
657
+ ndt_context_del(ctx);
658
+ fprintf(stderr, "test_match: FAIL: could not parse \"%s\"\n", t->candidate);
659
+ return -1;
660
+ }
661
+
662
+ for (alloc_fail = 1; alloc_fail < INT_MAX; alloc_fail++) {
663
+ ndt_err_clear(ctx);
664
+
665
+ ndt_set_alloc_fail();
666
+ ret = ndt_match(p, c, ctx);
667
+ ndt_set_alloc();
668
+
669
+ if (ctx->err != NDT_MemoryError) {
670
+ break;
671
+ }
672
+
673
+ if (ret != -1) {
674
+ ndt_del(p);
675
+ ndt_del(c);
676
+ ndt_context_del(ctx);
677
+ fprintf(stderr, "test_match: FAIL: expect ret == -1 after MemoryError\n");
678
+ fprintf(stderr, "test_match: FAIL: \"%s\"\n", t->pattern);
679
+ return -1;
680
+ }
681
+ }
682
+
683
+ if (ret != t->expected) {
684
+ ndt_del(p);
685
+ ndt_del(c);
686
+ ndt_context_del(ctx);
687
+ fprintf(stderr, "test_match: FAIL: expected %s\n", t->expected ? "true" : "false");
688
+ fprintf(stderr, "test_match: FAIL: pattern: \"%s\"\n", t->pattern);
689
+ fprintf(stderr, "test_match: FAIL: candidate: \"%s\"\n", t->candidate);
690
+ return -1;
691
+ }
692
+
693
+ ndt_del(p);
694
+ ndt_del(c);
695
+ count++;
696
+ }
697
+ fprintf(stderr, "test_match (%d test cases)\n", count);
698
+
699
+ ndt_context_del(ctx);
700
+ return 0;
701
+ }
702
+
703
+ typedef struct {
704
+ int64_t size;
705
+ ndt_t *types[NDT_MAX_ARGS];
706
+ } type_array_t;
707
+
708
+ static type_array_t
709
+ types_from_string(const char * const *s, ndt_context_t *ctx)
710
+ {
711
+ type_array_t t;
712
+ int i;
713
+
714
+ t.size = -1;
715
+
716
+ for (i = 0; s[i] != NULL; i++) {
717
+ t.types[i] = ndt_from_string(s[i], ctx);
718
+ if (t.types[i] == NULL) {
719
+ ndt_type_array_clear(t.types, i);
720
+ return t;
721
+ }
722
+ }
723
+
724
+ t.size = i;
725
+ return t;
726
+ }
727
+
728
+ static int
729
+ validate_typecheck_test(const typecheck_testcase_t *test,
730
+ const ndt_t *sig,
731
+ ndt_apply_spec_t *spec,
732
+ int ret,
733
+ ndt_context_t *ctx)
734
+ {
735
+ type_array_t out;
736
+ type_array_t broadcast;
737
+ int64_t i;
738
+
739
+ if (!test->success) {
740
+ if (ret == -1) {
741
+ return 0;
742
+ }
743
+ ndt_err_format(ctx, NDT_RuntimeError,
744
+ "test_typecheck: unexpected success: %s %s %s",
745
+ test->signature, test->in[0], test->in[1]);
746
+ return -1;
747
+ }
748
+
749
+ out = types_from_string(test->out, ctx);
750
+ if (out.size < 0) {
751
+ return -1;
752
+ }
753
+
754
+ broadcast = types_from_string(test->broadcast, ctx);
755
+ if (broadcast.size < 0) {
756
+ ndt_type_array_clear(broadcast.types, broadcast.size);
757
+ return -1;
758
+ }
759
+
760
+ if (spec->nout != sig->Function.nout ||
761
+ spec->nout != out.size) {
762
+ ndt_err_format(ctx, NDT_RuntimeError,
763
+ "test_typecheck: expected nout==test->nout==%d, got nout==%d and "
764
+ "test->nout==%d\n", sig->Function.nout, spec->nout, out.size);
765
+ return -1;
766
+ }
767
+
768
+ if (spec->nbroadcast != broadcast.size) {
769
+ ndt_err_format(ctx, NDT_RuntimeError,
770
+ "test_typecheck: expected nbroadcast==%d, got %d\n",
771
+ broadcast.size, spec->nbroadcast);
772
+ return -1;
773
+ }
774
+
775
+ if (spec->outer_dims != test->outer_dims) {
776
+ ndt_err_format(ctx, NDT_RuntimeError,
777
+ "test_typecheck: expected outer_dims==%d, got %d\n",
778
+ test->outer_dims, spec->outer_dims);
779
+ return -1;
780
+ }
781
+
782
+ for (i = 0; i < spec->nout; i++) {
783
+ if (!ndt_equal(spec->out[i], out.types[i])) {
784
+ ndt_err_format(ctx, NDT_RuntimeError,
785
+ "test_typecheck: out value %d: expected %s, got %s",
786
+ i, test->out[i], ndt_ast_repr(spec->out[i], ctx));
787
+ ndt_type_array_clear(out.types, out.size);
788
+ ndt_type_array_clear(broadcast.types, broadcast.size);
789
+ return -1;
790
+ }
791
+ }
792
+
793
+ for (i = 0; i < spec->nbroadcast; i++) {
794
+ if (!ndt_equal(spec->broadcast[i], broadcast.types[i])) {
795
+ ndt_err_format(ctx, NDT_RuntimeError,
796
+ "test_typecheck: broadcast value %d: expected %s, got %s",
797
+ i, test->broadcast[i], ndt_ast_repr(spec->broadcast[i], ctx));
798
+ ndt_type_array_clear(out.types, out.size);
799
+ ndt_type_array_clear(broadcast.types, broadcast.size);
800
+ return -1;
801
+ }
802
+ }
803
+
804
+ ndt_type_array_clear(out.types, out.size);
805
+ ndt_type_array_clear(broadcast.types, broadcast.size);
806
+
807
+ return 0;
808
+ }
809
+
810
+ static int
811
+ test_typecheck(void)
812
+ {
813
+ NDT_STATIC_CONTEXT(ctx);
814
+ ndt_apply_spec_t spec = ndt_apply_spec_empty;
815
+ const typecheck_testcase_t *test;
816
+ const ndt_t *sig = NULL;
817
+ type_array_t in;
818
+ int count = 0;
819
+ int ret = -1;
820
+
821
+ for (test = typecheck_tests; test->signature != NULL; test++) {
822
+ sig = ndt_from_string(test->signature, &ctx);
823
+ if (sig == NULL) {
824
+ ndt_err_format(&ctx, NDT_RuntimeError,
825
+ "test_typecheck: could not parse \"%s\"\n", test->signature);
826
+ goto error;
827
+ }
828
+
829
+ in = types_from_string(test->in, &ctx);
830
+ if (in.size < 0) {
831
+ goto error;
832
+ }
833
+
834
+ for (alloc_fail = 1; alloc_fail < INT_MAX; alloc_fail++) {
835
+ ndt_err_clear(&ctx);
836
+
837
+ ndt_set_alloc_fail();
838
+ ret = ndt_typecheck(&spec, sig, (const ndt_t **)in.types, in.size, NULL, NULL, &ctx);
839
+ ndt_set_alloc();
840
+
841
+ if (ctx.err != NDT_MemoryError) {
842
+ break;
843
+ }
844
+
845
+ ndt_apply_spec_clear(&spec);
846
+ if (ret != -1) {
847
+ ndt_err_format(&ctx, NDT_RuntimeError,
848
+ "test_typecheck: expect nout == -1 after MemoryError\n"
849
+ "test_typecheck: \"%s\"\n", test->signature);
850
+ goto error;
851
+ }
852
+ }
853
+
854
+ ndt_err_clear(&ctx);
855
+ ret = validate_typecheck_test(test, sig, &spec, ret, &ctx);
856
+ ndt_type_array_clear(in.types, in.size);
857
+ ndt_apply_spec_clear(&spec);
858
+ ndt_del((ndt_t *)sig);
859
+
860
+ if (ret < 0) {
861
+ goto error;
862
+ }
863
+
864
+ count++;
865
+ }
866
+
867
+ ret = 0;
868
+ fprintf(stderr, "test_typecheck (%d test cases)\n", count);
869
+
870
+
871
+ out:
872
+ ndt_context_del(&ctx);
873
+ return ret;
874
+
875
+ error:
876
+ ret = -1;
877
+ ndt_err_fprint(stderr, &ctx);
878
+ goto out;
879
+ }
880
+
881
+ static int
882
+ test_numba(void)
883
+ {
884
+ NDT_STATIC_CONTEXT(ctx);
885
+ const numba_testcase_t *test;
886
+ ndt_t *t;
887
+ char *sig = NULL;
888
+ char *core = NULL;
889
+ int count = 0;
890
+ int ret = -1;
891
+
892
+ for (test = numba_tests; test->signature != NULL; test++) {
893
+ t = ndt_from_string(test->signature, &ctx);
894
+ if (t == NULL) {
895
+ ndt_err_format(&ctx, NDT_RuntimeError,
896
+ "test_numba: could not parse \"%s\"\n", test->signature);
897
+ goto error;
898
+ }
899
+
900
+ for (alloc_fail = 1; alloc_fail < INT_MAX; alloc_fail++) {
901
+ ndt_err_clear(&ctx);
902
+
903
+ ndt_set_alloc_fail();
904
+ ret = ndt_to_nbformat(&sig, &core, t, &ctx);
905
+ ndt_set_alloc();
906
+
907
+ if (ctx.err != NDT_MemoryError) {
908
+ break;
909
+ }
910
+
911
+ if (ret != -1) {
912
+ ndt_del(t);
913
+ ndt_err_format(&ctx, NDT_RuntimeError,
914
+ "test_numba: expect ret == -1 after MemoryError\n"
915
+ "test_numba: \"%s\"\n", test->signature);
916
+ goto error;
917
+ }
918
+ }
919
+
920
+ ndt_err_clear(&ctx);
921
+ ndt_del(t);
922
+
923
+ if (sig == NULL || strcmp(sig, test->sig) != 0) {
924
+ ndt_err_format(&ctx, NDT_RuntimeError,
925
+ "test_numba: input: \"%s\" output: \"%s\"\n", test->sig, sig);
926
+ goto error;
927
+ }
928
+
929
+ if (core == NULL || strcmp(core, test->core) != 0) {
930
+ ndt_err_format(&ctx, NDT_RuntimeError,
931
+ "test_numba: input: \"%s\" output: \"%s\"\n", test->core, core);
932
+ goto error;
933
+ }
934
+
935
+ ndt_free(sig);
936
+ ndt_free(core);
937
+ sig = core = NULL;
938
+
939
+ count++;
940
+ }
941
+
942
+ ret = 0;
943
+ fprintf(stderr, "test_numba (%d test cases)\n", count);
944
+
945
+
946
+ out:
947
+ ndt_context_del(&ctx);
948
+ return ret;
949
+
950
+ error:
951
+ ret = -1;
952
+ ndt_err_fprint(stderr, &ctx);
953
+ goto out;
954
+ }
955
+
956
+ static int
957
+ test_static_context(void)
958
+ {
959
+ const char **c;
960
+ NDT_STATIC_CONTEXT(ctx);
961
+ ndt_t *t;
962
+ char *s;
963
+ int count = 0;
964
+
965
+ for (c = parse_tests; *c != NULL; c++) {
966
+ for (alloc_fail = 1; alloc_fail < INT_MAX; alloc_fail++) {
967
+ ndt_err_clear(&ctx);
968
+
969
+ ndt_set_alloc_fail();
970
+ t = ndt_from_string(*c, &ctx);
971
+ ndt_set_alloc();
972
+
973
+ if (ctx.err != NDT_MemoryError) {
974
+ break;
975
+ }
976
+
977
+ if (t != NULL) {
978
+ ndt_del(t);
979
+ fprintf(stderr, "test_static_context: FAIL: t != NULL after MemoryError\n");
980
+ fprintf(stderr, "test_static_context: FAIL: %s\n", *c);
981
+ return -1;
982
+ }
983
+ }
984
+ if (t == NULL) {
985
+ fprintf(stderr, "test_static_context: FAIL: expected success: \"%s\"\n", *c);
986
+ fprintf(stderr, "test_static_context: FAIL: got: %s: %s\n\n",
987
+ ndt_err_as_string(ctx.err),
988
+ ndt_context_msg(&ctx));
989
+ ndt_context_del(&ctx);
990
+ return -1;
991
+ }
992
+
993
+ for (alloc_fail = 1; alloc_fail < INT_MAX; alloc_fail++) {
994
+ ndt_err_clear(&ctx);
995
+
996
+ ndt_set_alloc_fail();
997
+ s = ndt_as_string(t, &ctx);
998
+ ndt_set_alloc();
999
+
1000
+ if (ctx.err != NDT_MemoryError) {
1001
+ break;
1002
+ }
1003
+
1004
+ if (s != NULL) {
1005
+ ndt_free(s);
1006
+ ndt_del(t);
1007
+ fprintf(stderr, "test_static_context: FAIL: s != NULL after MemoryError\n");
1008
+ fprintf(stderr, "test_static_context: FAIL: %s\n", *c);
1009
+ ndt_context_del(&ctx);
1010
+ return -1;
1011
+ }
1012
+ }
1013
+ if (s == NULL) {
1014
+ fprintf(stderr, "test_static_context: FAIL: expected success: \"%s\"\n", *c);
1015
+ fprintf(stderr, "test_static_context: FAIL: got: %s: %s\n\n",
1016
+ ndt_err_as_string(ctx.err),
1017
+ ndt_context_msg(&ctx));
1018
+ ndt_del(t);
1019
+ ndt_context_del(&ctx);
1020
+ return -1;
1021
+ }
1022
+
1023
+ ndt_free(s);
1024
+ ndt_del(t);
1025
+ count++;
1026
+ }
1027
+
1028
+ s = "2 * 1000000000000000000000000000 * complex128";
1029
+ t = ndt_from_string(s, &ctx);
1030
+ if (s == NULL) {
1031
+ fprintf(stderr, "test_static_context: FAIL: expected failure: \"%s\"\n", s);
1032
+ ndt_del(t);
1033
+ ndt_context_del(&ctx);
1034
+ return -1;
1035
+ }
1036
+ count++;
1037
+
1038
+ ndt_context_del(&ctx);
1039
+ fprintf(stderr, "test_static_context (%d test cases)\n", count);
1040
+
1041
+ return 0;
1042
+ }
1043
+
1044
+ typedef struct {
1045
+ const char *str;
1046
+ ndt_ssize_t hash;
1047
+ } hash_testcase_t;
1048
+
1049
+ static int
1050
+ cmp_hash_testcase(const void *x, const void *y)
1051
+ {
1052
+ const hash_testcase_t *p = (const hash_testcase_t *)x;
1053
+ const hash_testcase_t *q = (const hash_testcase_t *)y;
1054
+
1055
+ if (p->hash < q->hash) {
1056
+ return -1;
1057
+ }
1058
+ else if (p->hash == q->hash) {
1059
+ return 0;
1060
+ }
1061
+
1062
+ return 1;
1063
+ }
1064
+
1065
+ static int
1066
+ test_hash(void)
1067
+ {
1068
+ NDT_STATIC_CONTEXT(ctx);
1069
+ hash_testcase_t buf[1000];
1070
+ ptrdiff_t n = 1;
1071
+ const char **c;
1072
+ ndt_t *t;
1073
+ hash_testcase_t x;
1074
+ int i;
1075
+
1076
+ for (c = parse_roundtrip_tests; *c != NULL; c++) {
1077
+ n = c - parse_roundtrip_tests;
1078
+ if (n >= 1000) {
1079
+ break;
1080
+ }
1081
+
1082
+ ndt_err_clear(&ctx);
1083
+
1084
+ t = ndt_from_string(*c, &ctx);
1085
+ if (t == NULL) {
1086
+ fprintf(stderr, "test_hash: FAIL: expected success: \"%s\"\n", *c);
1087
+ fprintf(stderr, "test_hash: FAIL: got: %s: %s\n\n",
1088
+ ndt_err_as_string(ctx.err),
1089
+ ndt_context_msg(&ctx));
1090
+ ndt_context_del(&ctx);
1091
+ return -1;
1092
+ }
1093
+
1094
+ x.hash = ndt_hash(t, &ctx);
1095
+ x.str = *c;
1096
+ ndt_del(t);
1097
+
1098
+ if (x.hash == -1) {
1099
+ fprintf(stderr, "test_hash: FAIL: hash==-1\n\n");
1100
+ ndt_context_del(&ctx);
1101
+ return -1;
1102
+ }
1103
+
1104
+ buf[n] = x;
1105
+ }
1106
+
1107
+ qsort(buf, n, sizeof *buf, cmp_hash_testcase);
1108
+ for (i = 0; i < n-1; i++) {
1109
+ if (buf[i].hash == buf[i+1].hash) {
1110
+ fprintf(stderr,
1111
+ "test_hash: duplicate hash for %s: %" PRI_ndt_ssize "\n\n",
1112
+ buf[i].str, buf[i].hash);
1113
+ }
1114
+ }
1115
+
1116
+ t = ndt_from_string("var * {a: float64, b: string}", &ctx);
1117
+ if (t == NULL) {
1118
+ fprintf(stderr, "test_hash: FAIL: expected success\n\n");
1119
+ ndt_context_del(&ctx);
1120
+ return -1;
1121
+ }
1122
+
1123
+ alloc_fail = 1;
1124
+ ndt_set_alloc_fail();
1125
+ x.hash = ndt_hash(t, &ctx);
1126
+ ndt_set_alloc();
1127
+
1128
+ ndt_del(t);
1129
+
1130
+ if (x.hash != -1 || ctx.err != NDT_MemoryError) {
1131
+ fprintf(stderr, "test_hash: FAIL: expected failure, got %" PRI_ndt_ssize "\n\n", x.hash);
1132
+ ndt_context_del(&ctx);
1133
+ return -1;
1134
+ }
1135
+
1136
+ ndt_context_del(&ctx);
1137
+ fprintf(stderr, "test_hash (%d test cases)\n", (int)n);
1138
+
1139
+ return 0;
1140
+ }
1141
+
1142
+ static int
1143
+ test_copy(void)
1144
+ {
1145
+ NDT_STATIC_CONTEXT(ctx);
1146
+ const char **c;
1147
+ ndt_t *t, *u;
1148
+ int count = 0;
1149
+
1150
+ for (c = parse_tests; *c != NULL; c++) {
1151
+ t = ndt_from_string(*c, &ctx);
1152
+ if (t == NULL) {
1153
+ fprintf(stderr, "test_copy: FAIL: from_string: \"%s\"\n", *c);
1154
+ fprintf(stderr, "test_copy: FAIL: got: %s: %s\n\n",
1155
+ ndt_err_as_string(ctx.err),
1156
+ ndt_context_msg(&ctx));
1157
+ ndt_context_del(&ctx);
1158
+ return -1;
1159
+ }
1160
+
1161
+ for (alloc_fail = 1; alloc_fail < INT_MAX; alloc_fail++) {
1162
+ ndt_err_clear(&ctx);
1163
+
1164
+ ndt_set_alloc_fail();
1165
+ u = ndt_copy(t, &ctx);
1166
+ ndt_set_alloc();
1167
+
1168
+ if (ctx.err != NDT_MemoryError) {
1169
+ break;
1170
+ }
1171
+
1172
+ if (u != NULL) {
1173
+ fprintf(stderr, "test_copy: FAIL: unexpected success: \"%s\"\n", *c);
1174
+ ndt_del(u);
1175
+ ndt_del(t);
1176
+ ndt_context_del(&ctx);
1177
+ return -1;
1178
+ }
1179
+ }
1180
+ if (u == NULL) {
1181
+ fprintf(stderr, "test_copy: FAIL: copying failed: \"%s\"\n", *c);
1182
+ fprintf(stderr, "test_copy: FAIL: got: %s: %s\n\n",
1183
+ ndt_err_as_string(ctx.err),
1184
+ ndt_context_msg(&ctx));
1185
+ ndt_del(t);
1186
+ ndt_context_del(&ctx);
1187
+ return -1;
1188
+ }
1189
+
1190
+ if (!ndt_equal(t, u)) {
1191
+ fprintf(stderr, "test_copy: FAIL: copy: not equal\n\n");
1192
+ ndt_del(t);
1193
+ ndt_del(u);
1194
+ ndt_context_del(&ctx);
1195
+ return -1;
1196
+ }
1197
+
1198
+ ndt_del(u);
1199
+ ndt_del(t);
1200
+ count++;
1201
+ }
1202
+
1203
+ ndt_context_del(&ctx);
1204
+ fprintf(stderr, "test_copy (%d test cases)\n", count);
1205
+
1206
+ return 0;
1207
+ }
1208
+
1209
+ static int
1210
+ test_buffer(void)
1211
+ {
1212
+ const char **c;
1213
+ ndt_context_t *ctx;
1214
+ ndt_t *t;
1215
+ int count = 0;
1216
+
1217
+ ctx = ndt_context_new();
1218
+ if (ctx == NULL) {
1219
+ fprintf(stderr, "error: out of memory");
1220
+ return -1;
1221
+ }
1222
+
1223
+ for (c = buffer_tests; *c != NULL; c++) {
1224
+ for (alloc_fail = 1; alloc_fail < INT_MAX; alloc_fail++) {
1225
+ ndt_err_clear(ctx);
1226
+
1227
+ ndt_set_alloc_fail();
1228
+ t = ndt_from_bpformat(*c, ctx);
1229
+ ndt_set_alloc();
1230
+
1231
+ if (ctx->err != NDT_MemoryError) {
1232
+ break;
1233
+ }
1234
+
1235
+ if (t != NULL) {
1236
+ ndt_del(t);
1237
+ ndt_context_del(ctx);
1238
+ fprintf(stderr, "test_buffer: convert: FAIL: t != NULL after MemoryError\n");
1239
+ fprintf(stderr, "test_buffer: convert: FAIL: %s\n", *c);
1240
+ return -1;
1241
+ }
1242
+ }
1243
+ if (t == NULL) {
1244
+ fprintf(stderr, "test_buffer: convert: FAIL: expected success: \"%s\"\n", *c);
1245
+ fprintf(stderr, "test_buffer: convert: FAIL: got: %s: %s\n\n",
1246
+ ndt_err_as_string(ctx->err),
1247
+ ndt_context_msg(ctx));
1248
+ ndt_context_del(ctx);
1249
+ return -1;
1250
+ }
1251
+
1252
+ ndt_del(t);
1253
+ count++;
1254
+ }
1255
+ fprintf(stderr, "test_buffer (%d test cases)\n", count);
1256
+
1257
+ ndt_context_del(ctx);
1258
+ return 0;
1259
+ }
1260
+
1261
+ static int
1262
+ test_buffer_roundtrip(void)
1263
+ {
1264
+ const char **c;
1265
+ ndt_context_t *ctx;
1266
+ ndt_t *t;
1267
+ char *s;
1268
+ int count = 0;
1269
+ int ret;
1270
+
1271
+ ctx = ndt_context_new();
1272
+ if (ctx == NULL) {
1273
+ fprintf(stderr, "error: out of memory");
1274
+ return -1;
1275
+ }
1276
+
1277
+ for (c = buffer_roundtrip_tests; *c != NULL; c++) {
1278
+ for (alloc_fail = 1; alloc_fail < INT_MAX; alloc_fail++) {
1279
+ ndt_err_clear(ctx);
1280
+
1281
+ ndt_set_alloc_fail();
1282
+ t = ndt_from_bpformat(*c, ctx);
1283
+ ndt_set_alloc();
1284
+
1285
+ if (ctx->err != NDT_MemoryError) {
1286
+ break;
1287
+ }
1288
+
1289
+ if (t != NULL) {
1290
+ ndt_del(t);
1291
+ ndt_context_del(ctx);
1292
+ fprintf(stderr, "test_buffer: convert: FAIL: t != NULL after MemoryError\n");
1293
+ fprintf(stderr, "test_buffer: convert: FAIL: %s\n", *c);
1294
+ return -1;
1295
+ }
1296
+ }
1297
+ if (t == NULL) {
1298
+ fprintf(stderr, "test_buffer: convert: FAIL: expected success: \"%s\"\n", *c);
1299
+ fprintf(stderr, "test_buffer: convert: FAIL: got: %s: %s\n\n",
1300
+ ndt_err_as_string(ctx->err),
1301
+ ndt_context_msg(ctx));
1302
+ ndt_context_del(ctx);
1303
+ return -1;
1304
+ }
1305
+
1306
+ for (alloc_fail = 1; alloc_fail < INT_MAX; alloc_fail++) {
1307
+ ndt_err_clear(ctx);
1308
+
1309
+ ndt_set_alloc_fail();
1310
+ s = ndt_to_bpformat(t, ctx);
1311
+ ndt_set_alloc();
1312
+
1313
+ if (ctx->err != NDT_MemoryError) {
1314
+ break;
1315
+ }
1316
+
1317
+ if (s != NULL) {
1318
+ ndt_free(s);
1319
+ ndt_del(t);
1320
+ ndt_context_del(ctx);
1321
+ fprintf(stderr, "test_buffer_roundtrip: convert: FAIL: s != NULL after MemoryError\n");
1322
+ fprintf(stderr, "test_buffer_roundtrip: convert: FAIL: %s\n", *c);
1323
+ return -1;
1324
+ }
1325
+ }
1326
+ if (s == NULL) {
1327
+ fprintf(stderr, "test_buffer_roundtrip: convert: FAIL: expected success: \"%s\"\n", *c);
1328
+ fprintf(stderr, "test_buffer_roundtrip: convert: FAIL: got: %s: %s\n\n",
1329
+ ndt_err_as_string(ctx->err),
1330
+ ndt_context_msg(ctx));
1331
+ ndt_del(t);
1332
+ ndt_context_del(ctx);
1333
+ return -1;
1334
+ }
1335
+
1336
+ ret = strcmp(s, *c);
1337
+ ndt_del(t);
1338
+
1339
+ if (ret != 0) {
1340
+ fprintf(stderr, "test_buffer_roundtrip: convert: FAIL: input: \"%s\" output: \"%s\"\n", *c, s);
1341
+ ndt_free(s);
1342
+ ndt_context_del(ctx);
1343
+ return -1;
1344
+ }
1345
+
1346
+ ndt_free(s);
1347
+ count++;
1348
+ }
1349
+ fprintf(stderr, "test_buffer_roundtrip (%d test cases)\n", count);
1350
+
1351
+ ndt_context_del(ctx);
1352
+ return 0;
1353
+ }
1354
+
1355
+ static int
1356
+ test_buffer_error(void)
1357
+ {
1358
+ const char **c;
1359
+ ndt_context_t *ctx;
1360
+ ndt_t *t;
1361
+ int count = 0;
1362
+
1363
+ ctx = ndt_context_new();
1364
+ if (ctx == NULL) {
1365
+ fprintf(stderr, "error: out of memory");
1366
+ return -1;
1367
+ }
1368
+
1369
+ for (c = buffer_error_tests; *c != NULL; c++) {
1370
+ for (alloc_fail = 1; alloc_fail < INT_MAX; alloc_fail++) {
1371
+ ndt_err_clear(ctx);
1372
+
1373
+ ndt_set_alloc_fail();
1374
+ t = ndt_from_bpformat(*c, ctx);
1375
+ ndt_set_alloc();
1376
+
1377
+ if (ctx->err != NDT_MemoryError) {
1378
+ break;
1379
+ }
1380
+
1381
+ if (t != NULL) {
1382
+ ndt_del(t);
1383
+ ndt_context_del(ctx);
1384
+ fprintf(stderr, "test_buffer_error: FAIL: t != NULL after MemoryError\n");
1385
+ fprintf(stderr, "test_buffer_error: FAIL: input: %s\n", *c);
1386
+ return -1;
1387
+ }
1388
+ }
1389
+ if (t != NULL) {
1390
+ fprintf(stderr, "test_buffer_error: FAIL: unexpected success: \"%s\"\n", *c);
1391
+ fprintf(stderr, "test_buffer_error: FAIL: t != NULL after %s: %s\n",
1392
+ ndt_err_as_string(ctx->err),
1393
+ ndt_context_msg(ctx));
1394
+ ndt_del(t);
1395
+ ndt_context_del(ctx);
1396
+ return -1;
1397
+ }
1398
+ count++;
1399
+ }
1400
+ fprintf(stderr, "test_buffer_error (%d test cases)\n", count);
1401
+
1402
+ ndt_context_del(ctx);
1403
+ return 0;
1404
+ }
1405
+
1406
+ static int
1407
+ test_serialize(void)
1408
+ {
1409
+ const char **c;
1410
+ ndt_meta_t *m;
1411
+ ndt_context_t *ctx;
1412
+ ndt_t *t, *u;
1413
+ int count = 0;
1414
+ char *bytes;
1415
+ int64_t len;
1416
+
1417
+ ctx = ndt_context_new();
1418
+ if (ctx == NULL) {
1419
+ fprintf(stderr, "error: out of memory");
1420
+ return -1;
1421
+ }
1422
+
1423
+ for (c = parse_tests; *c != NULL; c++) {
1424
+ m = ndt_meta_new(ctx);
1425
+ if (m == NULL) {
1426
+ ndt_context_del(ctx);
1427
+ fprintf(stderr,
1428
+ "test_serialize: FAIL: unexpected failure in meta_new");
1429
+ return -1;
1430
+ }
1431
+
1432
+ t = ndt_from_string(*c, ctx);
1433
+ if (t == NULL) {
1434
+ ndt_meta_del(m);
1435
+ ndt_context_del(ctx);
1436
+ fprintf(stderr,
1437
+ "test_serialize: FAIL: unexpected failure in from_string");
1438
+ return -1;
1439
+ }
1440
+
1441
+ for (alloc_fail = 1; alloc_fail < INT_MAX; alloc_fail++) {
1442
+ ndt_err_clear(ctx);
1443
+ bytes = NULL;
1444
+
1445
+ ndt_set_alloc_fail();
1446
+ len = ndt_serialize(&bytes, t, ctx);
1447
+ ndt_set_alloc();
1448
+
1449
+ if (ctx->err != NDT_MemoryError) {
1450
+ break;
1451
+ }
1452
+
1453
+ if (len >= 0 || bytes != NULL) {
1454
+ ndt_del(t);
1455
+ ndt_free(bytes);
1456
+ ndt_meta_del(m);
1457
+ ndt_context_del(ctx);
1458
+ fprintf(stderr, "test_serialize: FAIL: invalid len or bytes after MemoryError\n");
1459
+ fprintf(stderr, "test_serialize: FAIL: %s\n", *c);
1460
+ return -1;
1461
+ }
1462
+ }
1463
+
1464
+ if (len < 0 || bytes == NULL) {
1465
+ ndt_del(t);
1466
+ ndt_free(bytes);
1467
+ ndt_meta_del(m);
1468
+ ndt_context_del(ctx);
1469
+ fprintf(stderr, "test_serialize: FAIL: invalid len or bytes (expected success)\n");
1470
+ fprintf(stderr, "test_serialize: FAIL: %s\n", *c);
1471
+ return -1;
1472
+ }
1473
+
1474
+ for (alloc_fail = 1; alloc_fail < INT_MAX; alloc_fail++) {
1475
+ ndt_err_clear(ctx);
1476
+
1477
+ ndt_set_alloc_fail();
1478
+ u = ndt_deserialize(m, bytes, len, ctx);
1479
+ ndt_set_alloc();
1480
+
1481
+ if (ctx->err != NDT_MemoryError) {
1482
+ break;
1483
+ }
1484
+
1485
+ if (u != NULL) {
1486
+ ndt_del(t);
1487
+ ndt_del(u);
1488
+ ndt_free(bytes);
1489
+ ndt_meta_del(m);
1490
+ ndt_context_del(ctx);
1491
+ fprintf(stderr, "test_serialize: FAIL: u != NULL after MemoryError\n");
1492
+ fprintf(stderr, "test_serialize: FAIL: %s\n", *c);
1493
+ return -1;
1494
+ }
1495
+ }
1496
+
1497
+ if (u == NULL) {
1498
+ fprintf(stderr, "test_serialize: FAIL: expected success: \"%s\"\n", *c);
1499
+ fprintf(stderr, "test_serialize: FAIL: got: %s: %s\n\n",
1500
+ ndt_err_as_string(ctx->err),
1501
+ ndt_context_msg(ctx));
1502
+ ndt_del(t);
1503
+ ndt_free(bytes);
1504
+ ndt_meta_del(m);
1505
+ ndt_context_del(ctx);
1506
+ return -1;
1507
+ }
1508
+
1509
+ ndt_free(bytes);
1510
+
1511
+ if (!ndt_equal(u, t)) {
1512
+ fprintf(stderr, "test_serialize: FAIL: u != v in %s\n", *c);
1513
+ ndt_del(t);
1514
+ ndt_del(u);
1515
+ ndt_meta_del(m);
1516
+ ndt_context_del(ctx);
1517
+ return -1;
1518
+ }
1519
+
1520
+ ndt_del(t);
1521
+ ndt_del(u);
1522
+
1523
+ ndt_meta_del(m);
1524
+ count++;
1525
+ }
1526
+ fprintf(stderr, "test_serialize (%d test cases)\n", count);
1527
+
1528
+ ndt_context_del(ctx);
1529
+ return 0;
1530
+ }
1531
+
1532
+ #if defined(__linux__)
1533
+ static int
1534
+ test_serialize_fuzz(void)
1535
+ {
1536
+ ndt_context_t *ctx;
1537
+ ndt_meta_t *m;
1538
+ char *buf;
1539
+ ssize_t ret, n;
1540
+ int src;
1541
+ int64_t i;
1542
+
1543
+ ctx = ndt_context_new();
1544
+ if (ctx == NULL) {
1545
+ fprintf(stderr, "\nmalloc error in fuzz tests\n");
1546
+ return -1;
1547
+ }
1548
+
1549
+ src = open("/dev/urandom", O_RDONLY);
1550
+ if (src < 0) {
1551
+ ndt_context_del(ctx);
1552
+ fprintf(stderr, "\ncould not open /dev/urandom\n");
1553
+ return -1;
1554
+ }
1555
+
1556
+ for (i = 0; i < 10000; i++) {
1557
+ n = rand() % 1000;
1558
+ buf = ndt_alloc(n, 1);
1559
+ if (buf == NULL) {
1560
+ close(src);
1561
+ ndt_context_del(ctx);
1562
+ fprintf(stderr, "malloc error in fuzz tests\n");
1563
+ return -1;
1564
+ }
1565
+
1566
+ ret = read(src, buf, n);
1567
+ if (ret < 0) {
1568
+ ndt_free(buf);
1569
+ close(src);
1570
+ ndt_context_del(ctx);
1571
+ fprintf(stderr, "\nread error in fuzz tests\n");
1572
+ return -1;
1573
+ }
1574
+
1575
+ m = ndt_meta_new(ctx);
1576
+ if (m == NULL) {
1577
+ ndt_free(buf);
1578
+ close(src);
1579
+ ndt_context_del(ctx);
1580
+ fprintf(stderr, "\nmalloc error in fuzz tests\n");
1581
+ return -1;
1582
+ }
1583
+
1584
+ ndt_err_clear(ctx);
1585
+ ndt_t *t = ndt_deserialize(m, buf, n, ctx);
1586
+ if (t != NULL) {
1587
+ ndt_del(t);
1588
+ }
1589
+
1590
+ ndt_free(buf);
1591
+ ndt_meta_del(m);
1592
+ }
1593
+ fprintf(stderr, "test_serialize_fuzz (%" PRIi64 " test cases)\n", i);
1594
+
1595
+ close(src);
1596
+ ndt_context_del(ctx);
1597
+ return 0;
1598
+ }
1599
+ #endif
1600
+
1601
+ static int (*tests[])(void) = {
1602
+ test_parse,
1603
+ test_parse_roundtrip,
1604
+ test_parse_error,
1605
+ test_indent,
1606
+ test_typedef,
1607
+ test_typedef_duplicates,
1608
+ test_typedef_error,
1609
+ test_equal,
1610
+ test_match,
1611
+ test_typecheck,
1612
+ test_numba,
1613
+ test_static_context,
1614
+ test_hash,
1615
+ test_copy,
1616
+ test_buffer,
1617
+ test_buffer_roundtrip,
1618
+ test_buffer_error,
1619
+ test_serialize,
1620
+ #ifdef __linux__
1621
+ test_serialize_fuzz,
1622
+ #endif
1623
+ #ifdef __GNUC__
1624
+ test_struct_align_pack,
1625
+ test_array,
1626
+ #endif
1627
+ NULL
1628
+ };
1629
+
1630
+ int
1631
+ main(void)
1632
+ {
1633
+ int (**f)(void);
1634
+ int success = 0;
1635
+ int fail = 0;
1636
+
1637
+ if (init_tests() < 0) {
1638
+ return 1;
1639
+ }
1640
+
1641
+ for (f = tests; *f != NULL; f++) {
1642
+ if ((*f)() < 0)
1643
+ fail++;
1644
+ else
1645
+ success++;
1646
+ }
1647
+
1648
+ if (fail) {
1649
+ fprintf(stderr, "\nFAIL (failures=%d)\n", fail);
1650
+ }
1651
+ else {
1652
+ fprintf(stderr, "\n%d tests OK.\n", success);
1653
+ }
1654
+
1655
+ ndt_finalize();
1656
+ return fail ? 1 : 0;
1657
+ }