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,110 @@
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 <assert.h>
36
+ #include <setjmp.h>
37
+ #include "ndtypes.h"
38
+ #include "bpgrammar.h"
39
+ #include "bplexer.h"
40
+
41
+
42
+ #ifdef YYDEBUG
43
+ int ndt_bpdebug = 1;
44
+ #endif
45
+
46
+
47
+ /* The yy_fatal_error() function of flex calls exit(). We intercept the function
48
+ and do a longjmp() for proper error handling. */
49
+ jmp_buf ndt_bp_lexerror;
50
+
51
+
52
+ ndt_t *
53
+ ndt_from_bpformat(const char *input, ndt_context_t *ctx)
54
+ {
55
+ volatile yyscan_t scanner = NULL;
56
+ volatile YY_BUFFER_STATE state = NULL;
57
+ char *buffer;
58
+ size_t size;
59
+ ndt_t *ast = NULL;
60
+ int ret;
61
+
62
+ size = strlen(input);
63
+ if (size > INT_MAX / 2) {
64
+ /* The code generated by flex truncates size_t in several places. */
65
+ ndt_err_format(ctx, NDT_LexError, "maximum input length: %d", INT_MAX/2);
66
+ return NULL;
67
+ }
68
+
69
+ buffer = ndt_alloc_size(size+2);
70
+ if (buffer == NULL) {
71
+ return ndt_memory_error(ctx);
72
+ }
73
+ memcpy(buffer, input, size);
74
+ buffer[size] = '\0';
75
+ buffer[size+1] = '\0';
76
+
77
+ if (setjmp(ndt_bp_lexerror) == 0) {
78
+ if (ndt_bplex_init_extra(ctx, (yyscan_t *)&scanner) != 0) {
79
+ ndt_err_format(ctx, NDT_LexError, "lexer initialization failed");
80
+ ndt_free(buffer);
81
+ return NULL;
82
+ }
83
+
84
+ state = ndt_bp_scan_buffer(buffer, size+2, scanner);
85
+ state->yy_bs_lineno = 1;
86
+ state->yy_bs_column = 1;
87
+
88
+ ret = ndt_bpparse(scanner, &ast, ctx);
89
+ ndt_bp_delete_buffer(state, scanner);
90
+ ndt_bplex_destroy(scanner);
91
+ ndt_free(buffer);
92
+
93
+ if (ret == 2) {
94
+ ndt_err_format(ctx, NDT_MemoryError, "out of memory");
95
+ }
96
+
97
+ return ast;
98
+ }
99
+ else { /* fatal lexer error */
100
+ if (state) {
101
+ ndt_free(state);
102
+ }
103
+ if (scanner) {
104
+ ndt_bplex_destroy(scanner);
105
+ }
106
+ ndt_free(buffer);
107
+ ndt_err_format(ctx, NDT_MemoryError, "flex: internal lexer error");
108
+ return NULL;
109
+ }
110
+ }
@@ -0,0 +1,228 @@
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 <stdarg.h>
35
+ #include "ndtypes.h"
36
+
37
+
38
+ /******************************************************************************/
39
+ /* Context */
40
+ /******************************************************************************/
41
+
42
+ ndt_context_t *
43
+ ndt_context_new(void)
44
+ {
45
+ ndt_context_t *ctx;
46
+
47
+ ctx = ndt_alloc_size(sizeof *ctx);
48
+ if (ctx == NULL) {
49
+ return NULL;
50
+ }
51
+
52
+ ctx->flags = NDT_Dynamic;
53
+ ctx->err = NDT_Success;
54
+ ctx->msg = ConstMsg;
55
+ ctx->ConstMsg = "Success";
56
+
57
+ return ctx;
58
+ }
59
+
60
+ void
61
+ ndt_context_del(ndt_context_t *ctx)
62
+ {
63
+ if (ctx) {
64
+ if (ctx->msg == DynamicMsg) {
65
+ ndt_free(ctx->DynamicMsg);
66
+ }
67
+ if (ctx->flags & NDT_Dynamic) {
68
+ ndt_free(ctx);
69
+ }
70
+ }
71
+ }
72
+
73
+
74
+ /******************************************************************************/
75
+ /* Error handling */
76
+ /******************************************************************************/
77
+
78
+ /* Set an error with a message. */
79
+ void
80
+ ndt_err_format(ndt_context_t *ctx, enum ndt_error err, const char *fmt, ...)
81
+ {
82
+ va_list ap, aq;
83
+ char *s;
84
+ int n;
85
+
86
+ ndt_err_clear(ctx);
87
+ ctx->err = err;
88
+
89
+ va_start(ap, fmt);
90
+ va_copy(aq, ap);
91
+
92
+ n = vsnprintf(NULL, 0, fmt, ap);
93
+ va_end(ap);
94
+ if (n < 0 || n == INT_MAX) {
95
+ ctx->msg = ConstMsg;
96
+ ctx->ConstMsg = \
97
+ "internal error during the handling of the original error";
98
+ return;
99
+ }
100
+
101
+ s = ndt_alloc(1, n+1);
102
+ if (s == NULL) {
103
+ va_end(aq);
104
+ ctx->err = NDT_MemoryError;
105
+ ctx->msg = ConstMsg;
106
+ ctx->ConstMsg = "out of memory";
107
+ return;
108
+ }
109
+
110
+ n = vsnprintf(s, n+1, fmt, aq);
111
+ va_end(aq);
112
+ if (n < 0) {
113
+ ndt_free(s);
114
+ ctx->msg = ConstMsg;
115
+ ctx->ConstMsg = \
116
+ "internal error during the handling of the original error";
117
+ return;
118
+ }
119
+
120
+ ctx->msg = DynamicMsg;
121
+ ctx->DynamicMsg = s;
122
+ }
123
+
124
+ /* Append 'msg' to an existing error message. If no error is set, do nothing. */
125
+ void
126
+ ndt_err_append(ndt_context_t *ctx, const char *msg)
127
+ {
128
+ NDT_STATIC_CONTEXT(localctx);
129
+ enum ndt_error err = ctx->err;
130
+ char *s;
131
+
132
+ if (!ndt_err_occurred(ctx)) {
133
+ return;
134
+ }
135
+
136
+ s = ndt_strdup(ndt_context_msg(ctx), &localctx);
137
+ if (s == NULL) {
138
+ ndt_context_del(&localctx);
139
+ return;
140
+ }
141
+
142
+ ndt_err_clear(ctx);
143
+ ndt_err_format(ctx, err, "%s: \"%s\"", s, msg);
144
+ ndt_free(s);
145
+ }
146
+
147
+ /* Check if an error has occurred. */
148
+ int
149
+ ndt_err_occurred(const ndt_context_t *ctx)
150
+ {
151
+ return ctx->err != NDT_Success;
152
+ }
153
+
154
+ /* Clear an error. */
155
+ void
156
+ ndt_err_clear(ndt_context_t *ctx)
157
+ {
158
+ ctx->err = NDT_Success;
159
+ if (ctx->msg == DynamicMsg) {
160
+ ndt_free(ctx->DynamicMsg);
161
+ ctx->msg = ConstMsg;
162
+ ctx->ConstMsg = "Success";
163
+ }
164
+ }
165
+
166
+ /* Set a malloc error. */
167
+ void *
168
+ ndt_memory_error(ndt_context_t *ctx)
169
+ {
170
+ ndt_err_format(ctx, NDT_MemoryError, "out of memory");
171
+ return NULL;
172
+ }
173
+
174
+
175
+ /******************************************************************************/
176
+ /* Display errors */
177
+ /******************************************************************************/
178
+
179
+ const char *
180
+ ndt_err_as_string(enum ndt_error err)
181
+ {
182
+ switch (err) {
183
+ case NDT_Success:
184
+ return "Success";
185
+ case NDT_MemoryError:
186
+ return "MemoryError";
187
+ case NDT_ValueError:
188
+ return "ValueError";
189
+ case NDT_TypeError:
190
+ return "TypeError";
191
+ case NDT_InvalidArgumentError:
192
+ return "InvalidArgumentError";
193
+ case NDT_NotImplementedError:
194
+ return "NotImplementedError";
195
+ case NDT_IndexError:
196
+ return "IndexError";
197
+ case NDT_RuntimeError:
198
+ return "RuntimeError";
199
+ case NDT_LexError:
200
+ return "LexError";
201
+ case NDT_ParseError:
202
+ return "ParseError";
203
+ case NDT_OSError:
204
+ return "OSError";
205
+ }
206
+
207
+ /* NOT REACHED: tags should be exhaustive. */
208
+ return "UnknownError";
209
+ }
210
+
211
+ /* Get the current error message. */
212
+ const char *
213
+ ndt_context_msg(ndt_context_t *ctx)
214
+ {
215
+ if (ctx->msg == ConstMsg) {
216
+ return ctx->ConstMsg;
217
+ }
218
+ return ctx->DynamicMsg;
219
+ }
220
+
221
+ /* Print an error. Mostly useful for debugging. */
222
+ void
223
+ ndt_err_fprint(FILE *fp, ndt_context_t *ctx)
224
+ {
225
+ const char *err = ndt_err_as_string(ctx->err);
226
+
227
+ fprintf(fp, "%s: %s\n", err, ndt_context_msg(ctx));
228
+ }
@@ -0,0 +1,634 @@
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 <string.h>
36
+ #include <assert.h>
37
+ #include "ndtypes.h"
38
+
39
+
40
+ static inline void
41
+ copy_common(ndt_t *u, const ndt_t *t)
42
+ {
43
+ assert(u->tag == t->tag);
44
+ u->access = t->access;
45
+ u->flags = t->flags;
46
+ u->ndim = t->ndim;
47
+ u->datasize = t->datasize;
48
+ u->align = t->align;
49
+ }
50
+
51
+ static ndt_t *
52
+ ndt_copy_var_dim(const ndt_t *t, ndt_context_t *ctx)
53
+ {
54
+ ndt_t *type;
55
+ ndt_slice_t *slices;
56
+ int nslices;
57
+
58
+ assert(t->tag == VarDim);
59
+
60
+ type = ndt_copy(t->VarDim.type, ctx);
61
+ if (type == NULL) {
62
+ return NULL;
63
+ }
64
+
65
+ if (ndt_is_abstract(t)) {
66
+ return ndt_abstract_var_dim(type, ctx);
67
+ }
68
+
69
+ slices = NULL;
70
+ nslices = t->Concrete.VarDim.nslices;
71
+
72
+ if (nslices > 0) {
73
+ slices = ndt_alloc(nslices, sizeof *slices);
74
+ if (slices == NULL) {
75
+ return ndt_memory_error(ctx);
76
+ }
77
+ memcpy(slices, t->Concrete.VarDim.slices,
78
+ nslices * (sizeof *slices));
79
+ }
80
+
81
+ return ndt_var_dim(type, ExternalOffsets,
82
+ t->Concrete.VarDim.noffsets,
83
+ t->Concrete.VarDim.offsets,
84
+ nslices,
85
+ slices, ctx);
86
+ }
87
+
88
+ static ndt_t *
89
+ ndt_copy_function(const ndt_t *t, ndt_context_t *ctx)
90
+ {
91
+ ndt_t *u;
92
+ int64_t i;
93
+
94
+ assert(t->tag == Function);
95
+
96
+ u = ndt_function_new(t->Function.nargs, ctx);
97
+ if (u == NULL) {
98
+ return NULL;
99
+ }
100
+ u->Function.nin = t->Function.nin;
101
+ u->Function.nout = t->Function.nout;
102
+
103
+ copy_common(u, t);
104
+
105
+ for (i = 0; i < t->Function.nargs; i++) {
106
+ u->Function.types[i] = ndt_copy(t->Function.types[i], ctx);
107
+ if (u->Function.types[i] == NULL) {
108
+ ndt_del(u);
109
+ return NULL;
110
+ }
111
+ }
112
+
113
+ return u;
114
+ }
115
+
116
+ static ndt_t *
117
+ ndt_copy_tuple(const ndt_t *t, ndt_context_t *ctx)
118
+ {
119
+ ndt_t *u;
120
+ int64_t i;
121
+
122
+ assert(t->tag == Tuple);
123
+
124
+ u = ndt_tuple_new(t->Tuple.flag, t->Tuple.shape, ctx);
125
+ if (u == NULL) {
126
+ return NULL;
127
+ }
128
+
129
+ copy_common(u, t);
130
+
131
+ for (i = 0; i < t->Tuple.shape; i++) {
132
+ u->Tuple.types[i] = ndt_copy(t->Tuple.types[i], ctx);
133
+ if (u->Tuple.types[i] == NULL) {
134
+ ndt_del(u);
135
+ return NULL;
136
+ }
137
+
138
+ u->Concrete.Tuple.offset[i] = t->Concrete.Tuple.offset[i];
139
+ u->Concrete.Tuple.align[i] = t->Concrete.Tuple.align[i];
140
+ u->Concrete.Tuple.pad[i] = t->Concrete.Tuple.pad[i];
141
+ }
142
+
143
+ return u;
144
+ }
145
+
146
+ static ndt_t *
147
+ ndt_copy_record(const ndt_t *t, ndt_context_t *ctx)
148
+ {
149
+ ndt_t *u;
150
+ int64_t i;
151
+
152
+ assert(t->tag == Record);
153
+
154
+ u = ndt_record_new(t->Record.flag, t->Record.shape, ctx);
155
+ if (u == NULL) {
156
+ return NULL;
157
+ }
158
+
159
+ copy_common(u, t);
160
+
161
+ for (i = 0; i < t->Record.shape; i++) {
162
+ u->Record.names[i] = ndt_strdup(t->Record.names[i], ctx);
163
+ if (u->Record.names[i] == NULL) {
164
+ ndt_del(u);
165
+ return NULL;
166
+ }
167
+
168
+ u->Record.types[i] = ndt_copy(t->Record.types[i], ctx);
169
+ if (u->Record.types[i] == NULL) {
170
+ ndt_del(u);
171
+ return NULL;
172
+ }
173
+
174
+ u->Concrete.Record.offset[i] = t->Concrete.Record.offset[i];
175
+ u->Concrete.Record.align[i] = t->Concrete.Record.align[i];
176
+ u->Concrete.Record.pad[i] = t->Concrete.Record.pad[i];
177
+ }
178
+
179
+ return u;
180
+ }
181
+
182
+ static int
183
+ ndt_copy_value(ndt_value_t *v, const ndt_value_t *u, ndt_context_t *ctx)
184
+ {
185
+ *v = *u;
186
+
187
+ switch (u->tag) {
188
+ case ValString:
189
+ v->ValString = ndt_strdup(u->ValString, ctx);
190
+ if (v->ValString == NULL) {
191
+ return -1;
192
+ }
193
+ return 0;
194
+ case ValNA: case ValBool: case ValInt64: case ValFloat64:
195
+ return 0;
196
+ }
197
+
198
+ /* NOT REACHED: tags should be exhaustive */
199
+ ndt_err_format(ctx, NDT_RuntimeError, "ndt_copy_value: unexpected tag");
200
+ return -1;
201
+ }
202
+
203
+ static ndt_t *
204
+ ndt_copy_categorical(const ndt_t *t, ndt_context_t *ctx)
205
+ {
206
+ int64_t ntypes = t->Categorical.ntypes;
207
+ ndt_value_t *types;
208
+ int64_t i;
209
+
210
+ assert(t->tag == Categorical);
211
+
212
+ types = ndt_alloc(ntypes, sizeof(ndt_value_t));
213
+ if (types == NULL) {
214
+ return ndt_memory_error(ctx);
215
+ }
216
+
217
+ for (i = 0; i < ntypes; i++) {
218
+ types[i].tag = ValNA;
219
+ }
220
+
221
+ for (i = 0; i < ntypes; i++) {
222
+ if (ndt_copy_value(types+i, t->Categorical.types+i, ctx) < 0) {
223
+ ndt_value_array_del(types, ntypes);
224
+ return NULL;
225
+ }
226
+ }
227
+
228
+ return ndt_categorical(types, ntypes, ctx);
229
+ }
230
+
231
+ ndt_t *
232
+ ndt_copy(const ndt_t *t, ndt_context_t *ctx)
233
+ {
234
+ ndt_t *u = NULL;
235
+ ndt_t *type;
236
+
237
+ switch (t->tag) {
238
+ case FixedDim: {
239
+ type = ndt_copy(t->FixedDim.type, ctx);
240
+ if (type == NULL) {
241
+ return NULL;
242
+ }
243
+
244
+ u = ndt_fixed_dim_tag(type, t->FixedDim.tag, t->FixedDim.shape,
245
+ t->Concrete.FixedDim.step, ctx);
246
+ goto copy_common_fields;
247
+ }
248
+
249
+ case VarDim: {
250
+ u = ndt_copy_var_dim(t, ctx);
251
+ goto copy_common_fields;
252
+ }
253
+
254
+ case SymbolicDim: {
255
+ char *name;
256
+
257
+ type = ndt_copy(t->SymbolicDim.type, ctx);
258
+ if (type == NULL) {
259
+ return NULL;
260
+ }
261
+
262
+ name = ndt_strdup(t->SymbolicDim.name, ctx);
263
+ if (name == NULL) {
264
+ ndt_del(type);
265
+ return NULL;
266
+ }
267
+
268
+ u = ndt_symbolic_dim_tag(name, type, t->SymbolicDim.tag, ctx);
269
+ goto copy_common_fields;
270
+ }
271
+
272
+ case EllipsisDim: {
273
+ char *name = NULL;
274
+
275
+ type = ndt_copy(t->EllipsisDim.type, ctx);
276
+ if (type == NULL) {
277
+ return NULL;
278
+ }
279
+
280
+ if (t->EllipsisDim.name != NULL) {
281
+ name = ndt_strdup(t->SymbolicDim.name, ctx);
282
+ if (name == NULL) {
283
+ ndt_del(type);
284
+ return NULL;
285
+ }
286
+ }
287
+
288
+ u = ndt_ellipsis_dim_tag(name, type, t->EllipsisDim.tag, ctx);
289
+ goto copy_common_fields;
290
+ }
291
+
292
+ case Tuple: {
293
+ return ndt_copy_tuple(t, ctx);
294
+ }
295
+
296
+ case Record: {
297
+ return ndt_copy_record(t, ctx);
298
+ }
299
+
300
+ case Ref: {
301
+ type = ndt_copy(t->Ref.type, ctx);
302
+ if (type == NULL) {
303
+ return NULL;
304
+ }
305
+
306
+ u = ndt_ref(type, ctx);
307
+ goto copy_common_fields;
308
+ }
309
+
310
+ case Constr: {
311
+ char *name = ndt_strdup(t->Constr.name, ctx);
312
+ if (name == NULL) {
313
+ return NULL;
314
+ }
315
+
316
+ type = ndt_copy(t->Constr.type, ctx);
317
+ if (type == NULL) {
318
+ ndt_free(name);
319
+ return NULL;
320
+ }
321
+
322
+ u = ndt_constr(name, type, ctx);
323
+ goto copy_common_fields;
324
+ }
325
+
326
+ case Nominal: {
327
+ char *name = ndt_strdup(t->Nominal.name, ctx);
328
+ if (name == NULL) {
329
+ return NULL;
330
+ }
331
+
332
+ type = ndt_copy(t->Nominal.type, ctx);
333
+ if (type == NULL) {
334
+ ndt_free(name);
335
+ return NULL;
336
+ }
337
+
338
+ u = ndt_nominal(name, type, ctx);
339
+ goto copy_common_fields;
340
+ }
341
+
342
+ case Categorical: {
343
+ u = ndt_copy_categorical(t, ctx);
344
+ goto copy_common_fields;
345
+ }
346
+
347
+ case Typevar: {
348
+ char *name;
349
+
350
+ name = ndt_strdup(t->Typevar.name, ctx);
351
+ if (name == NULL) {
352
+ return NULL;
353
+ }
354
+
355
+ u = ndt_typevar(name, ctx);
356
+ goto copy_common_fields;
357
+ }
358
+
359
+ case Function: {
360
+ return ndt_copy_function(t, ctx);
361
+ }
362
+
363
+ case Module: {
364
+ char *name;
365
+
366
+ type = ndt_copy(t->Module.type, ctx);
367
+ if (type == NULL) {
368
+ return NULL;
369
+ }
370
+
371
+ name = ndt_strdup(t->Module.name, ctx);
372
+ if (name == NULL) {
373
+ ndt_del(type);
374
+ return NULL;
375
+ }
376
+
377
+ u = ndt_module(name, type, ctx);
378
+ goto copy_common_fields;
379
+ }
380
+
381
+ case AnyKind:
382
+ case ScalarKind:
383
+ case SignedKind: case UnsignedKind:
384
+ case FloatKind: case ComplexKind:
385
+ case FixedStringKind: case FixedBytesKind:
386
+ case Bool:
387
+ case Int8: case Int16: case Int32: case Int64:
388
+ case Uint8: case Uint16: case Uint32: case Uint64:
389
+ case Float16: case Float32: case Float64:
390
+ case Complex32: case Complex64: case Complex128:
391
+ case FixedString: case FixedBytes:
392
+ case String: case Bytes:
393
+ case Char: {
394
+ u = ndt_new(t->tag, ctx);
395
+ if (u == NULL) {
396
+ return NULL;
397
+ }
398
+ *u = *t;
399
+ return u;
400
+ }
401
+ }
402
+
403
+ goto invalid_tag;
404
+
405
+
406
+ copy_common_fields:
407
+ if (u == NULL) {
408
+ return NULL;
409
+ }
410
+
411
+ copy_common(u, t);
412
+ return u;
413
+
414
+ invalid_tag:
415
+ /* NOT REACHED: tags should be exhaustive */
416
+ ndt_err_format(ctx, NDT_RuntimeError, "ndt_copy: unexpected tag");
417
+ return NULL;
418
+ }
419
+
420
+ static ndt_t *
421
+ fixed_copy_contiguous(const ndt_t *t, ndt_t *type, ndt_context_t *ctx)
422
+ {
423
+ if (t->ndim == 0) {
424
+ return type;
425
+ }
426
+
427
+ assert(t->tag == FixedDim);
428
+ assert(ndt_is_concrete(t));
429
+ type = fixed_copy_contiguous(t->FixedDim.type, type, ctx);
430
+ if (type == NULL) {
431
+ ndt_del(type);
432
+ return NULL;
433
+ }
434
+
435
+ return ndt_fixed_dim_tag(type, t->FixedDim.tag, t->FixedDim.shape,
436
+ INT64_MAX, ctx);
437
+ }
438
+
439
+ typedef struct {
440
+ int maxdim;
441
+ int32_t index[NDT_MAX_DIM+1];
442
+ int32_t noffsets[NDT_MAX_DIM+1];
443
+ int32_t *offsets[NDT_MAX_DIM+1];
444
+ } offsets_t;
445
+
446
+ static void
447
+ clear_offsets(offsets_t *m)
448
+ {
449
+ for (int i = 0; i < NDT_MAX_DIM+1; i++) {
450
+ ndt_free(m->offsets[i]);
451
+ }
452
+ }
453
+
454
+ static int
455
+ var_init_offsets(offsets_t *m, const ndt_t *t, int32_t noffsets, ndt_context_t *ctx)
456
+ {
457
+ int32_t *offsets;
458
+ int64_t shape, start, step;
459
+ int64_t sum;
460
+ int32_t i;
461
+
462
+ assert(t->ndim >= 1);
463
+
464
+ offsets = ndt_alloc(noffsets, sizeof *offsets);
465
+ if (offsets == NULL) {
466
+ clear_offsets(m);
467
+ (void)ndt_memory_error(ctx);
468
+ return -1;
469
+ }
470
+ m->noffsets[t->ndim] = noffsets;
471
+ m->offsets[t->ndim] = offsets;
472
+
473
+ if (t->ndim == 1) {
474
+ return 0;
475
+ }
476
+
477
+ for (i=0, sum=0; i < noffsets-1; i++) {
478
+ shape = ndt_var_indices(&start, &step, t, i, ctx);
479
+ if (shape == -1) {
480
+ clear_offsets(m);
481
+ return -1;
482
+ }
483
+ sum += shape;
484
+ }
485
+
486
+ return var_init_offsets(m, t->VarDim.type, (int32_t)sum+1, ctx);
487
+ }
488
+
489
+ static int
490
+ var_copy_shapes(offsets_t *m, int64_t src_index, const ndt_t *t, ndt_context_t *ctx)
491
+ {
492
+ int64_t shape, start, step;
493
+
494
+ if (t->ndim == 0) {
495
+ return 0;
496
+ }
497
+
498
+ shape = ndt_var_indices(&start, &step, t, src_index, ctx);
499
+ if (shape < 0) {
500
+ clear_offsets(m);
501
+ return -1;
502
+ }
503
+ int32_t dst_index = m->index[t->ndim]++;
504
+ m->offsets[t->ndim][dst_index] = (int32_t)shape;
505
+
506
+ for (int64_t i = 0; i < shape; i++) {
507
+ int64_t src_next = start + i * step;
508
+ if (var_copy_shapes(m, src_next, t->VarDim.type, ctx) < 0) {
509
+ clear_offsets(m);
510
+ return -1;
511
+ }
512
+ }
513
+
514
+ return 0;
515
+ }
516
+
517
+ static void
518
+ var_sum_shapes(offsets_t *m)
519
+ {
520
+ int i, k;
521
+
522
+ for (i = 1; i <= m->maxdim; i++) {
523
+ int32_t sum = 0;
524
+ for (k = 0; k < m->noffsets[i]; k++) {
525
+ int32_t s = m->offsets[i][k];
526
+ m->offsets[i][k] = sum;
527
+ sum += s;
528
+ }
529
+ }
530
+ }
531
+
532
+ ndt_t *
533
+ var_from_offsets_and_dtype(offsets_t *m, ndt_t *type, ndt_context_t *ctx)
534
+ {
535
+ ndt_t *t;
536
+ int i;
537
+
538
+ for (i=1, t=type; i <= m->maxdim; i++, type=t) {
539
+ t = ndt_var_dim(type, InternalOffsets, m->noffsets[i], m->offsets[i],
540
+ 0, NULL, ctx);
541
+ m->offsets[i] = NULL;
542
+ if (t == NULL) {
543
+ clear_offsets(m);
544
+ return NULL;
545
+ }
546
+ }
547
+
548
+ return t;
549
+ }
550
+
551
+ static ndt_t *
552
+ var_copy_contiguous(const ndt_t *t, ndt_t *dtype, ndt_context_t *ctx)
553
+ {
554
+ offsets_t m = {.maxdim=0, .index={0}, .noffsets={0}, .offsets={NULL}};
555
+
556
+ assert(t->tag == VarDim);
557
+ assert(ndt_is_concrete(t));
558
+ assert(t->Concrete.VarDim.noffsets == 2);
559
+
560
+ if (var_init_offsets(&m, t, 2, ctx) < 0) {
561
+ ndt_del(dtype);
562
+ return NULL;
563
+ }
564
+ m.maxdim = t->ndim;
565
+
566
+ if (var_copy_shapes(&m, 0, t, ctx) < 0) {
567
+ ndt_del(dtype);
568
+ return NULL;
569
+ }
570
+
571
+ var_sum_shapes(&m);
572
+
573
+ return var_from_offsets_and_dtype(&m, dtype, ctx);
574
+ }
575
+
576
+ ndt_t *
577
+ ndt_copy_contiguous_dtype(const ndt_t *t, ndt_t *dtype, ndt_context_t *ctx)
578
+ {
579
+ if (ndt_is_abstract(t) || ndt_is_abstract(dtype)) {
580
+ ndt_err_format(ctx, NDT_ValueError,
581
+ "copy_new_dtype() called on abstract type");
582
+ return NULL;
583
+ }
584
+
585
+ switch (t->tag) {
586
+ case FixedDim: {
587
+ return fixed_copy_contiguous(t, dtype, ctx);
588
+ }
589
+ case VarDim: {
590
+ return var_copy_contiguous(t, dtype, ctx);
591
+ }
592
+ default:
593
+ return dtype;
594
+ }
595
+ }
596
+
597
+ ndt_t *
598
+ ndt_copy_contiguous(const ndt_t *t, ndt_context_t *ctx)
599
+ {
600
+ ndt_t *dtype = ndt_copy(ndt_dtype(t), ctx);
601
+ if (dtype == NULL) {
602
+ return NULL;
603
+ }
604
+
605
+ return ndt_copy_contiguous_dtype(t, dtype, ctx);
606
+ }
607
+
608
+ ndt_t *
609
+ ndt_copy_abstract_var_dtype(const ndt_t *t, ndt_t *dtype, ndt_context_t *ctx)
610
+ {
611
+ if (t->ndim == 0) {
612
+ return dtype;
613
+ }
614
+
615
+ switch (t->tag) {
616
+ case VarDim: {
617
+ if (!ndt_is_abstract(t)) {
618
+ ndt_err_format(ctx, NDT_ValueError,
619
+ "ndt_copy_abstract_var_dtype() called on concrete type");
620
+ return NULL;
621
+ }
622
+ ndt_t *u = ndt_copy_abstract_var_dtype(t->VarDim.type, dtype, ctx);
623
+ if (u == NULL) {
624
+ return NULL;
625
+ }
626
+
627
+ return ndt_abstract_var_dim(u, ctx);
628
+ }
629
+ default:
630
+ ndt_err_format(ctx, NDT_ValueError,
631
+ "ndt_copy_abstract_var_dtype(): not a var dimension");
632
+ return NULL;
633
+ }
634
+ }