ndtypes 0.2.0dev4

Sign up to get free protection for your applications and to get access to all the features.
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
+ }