ndtypes 0.2.0dev5 → 0.2.0dev6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +12 -0
  3. data/Rakefile +8 -0
  4. data/ext/ruby_ndtypes/GPATH +0 -0
  5. data/ext/ruby_ndtypes/GRTAGS +0 -0
  6. data/ext/ruby_ndtypes/GTAGS +0 -0
  7. data/ext/ruby_ndtypes/extconf.rb +1 -1
  8. data/ext/ruby_ndtypes/include/ndtypes.h +231 -122
  9. data/ext/ruby_ndtypes/include/ruby_ndtypes.h +1 -1
  10. data/ext/ruby_ndtypes/lib/libndtypes.a +0 -0
  11. data/ext/ruby_ndtypes/lib/libndtypes.so.0.2.0dev3 +0 -0
  12. data/ext/ruby_ndtypes/ndtypes/Makefile +87 -0
  13. data/ext/ruby_ndtypes/ndtypes/config.h +68 -0
  14. data/ext/ruby_ndtypes/ndtypes/config.log +477 -0
  15. data/ext/ruby_ndtypes/ndtypes/config.status +1027 -0
  16. data/ext/ruby_ndtypes/ndtypes/doc/_static/style.css +7 -0
  17. data/ext/ruby_ndtypes/ndtypes/doc/_templates/layout.html +2 -0
  18. data/ext/ruby_ndtypes/ndtypes/doc/conf.py +40 -4
  19. data/ext/ruby_ndtypes/ndtypes/doc/images/xndlogo.png +0 -0
  20. data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/types.rst +1 -1
  21. data/ext/ruby_ndtypes/ndtypes/doc/requirements.txt +2 -0
  22. data/ext/ruby_ndtypes/ndtypes/libndtypes/Makefile +287 -0
  23. data/ext/ruby_ndtypes/ndtypes/libndtypes/Makefile.in +20 -4
  24. data/ext/ruby_ndtypes/ndtypes/libndtypes/Makefile.vc +22 -3
  25. data/ext/ruby_ndtypes/ndtypes/libndtypes/alloc.c +1 -1
  26. data/ext/ruby_ndtypes/ndtypes/libndtypes/alloc.o +0 -0
  27. data/ext/ruby_ndtypes/ndtypes/libndtypes/attr.o +0 -0
  28. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/Makefile +73 -0
  29. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.c +246 -229
  30. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.h +15 -11
  31. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.o +0 -0
  32. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.y +38 -28
  33. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.c +91 -91
  34. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.h +1 -1
  35. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.l +4 -3
  36. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.o +0 -0
  37. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/export.c +8 -7
  38. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/export.o +0 -0
  39. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/import.c +2 -2
  40. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/import.o +0 -0
  41. data/ext/ruby_ndtypes/ndtypes/libndtypes/context.o +0 -0
  42. data/ext/ruby_ndtypes/ndtypes/libndtypes/copy.c +263 -182
  43. data/ext/ruby_ndtypes/ndtypes/libndtypes/copy.o +0 -0
  44. data/ext/ruby_ndtypes/ndtypes/libndtypes/encodings.o +0 -0
  45. data/ext/ruby_ndtypes/ndtypes/libndtypes/equal.c +67 -7
  46. data/ext/ruby_ndtypes/ndtypes/libndtypes/equal.o +0 -0
  47. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.c +1112 -1000
  48. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.h +69 -58
  49. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.o +0 -0
  50. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.y +150 -99
  51. data/ext/ruby_ndtypes/ndtypes/libndtypes/io.c +185 -15
  52. data/ext/ruby_ndtypes/ndtypes/libndtypes/io.o +0 -0
  53. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.c +301 -276
  54. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.h +1 -1
  55. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.l +9 -4
  56. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.o +0 -0
  57. data/ext/ruby_ndtypes/ndtypes/libndtypes/libndtypes.a +0 -0
  58. data/ext/ruby_ndtypes/ndtypes/libndtypes/libndtypes.so +1 -0
  59. data/ext/ruby_ndtypes/ndtypes/libndtypes/libndtypes.so.0 +1 -0
  60. data/ext/ruby_ndtypes/ndtypes/libndtypes/libndtypes.so.0.2.0dev3 +0 -0
  61. data/ext/ruby_ndtypes/ndtypes/libndtypes/match.c +729 -228
  62. data/ext/ruby_ndtypes/ndtypes/libndtypes/match.o +0 -0
  63. data/ext/ruby_ndtypes/ndtypes/libndtypes/ndtypes.c +768 -403
  64. data/ext/ruby_ndtypes/ndtypes/libndtypes/ndtypes.h +1002 -0
  65. data/ext/ruby_ndtypes/ndtypes/libndtypes/ndtypes.h.in +231 -122
  66. data/ext/ruby_ndtypes/ndtypes/libndtypes/ndtypes.o +0 -0
  67. data/ext/ruby_ndtypes/ndtypes/libndtypes/parsefuncs.c +176 -84
  68. data/ext/ruby_ndtypes/ndtypes/libndtypes/parsefuncs.h +26 -14
  69. data/ext/ruby_ndtypes/ndtypes/libndtypes/parsefuncs.o +0 -0
  70. data/ext/ruby_ndtypes/ndtypes/libndtypes/parser.c +57 -35
  71. data/ext/ruby_ndtypes/ndtypes/libndtypes/parser.o +0 -0
  72. data/ext/ruby_ndtypes/ndtypes/libndtypes/primitive.c +420 -0
  73. data/ext/ruby_ndtypes/ndtypes/libndtypes/primitive.o +0 -0
  74. data/ext/ruby_ndtypes/ndtypes/libndtypes/seq.c +8 -8
  75. data/ext/ruby_ndtypes/ndtypes/libndtypes/seq.h +1 -1
  76. data/ext/ruby_ndtypes/ndtypes/libndtypes/seq.o +0 -0
  77. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/Makefile +48 -0
  78. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/deserialize.c +200 -116
  79. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/deserialize.o +0 -0
  80. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/serialize.c +46 -4
  81. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/serialize.o +0 -0
  82. data/ext/ruby_ndtypes/ndtypes/libndtypes/substitute.c +58 -27
  83. data/ext/ruby_ndtypes/ndtypes/libndtypes/substitute.h +1 -1
  84. data/ext/ruby_ndtypes/ndtypes/libndtypes/substitute.o +0 -0
  85. data/ext/ruby_ndtypes/ndtypes/libndtypes/symtable.c +3 -5
  86. data/ext/ruby_ndtypes/ndtypes/libndtypes/symtable.h +12 -4
  87. data/ext/ruby_ndtypes/ndtypes/libndtypes/symtable.o +0 -0
  88. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/Makefile +55 -0
  89. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/Makefile.in +8 -8
  90. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/Makefile.vc +5 -5
  91. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/runtest.c +274 -172
  92. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test.h +24 -4
  93. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_array.c +2 -2
  94. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_buffer.c +14 -14
  95. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_match.c +32 -30
  96. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_parse.c +37 -0
  97. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_parse_error.c +36 -0
  98. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_parse_roundtrip.c +16 -0
  99. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_record.c +5 -5
  100. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_typecheck.c +706 -253
  101. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_unify.c +132 -0
  102. data/ext/ruby_ndtypes/ndtypes/libndtypes/unify.c +703 -0
  103. data/ext/ruby_ndtypes/ndtypes/libndtypes/unify.o +0 -0
  104. data/ext/ruby_ndtypes/ndtypes/libndtypes/util.c +335 -127
  105. data/ext/ruby_ndtypes/ndtypes/libndtypes/util.o +0 -0
  106. data/ext/ruby_ndtypes/ndtypes/libndtypes/values.c +2 -2
  107. data/ext/ruby_ndtypes/ndtypes/libndtypes/values.o +0 -0
  108. data/ext/ruby_ndtypes/ndtypes/python/ndt_randtype.py +88 -71
  109. data/ext/ruby_ndtypes/ndtypes/python/ndt_support.py +0 -1
  110. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/__init__.py +10 -13
  111. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/_ndtypes.c +395 -314
  112. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/libndtypes.a +0 -0
  113. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/libndtypes.so +1 -0
  114. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/libndtypes.so.0 +1 -0
  115. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/libndtypes.so.0.2.0dev3 +0 -0
  116. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/ndtypes.h +1002 -0
  117. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/pyndtypes.h +15 -33
  118. data/ext/ruby_ndtypes/ndtypes/python/test_ndtypes.py +340 -132
  119. data/ext/ruby_ndtypes/ndtypes/setup.py +11 -2
  120. data/ext/ruby_ndtypes/ruby_ndtypes.c +364 -241
  121. data/ext/ruby_ndtypes/ruby_ndtypes.h +1 -1
  122. data/ext/ruby_ndtypes/ruby_ndtypes_internal.h +0 -1
  123. data/lib/ndtypes.rb +11 -0
  124. data/lib/ndtypes/version.rb +2 -2
  125. data/lib/ruby_ndtypes.so +0 -0
  126. data/ndtypes.gemspec +3 -0
  127. data/spec/ndtypes_spec.rb +6 -0
  128. metadata +98 -4
  129. data/ext/ruby_ndtypes/gc_guard.c +0 -36
  130. data/ext/ruby_ndtypes/gc_guard.h +0 -12
@@ -42,6 +42,7 @@ from distutils.sysconfig import get_python_lib
42
42
  from glob import glob
43
43
  import platform
44
44
  import subprocess
45
+ import argparse
45
46
  import shutil
46
47
 
47
48
  try:
@@ -81,6 +82,13 @@ Links
81
82
  * http://xnd.readthedocs.io/en/latest/
82
83
  """
83
84
 
85
+ # Pre-parse and remove the '-j' argument from sys.argv.
86
+ parser = argparse.ArgumentParser()
87
+ parser.add_argument('-j', default=None)
88
+ values, rest = parser.parse_known_args()
89
+ PARALLEL = values.j
90
+ sys.argv = sys.argv[:1] + rest
91
+
84
92
 
85
93
  if sys.platform == "darwin":
86
94
  LIBNAME = "libndtypes.dylib"
@@ -230,10 +238,11 @@ def ndtypes_ext():
230
238
  runtime_library_dirs = ["$ORIGIN"]
231
239
 
232
240
  if BUILD_ALL:
241
+ make = "make -j%d" % int(PARALLEL) if PARALLEL else "make"
233
242
  if WITH_VALGRIND:
234
- os.system("./configure --with-valgrind && make")
243
+ os.system("./configure --with-valgrind && %s" % make)
235
244
  else:
236
- os.system("./configure && make")
245
+ os.system("./configure && %s" % make)
237
246
 
238
247
  return Extension (
239
248
  "ndtypes._ndtypes",
@@ -8,7 +8,6 @@
8
8
  /* ---------- Interal declarations ---------- */
9
9
  /* data_type_t variables. */
10
10
  static const rb_data_type_t NdtObject_type;
11
- static const rb_data_type_t ResourceBufferObject_type;
12
11
 
13
12
  /* Class declarations. */
14
13
  VALUE cNDTypes;
@@ -82,148 +81,14 @@ seterr(ndt_context_t *ctx)
82
81
  return exc;
83
82
  }
84
83
 
85
- /******************************************************************************/
86
- /************************* Resource Buffer Object *****************************/
87
-
88
- /* A ResourceBufferObject is passed around various NDT objects for storing
89
- * internal state. It might or might not be duplicated across other NDT
90
- * objects.
91
- */
92
- typedef struct ResourceBufferObject {
93
- ndt_meta_t *m;
94
- } ResourceBufferObject;
95
-
96
- #define GET_RBUF(obj, rbuf_p) do { \
97
- TypedData_Get_Struct((obj), ResourceBufferObject, \
98
- &ResourceBufferObject_type, (rbuf_p)); \
99
- } while (0)
100
- #define RBUF_NDT_M(rbuf_p) ((ndt_meta_t*)(rbuf_p->m))
101
- #define MAKE_RBUF(self, rbuf_p) TypedData_Make_Struct(self, ResourceBufferObject, \
102
- &ResourceBufferObject_type, rbuf_p)
103
- #define WRAP_RBUF(self, rbuf_p) TypedData_Wrap_Struct(self, \
104
- &ResourceBufferObject_type, rbuf_p)
105
-
106
- /* GC free the ResourceBufferObject struct. */
107
- static void
108
- ResourceBufferObject_dfree(void * self)
109
- {
110
- ResourceBufferObject * rbf = (ResourceBufferObject*)self;
111
-
112
- ndt_meta_del(rbf->m);
113
- rbf->m = NULL;
114
- xfree(rbf);
115
- }
116
-
117
- /* Calculate the size of the object. */
118
- static size_t
119
- ResourceBufferObject_dsize(const void *self)
120
- {
121
- return sizeof(ResourceBufferObject);
122
- }
123
-
124
- static const rb_data_type_t ResourceBufferObject_type = {
125
- .wrap_struct_name = "ResourceBufferObject",
126
- .function = {
127
- .dmark = 0,
128
- .dfree = ResourceBufferObject_dfree,
129
- .dsize = ResourceBufferObject_dsize,
130
- .reserved = {0,0},
131
- },
132
- .parent = 0,
133
- .flags = RUBY_TYPED_FREE_IMMEDIATELY,
134
- };
135
-
136
- /* FIXME: change this to rbuf_alloc to reflect that its not called by Ruby alloc. */
137
- static VALUE
138
- rbuf_allocate(void)
139
- {
140
- NDT_STATIC_CONTEXT(ctx);
141
- ResourceBufferObject *self;
142
-
143
- self = ALLOC(ResourceBufferObject);
144
-
145
- self->m = ndt_meta_new(&ctx);
146
- if (self->m == NULL) {
147
- rb_raise(rb_eNoMemError, "cannot allocate rbuf object.");
148
- }
149
-
150
- return WRAP_RBUF(cNDTypes_RBuf, self);
151
- }
152
-
153
- static int
154
- rbuf_init_from_offset_list(ResourceBufferObject *rbuf, VALUE list)
155
- {
156
- ndt_meta_t * const m = rbuf->m;
157
- VALUE lst;
158
-
159
- Check_Type(list, T_ARRAY);
160
-
161
- const int64_t n = RARRAY_LEN(list);
162
- if (n < 1 || n > NDT_MAX_DIM) {
163
- rb_raise(rb_eValueError, "number of offset lists must be in [1, %d].",
164
- NDT_MAX_DIM);
165
- }
166
-
167
- m->ndims = 0;
168
- for (int64_t i = n-1; i >= 0; i--) {
169
- lst = rb_ary_entry(list, i);
170
- if (!RB_TYPE_P(lst, T_ARRAY)) {
171
- rb_raise(rb_eTypeError, "expected a list of offset lists.");
172
- }
173
-
174
- const int64_t noffsets = RARRAY_LEN(lst);
175
- if (noffsets < 2 || noffsets > INT32_MAX) {
176
- rb_raise(rb_eValueError, "length of a single offset must be in [2, INT32_MAX].");
177
- }
178
-
179
- int32_t * const offsets = ndt_alloc(noffsets, sizeof(int32_t));
180
- if (offsets == NULL) {
181
- rb_raise(rb_eNoMemError, "could not allocate offsets.");
182
- }
183
-
184
- for (int32_t k = 0; k < noffsets; k++) {
185
- long long x = NUM2LL(rb_ary_entry(lst, k));
186
- if (x == -1 || x < 0 || x > INT32_MAX) {
187
- ndt_free(offsets);
188
- rb_raise(rb_eValueError, "offset must be in [0, INT32_MAX].");
189
- }
190
-
191
- offsets[k] = (int32_t)x;
192
- }
193
-
194
- m->noffsets[m->ndims] = (int32_t)noffsets;
195
- m->offsets[m->ndims] = offsets;
196
- m->ndims++;
197
- }
198
-
199
- return 0;
200
- }
201
-
202
- static VALUE
203
- rbuf_from_offset_lists(VALUE list)
204
- {
205
- VALUE rbuf;
206
- ResourceBufferObject * rbuf_p;
207
-
208
- rbuf = rbuf_allocate();
209
- GET_RBUF(rbuf, rbuf_p);
210
- rbuf_init_from_offset_list(rbuf_p, list);
211
-
212
- return rbuf;
213
- }
214
-
215
- /******************************************************************************/
216
-
217
84
  /******************************************************************************/
218
85
  /************************* NDT struct object **********************************/
219
86
 
220
87
  typedef struct NdtObject {
221
- VALUE rbuf; /* resource buffer */
222
- ndt_t *ndt; /* type */
88
+ const ndt_t *ndt; /* type */
223
89
  } NdtObject;
224
90
 
225
91
  #define NDT(v) (((NdtObject *)v)->ndt)
226
- #define RBUF(v) (((NdtObject *)v)->rbuf)
227
92
  #define GET_NDT(obj, ndt_p) do { \
228
93
  TypedData_Get_Struct((obj), NdtObject, \
229
94
  &NdtObject_type, (ndt_p)); \
@@ -232,20 +97,6 @@ typedef struct NdtObject {
232
97
  &NdtObject_type, ndt_p)
233
98
  #define WRAP_NDT(self, ndt_p) TypedData_Wrap_Struct(self, &NdtObject_type, ndt_p)
234
99
  #define NDT_CHECK_TYPE(obj) (CLASS_OF(obj) == cNDTypes)
235
-
236
- /* Get the metatdata of the ResourceBufferObject within this NDT Ruby object. */
237
- static ndt_meta_t *
238
- rbuf_ndt_meta(VALUE ndt)
239
- {
240
- NdtObject *ndt_p;
241
- ResourceBufferObject *rbuf_p;
242
-
243
- GET_NDT(ndt, ndt_p);
244
- GET_RBUF(ndt_p->rbuf, rbuf_p);
245
-
246
- return rbuf_p->m;
247
- }
248
-
249
100
  /* Allocate an NdtObject, initialize members and return wrapped as a Ruby object. */
250
101
  static VALUE
251
102
  NdtObject_alloc(void)
@@ -253,8 +104,6 @@ NdtObject_alloc(void)
253
104
  NdtObject *ndt_p;
254
105
 
255
106
  ndt_p = ZALLOC(NdtObject);
256
-
257
- ndt_p->rbuf = 0;
258
107
  ndt_p->ndt = NULL;
259
108
 
260
109
  return WRAP_NDT(cNDTypes, ndt_p);
@@ -263,20 +112,13 @@ NdtObject_alloc(void)
263
112
  /* GC mark the NdtObject struct. */
264
113
  /* TODO: verify that there are no more object allocations happening inside ndt. */
265
114
  static void
266
- NdtObject_dmark(void * self)
267
- {
268
- NdtObject * ndt = (NdtObject*)self;
269
-
270
- rb_gc_mark(ndt->rbuf);
271
- }
115
+ NdtObject_dmark(void * self) {}
272
116
 
273
117
  /* GC free the NdtObject struct. */
274
118
  static void
275
119
  NdtObject_dfree(void * self)
276
120
  {
277
121
  NdtObject * ndt = (NdtObject*)self;
278
-
279
- rb_ndtypes_gc_guard_unregister(ndt);
280
122
  xfree(ndt);
281
123
  }
282
124
 
@@ -333,13 +175,81 @@ NDTYPES_BOOL_FUNC(ndt_is_complex)
333
175
 
334
176
  NDTYPES_BOOL_FUNC(ndt_is_c_contiguous)
335
177
  NDTYPES_BOOL_FUNC(ndt_is_f_contiguous)
178
+ NDTYPES_BOOL_FUNC(ndt_is_var_contiguous)
179
+
180
+ static int
181
+ offsets_from_array(ndt_meta_t *m, VALUE array)
182
+ {
183
+ NDT_STATIC_CONTEXT(ctx);
184
+ VALUE temp;
185
+
186
+ Check_Type(array, T_ARRAY);
187
+
188
+ const int n = RARRAY_LEN(array);
189
+ if (n < 1 || n > NDT_MAX_DIM) {
190
+ rb_raise(rb_eValueError, "number of offsets arrays must be in [1, %d].", NDT_MAX_DIM);
191
+ }
192
+
193
+ m->ndims = 0;
194
+ for (int i = n-1; i >= 0; i--) {
195
+ temp = rb_ary_entry(array, i);
196
+ if (!RB_TYPE_P(temp, T_ARRAY)) {
197
+ rb_raise(rb_eValueError, "expected a list of offset lists.");
198
+ }
199
+
200
+ const int64_t noffsets = RARRAY_LEN(temp);
201
+ if (noffsets < 2 || noffsets > INT32_MAX) {
202
+ rb_raise(rb_eValueError, "length of a single offset list be in [2, INT32_MAX].");
203
+ }
204
+
205
+ int32_t * const offsets = ndt_alloc(noffsets, sizeof(int32_t));
206
+ if (offsets == NULL) {
207
+ rb_raise(rb_eNoMemError, "no memory to allocate offsets.");
208
+ }
209
+
210
+ for (int32_t k = 0; k < noffsets; k++) {
211
+ long long x = NUM2LL(rb_ary_entry(temp, k));
212
+
213
+ if (x < 0 || x > INT32_MAX) {
214
+ ndt_free(offsets);
215
+ rb_raise(rb_eValueError, "offset must be in [0, INT32_MAX].");
216
+ }
217
+ offsets[k] = (int32_t)x;
218
+ }
219
+
220
+ m->offsets[m->ndims] = ndt_offsets_from_ptr(offsets, (int32_t)noffsets, &ctx);
221
+ if (m->offsets[m->ndims] == NULL) {
222
+ seterr(&ctx);
223
+ raise_error();
224
+ }
225
+ m->ndims++;
226
+ }
227
+
228
+ return 0;
229
+ }
230
+
231
+ static VALUE
232
+ array_from_int64(int64_t x[NDT_MAX_DIM], int ndim)
233
+ {
234
+ VALUE array;
235
+ int i;
236
+
237
+ array = rb_ary_new2(ndim);
238
+
239
+ for (i = 0; i < ndim; ++i) {
240
+ VALUE v = LL2NUM(x[i]);
241
+ rb_ary_store(array, i, v);
242
+ }
243
+
244
+ return array;
245
+ }
336
246
 
337
247
  static VALUE
338
248
  NDTypes_from_object(VALUE self, VALUE type)
339
249
  {
340
250
  NDT_STATIC_CONTEXT(ctx);
341
251
  const char *cp;
342
- NdtObject *ndt_p;
252
+ NdtObject *self_p;
343
253
 
344
254
  if (NDT_CHECK_TYPE(type)) {
345
255
  return rb_funcall(type, rb_intern("dup"), 0, NULL);
@@ -347,16 +257,10 @@ NDTypes_from_object(VALUE self, VALUE type)
347
257
 
348
258
  cp = StringValuePtr(type);
349
259
 
350
- GET_NDT(self, ndt_p);
351
- RBUF(ndt_p) = rbuf_allocate();
352
- if (RBUF(ndt_p) == NULL) {
353
- rb_raise(rb_eNoMemError, "problem in allocating RBUF object.");
354
- }
355
-
356
- rb_ndtypes_gc_guard_register(ndt_p, RBUF(ndt_p));
260
+ GET_NDT(self, self_p);
357
261
 
358
- NDT(ndt_p) = ndt_from_string_fill_meta(rbuf_ndt_meta(self), cp, &ctx);
359
- if (NDT(ndt_p) == NULL) {
262
+ NDT(self_p) = ndt_from_string(cp, &ctx);
263
+ if (NDT(self_p) == NULL) {
360
264
  seterr(&ctx);
361
265
  raise_error();
362
266
  }
@@ -365,23 +269,33 @@ NDTypes_from_object(VALUE self, VALUE type)
365
269
  }
366
270
 
367
271
  static VALUE
368
- NDTypes_from_offsets_and_dtype(VALUE offsets, VALUE type)
272
+ NDTypes_from_offsets_and_dtype(VALUE self, VALUE offsets, VALUE type)
369
273
  {
370
274
  NDT_STATIC_CONTEXT(ctx);
371
- VALUE self;
372
275
  NdtObject *self_p;
276
+ ndt_meta_t m = {.ndims = 0, .offsets = {NULL}};
373
277
  const char *cp;
374
278
 
375
279
  Check_Type(type, T_STRING);
280
+ Check_Type(offsets, T_ARRAY);
376
281
 
377
282
  cp = StringValuePtr(type);
378
283
 
379
- self = NdtObject_alloc();
380
284
  GET_NDT(self, self_p);
381
- RBUF(self_p) = rbuf_from_offset_lists(offsets);
382
- NDT(self_p) = ndt_from_metadata_and_dtype(rbuf_ndt_meta(self_p), cp, &ctx);
383
285
 
384
- rb_ndtypes_gc_guard_register(self_p, RBUF(self_p));
286
+ if (offsets_from_array(&m, offsets) < 0) {
287
+ ndt_meta_clear(&m);
288
+ seterr(&ctx);
289
+ raise_error();
290
+ }
291
+
292
+ NDT(self_p) = ndt_from_metadata_and_dtype(&m, cp, &ctx);
293
+ ndt_meta_clear(&m);
294
+
295
+ if (NDT(self_p) == NULL) {
296
+ seterr(&ctx);
297
+ raise_error();
298
+ }
385
299
 
386
300
  return self;
387
301
  }
@@ -407,7 +321,7 @@ NDTypes_initialize(int argc, VALUE *argv, VALUE self)
407
321
  return NDTypes_from_object(self, type);
408
322
  }
409
323
 
410
- return NDTypes_from_offsets_and_dtype(offsets, type);
324
+ return NDTypes_from_offsets_and_dtype(self, offsets, type);
411
325
  }
412
326
 
413
327
  /* String representation of the type. */
@@ -436,15 +350,15 @@ NDTypes_to_s(VALUE self)
436
350
  static VALUE
437
351
  NDTypes_serialize(VALUE self)
438
352
  {
439
- NdtObject *ndt;
353
+ NdtObject *self_p;
440
354
  char *bytes;
441
355
  int64_t size;
442
356
  VALUE str;
443
357
 
444
358
  NDT_STATIC_CONTEXT(ctx);
445
- GET_NDT(self, ndt);
359
+ GET_NDT(self, self_p);
446
360
 
447
- size = ndt_serialize(&bytes, NDT(ndt), &ctx);
361
+ size = ndt_serialize(&bytes, NDT(self_p), &ctx);
448
362
  if (size < 0) {
449
363
  seterr(&ctx);
450
364
  raise_error();
@@ -467,7 +381,7 @@ NDTypes_ndim(VALUE self)
467
381
  const ndt_t *t = NDT(ndt_p);
468
382
 
469
383
  if (ndt_is_abstract(t)) {
470
- rb_raise(rb_eTypeError, "abstract type has no ndim.");
384
+ rb_raise(rb_eNoMethodError, "abstract type has no ndim.");
471
385
  }
472
386
 
473
387
  return LL2NUM(t->ndim);
@@ -502,7 +416,7 @@ NDTypes_itemsize(VALUE self)
502
416
  const ndt_t *t = NDT(ndt_p);
503
417
 
504
418
  if (ndt_is_abstract(t)) {
505
- rb_raise(rb_eTypeError, "abstract type has no datasize.");
419
+ rb_raise(rb_eNoMethodError, "abstract type has no datasize.");
506
420
  }
507
421
 
508
422
  switch (t->tag) {
@@ -531,7 +445,7 @@ NDTypes_align(VALUE self)
531
445
  const ndt_t *t = NDT(ndt_p);
532
446
 
533
447
  if (ndt_is_abstract(t)) {
534
- rb_raise(rb_eTypeError, "abstract type has no datasize.");
448
+ rb_raise(rb_eNoMethodError, "abstract type has no datasize.");
535
449
  }
536
450
 
537
451
  return LL2NUM(t->align);
@@ -631,6 +545,7 @@ NDTypes_match(VALUE self, VALUE other)
631
545
  return INT2BOOL(res);
632
546
  }
633
547
 
548
+ /* Implemented NDT#ast */
634
549
  static VALUE
635
550
  NDTypes_ast(VALUE self)
636
551
  {
@@ -675,47 +590,241 @@ NDTypes_pretty(VALUE self)
675
590
  return result;
676
591
  }
677
592
 
678
- /****************************************************************************/
679
- /* Class methods */
680
- /****************************************************************************/
593
+ /* NDT#shape */
594
+ static VALUE
595
+ NDTypes_shape(VALUE self)
596
+ {
597
+ NDT_STATIC_CONTEXT(ctx);
598
+ ndt_ndarray_t x;
599
+ NdtObject *self_p;
600
+
601
+ GET_NDT(self, self_p);
602
+
603
+ if (ndt_as_ndarray(&x, NDT(self_p), &ctx) < 0) {
604
+ seterr(&ctx);
605
+ raise_error();
606
+ }
607
+
608
+ return array_from_int64(x.shape, x.ndim);
609
+ }
681
610
 
682
- /* Deserialize a byte string into an NDTypes object. */
683
611
  static VALUE
684
- NDTypes_s_deserialize(VALUE klass, VALUE str)
612
+ NDTypes_strides(VALUE self)
685
613
  {
686
- NdtObject *ndt_p;
687
- ResourceBufferObject *rbuf_p;
688
- VALUE ndt, rbuf;
689
- char *cp;
690
- int64_t len;
691
614
  NDT_STATIC_CONTEXT(ctx);
615
+ ndt_ndarray_t x;
616
+ NdtObject *self_p;
692
617
 
693
- Check_Type(str, T_STRING);
618
+ GET_NDT(self, self_p);
694
619
 
695
- cp = StringValuePtr(str);
696
- if (cp == NULL) {
697
- // raise
620
+ if (ndt_as_ndarray(&x, NDT(self_p), &ctx) < 0) {
621
+ seterr(&ctx);
622
+ raise_error();
623
+ }
624
+
625
+ return array_from_int64(x.strides, x.ndim);
626
+ }
627
+
628
+ static int
629
+ parse_apply_args(const ndt_t* types[NDT_MAX_ARGS], int *num_intypes, int *num_outtypes,
630
+ int *num_args, VALUE input_types, VALUE out_types) {
631
+ size_t nin, nout;
632
+ if (RARRAY_LEN(input_types) == 0) {
633
+ rb_raise(rb_eArgError, "must specify more than 0 input types.");
634
+ }
635
+
636
+ nin = RARRAY_LEN(input_types);
637
+ if (nin > NDT_MAX_ARGS) {
638
+ rb_raise(rb_eArgError, "maximum number of arguments cannot exceed %d, got %d.",
639
+ NDT_MAX_ARGS, nin);
640
+ }
641
+
642
+ for (int i = 0; i < nin; ++i) {
643
+ VALUE v = rb_ary_entry(input_types, i);
644
+ NdtObject *v_p;
645
+
646
+ if (!NDT_CHECK_TYPE(v)) {
647
+ rb_raise(rb_eArgError, "every argument must be of type NDT.");
648
+ }
649
+
650
+ GET_NDT(v, v_p);
651
+ types[i] = NDT(v_p);
698
652
  }
699
- len = RSTRING_LEN(str);
700
653
 
701
- rbuf_p = ALLOC(ResourceBufferObject);
702
- rbuf_p->m = ndt_meta_new(&ctx);
703
- if (rbuf_p->m == NULL) {
704
- /* TODO: cannot alloc meta data */
654
+ if (out_types == Qnil) {
655
+ nout = 0;
656
+ }
657
+ else {
658
+ if (NDT_CHECK_TYPE(out_types)) {
659
+ NdtObject *out_p;
660
+ nout = 1;
661
+ if (nin + nout > NDT_MAX_ARGS) {
662
+ rb_raise(rb_eTypeError, "max number of args is %d, got %d.", NDT_MAX_ARGS, nin+nout);
663
+ }
664
+ GET_NDT(out_types, out_p);
665
+ types[nin] = NDT(out_p);
666
+ }
667
+ else if (TYPE(out_types) == T_ARRAY) {
668
+ nout = RARRAY_LEN(out_types);
669
+ if (nout > NDT_MAX_ARGS || nin+nout > NDT_MAX_ARGS) {
670
+ rb_raise(rb_eTypeError, "max number of args is %d, got %d.", NDT_MAX_ARGS, nin+nout);
671
+ }
672
+
673
+ for (int i = 0; i < nout; ++i) {
674
+ NdtObject *v_p;
675
+ VALUE v = rb_ary_entry(out_types, i);
676
+ if (!NDT_CHECK_TYPE(v)) {
677
+ rb_raise(rb_eTypeError, "expected NDT arguments for all out types.");
678
+ }
679
+ GET_NDT(v, v_p);
680
+ types[nin+i] = NDT(v_p);
681
+ }
682
+ }
683
+ else {
684
+ rb_raise(rb_eTypeError, "'out' argument must be ndt or a tuple of ndt.");
685
+ }
705
686
  }
706
687
 
707
- ndt_p = ALLOC(NdtObject);
708
- NDT(ndt_p) = ndt_deserialize(RBUF_NDT_M(rbuf_p), cp, len, &ctx);
709
- if (NDT(ndt_p) == NULL) {
710
- /* TODO: raise error for cannot deserialize */
688
+ for (int i = 0; i < nin+nout; ++i) {
689
+ ndt_incref(types[i]);
711
690
  }
712
691
 
713
- rbuf = WRAP_RBUF(cNDTypes_RBuf, rbuf_p);
714
- RBUF(ndt_p) = rbuf;
715
- rb_ndtypes_gc_guard_register(ndt_p, rbuf);
716
- ndt = WRAP_NDT(cNDTypes, ndt_p);
692
+ *num_intypes = (int)nin;
693
+ *num_outtypes = (int)nout;
694
+ *num_args = (int)nin + (int)nout;
695
+
696
+ return 0;
697
+
698
+ }
699
+
700
+ static VALUE
701
+ NDTypes_apply(VALUE self, VALUE input_types, VALUE out_types)
702
+ {
703
+ NDT_STATIC_CONTEXT(ctx);
704
+ const ndt_t *types[NDT_MAX_ARGS] = {NULL};
705
+ const int64_t li[NDT_MAX_ARGS] = {0};
706
+ ndt_apply_spec_t spec = ndt_apply_spec_empty;
707
+ VALUE res, flags, outer_dims, nin, nout, nargs, lst;
708
+ int ret;
709
+ int num_intypes, num_outtypes, num_args;
710
+ NdtObject *self_p;
711
+
712
+ Check_Type(input_types, T_ARRAY);
713
+
714
+ parse_apply_args(types, &num_intypes, &num_outtypes, &num_args, input_types, out_types);
715
+ GET_NDT(self, self_p);
716
+ const ndt_t * sig = NDT(self_p);
717
+ ret = ndt_typecheck(&spec, sig, types, li, num_intypes, num_outtypes, false,
718
+ NULL, NULL, &ctx);
719
+ ndt_type_array_clear(types, num_args);
717
720
 
718
- return ndt;
721
+ if (ret < 0) {
722
+ seterr(&ctx);
723
+ raise_error();
724
+ }
725
+
726
+ flags = rb_str_new2(ndt_apply_flags_as_string(&spec));
727
+ lst = rb_ary_new2(spec.nargs);
728
+
729
+ for (int i = 0; i < spec.nargs; ++i) {
730
+ VALUE x = NdtObject_alloc();
731
+ NdtObject *x_p;
732
+ GET_NDT(x, x_p);
733
+
734
+ NDT(x_p) = spec.types[i];
735
+ rb_ary_store(lst, i, x);
736
+ }
737
+
738
+ outer_dims = LL2NUM(spec.outer_dims);
739
+ nin = LL2NUM(spec.nin);
740
+ nout = LL2NUM(spec.nout);
741
+ nargs = LL2NUM(spec.nargs);
742
+
743
+ return rb_funcall(rb_const_get(cNDTypes, rb_intern("ApplySpec")), rb_intern("new"),
744
+ 6, flags, outer_dims, nin, nout, nargs, lst);
745
+ }
746
+
747
+ static const ndt_t *
748
+ from_string(VALUE v)
749
+ {
750
+ NDT_STATIC_CONTEXT(ctx);
751
+ const char *cp;
752
+ const ndt_t *t;
753
+
754
+ Check_Type(v, T_STRING);
755
+
756
+ cp = RSTRING_PTR(v);
757
+ t = ndt_from_string(cp, &ctx);
758
+ if (t == NULL) {
759
+ seterr(&ctx);
760
+ raise_error();
761
+ }
762
+
763
+ return t;
764
+ }
765
+
766
+ /* Implement NDT#_at */
767
+ static VALUE
768
+ NDTypes_at(VALUE self, VALUE obj_n, VALUE dtype)
769
+ {
770
+ NDT_STATIC_CONTEXT(ctx);
771
+ int n = FIX2INT(obj_n);
772
+ VALUE res;
773
+ const ndt_t *t, *dt;
774
+ NdtObject *dtype_p, *self_p;
775
+
776
+ if (dtype == Qnil) {
777
+ dt = NULL;
778
+ }
779
+ else if (NDT_CHECK_TYPE(dtype)) {
780
+ GET_NDT(dtype, dtype_p);
781
+ dt = NDT(dtype_p);
782
+ ndt_incref(dt);
783
+ }
784
+ else if (TYPE(dtype) == T_STRING) {
785
+ dt = from_string(dtype);
786
+ }
787
+ else {
788
+ rb_raise(rb_eTypeError, "dtype argument must be 'ndt' or 'str'");
789
+ }
790
+
791
+ GET_NDT(self, self_p);
792
+ t = ndt_copy_contiguous_at(NDT(self_p), n, dt, &ctx);
793
+
794
+ if (dt != NULL) {
795
+ ndt_decref(dt);
796
+ }
797
+ if (t == NULL) {
798
+ seterr(&ctx);
799
+ raise_error();
800
+ }
801
+
802
+ res = rb_ndtypes_from_type(t);
803
+ ndt_decref(t);
804
+
805
+ return res;
806
+ }
807
+
808
+ /****************************************************************************/
809
+ /* Class methods */
810
+ /****************************************************************************/
811
+
812
+ /* Deserialize a byte string into an NDTypes object. */
813
+ static VALUE
814
+ NDTypes_s_deserialize(VALUE klass, VALUE str)
815
+ {
816
+ NDT_STATIC_CONTEXT(ctx);
817
+ VALUE self;
818
+ NdtObject *self_p;
819
+
820
+ Check_Type(str, T_STRING);
821
+
822
+ self = NdtObject_alloc();
823
+ GET_NDT(self, self_p);
824
+
825
+ NDT(self_p) = ndt_deserialize(RSTRING_PTR(str), RSTRING_LEN(str), &ctx);
826
+
827
+ return self;
719
828
  }
720
829
 
721
830
  /* Create a typedef */
@@ -730,22 +839,17 @@ NDTypes_s_typedef(VALUE klass, VALUE new_type, VALUE old_type)
730
839
  Check_Type(old_type, T_STRING);
731
840
 
732
841
  cname = StringValueCStr(new_type);
733
- if (cname == NULL) {
734
-
735
- }
736
-
737
842
  ctype = StringValueCStr(old_type);
738
- if (ctype == NULL) {
739
-
740
- }
741
843
 
742
844
  t = ndt_from_string(ctype, &ctx);
743
845
  if (t == NULL) {
744
-
846
+ seterr(&ctx);
847
+ raise_error();
745
848
  }
746
849
 
747
850
  if (ndt_typedef(cname, t, NULL, &ctx) < 0) {
748
-
851
+ seterr(&ctx);
852
+ raise_error();
749
853
  }
750
854
 
751
855
  return Qnil;
@@ -757,7 +861,7 @@ NDTypes_s_instantiate(VALUE klass, VALUE name, VALUE type)
757
861
  {
758
862
  const char *cname;
759
863
  char *cp;
760
- ndt_t *t, *tp;
864
+ const ndt_t *t;//, *tp;
761
865
  NdtObject *type_p;
762
866
  NDT_STATIC_CONTEXT(ctx);
763
867
 
@@ -777,29 +881,53 @@ NDTypes_s_instantiate(VALUE klass, VALUE name, VALUE type)
777
881
 
778
882
  GET_NDT(type, type_p);
779
883
 
780
- tp = ndt_copy(NDT(type_p), &ctx);
781
- if (tp == NULL) {
782
- ndt_free(cp);
884
+ t = ndt_nominal(cp, NDT(type_p), false, &ctx);
885
+ if (t == NULL) {
783
886
  seterr(&ctx);
784
887
  raise_error();
785
888
  }
786
889
 
787
- t = ndt_nominal(cp, tp, &ctx);
788
- if (t == NULL) {
890
+ VALUE ret = rb_ndtypes_from_type(t);
891
+ ndt_decref(t);
892
+
893
+ return ret;
894
+ }
895
+
896
+ static VALUE
897
+ NDTypes_s_from_format(VALUE klass, VALUE format)
898
+ {
899
+ NDT_STATIC_CONTEXT(ctx);
900
+ VALUE self;
901
+ NdtObject *self_p;
902
+ const char *cp;
903
+
904
+ Check_Type(format, T_STRING);
905
+
906
+ cp = StringValueCStr(format);
907
+ self = NdtObject_alloc();
908
+
909
+ GET_NDT(self, self_p);
910
+
911
+ NDT(self_p) = ndt_from_bpformat(cp, &ctx);
912
+ if (NDT(self_p) == NULL) {
789
913
  seterr(&ctx);
790
914
  raise_error();
791
915
  }
792
916
 
793
- return rb_ndtypes_move_subtree(type, t);
917
+ return self;
794
918
  }
795
919
 
920
+
796
921
  /****************************************************************************/
797
922
  /* Public C API */
798
923
  /****************************************************************************/
799
924
 
800
925
  /* Create NDT object from ndt_t type struct. */
926
+ /* Increments the refcnt of the NDT so can be thought of as making
927
+ * a copy of the object.
928
+ */
801
929
  VALUE
802
- rb_ndtypes_from_type(ndt_t *type)
930
+ rb_ndtypes_from_type(const ndt_t *type)
803
931
  {
804
932
  VALUE self;
805
933
  NdtObject *self_p;
@@ -807,6 +935,7 @@ rb_ndtypes_from_type(ndt_t *type)
807
935
  self = NdtObject_alloc();
808
936
  GET_NDT(self, self_p);
809
937
 
938
+ ndt_incref(type);
810
939
  NDT(self_p) = type;
811
940
 
812
941
  return self;
@@ -889,11 +1018,6 @@ rb_ndtypes_move_subtree(VALUE src, ndt_t *t)
889
1018
  rb_raise(rb_eNoMemError, "could not allocate memory for ndt_copy().");
890
1019
  }
891
1020
 
892
- GET_NDT(src, src_p);
893
- RBUF(dest_p) = RBUF(src_p);
894
-
895
- rb_ndtypes_gc_guard_register(dest_p, RBUF(dest_p));
896
-
897
1021
  return dest;
898
1022
  }
899
1023
 
@@ -924,16 +1048,12 @@ rb_ndtypes_from_object(VALUE type)
924
1048
 
925
1049
  copy = NdtObject_alloc();
926
1050
  GET_NDT(copy, copy_p);
1051
+ NDT(copy_p) = ndt_from_string(cp, &ctx);
927
1052
 
928
- RBUF(copy_p) = rbuf_allocate();
929
- NDT(copy_p) = ndt_from_string_fill_meta(
930
- rbuf_ndt_meta(copy),
931
- cp, &ctx);
932
1053
  if (NDT(copy_p) == NULL) {
933
1054
  seterr(&ctx);
934
1055
  raise_error();
935
1056
  }
936
- rb_ndtypes_gc_guard_register(copy_p, RBUF(copy_p));
937
1057
 
938
1058
  return copy;
939
1059
  }
@@ -974,6 +1094,10 @@ void Init_ruby_ndtypes(void)
974
1094
  rb_define_method(cNDTypes, "match", NDTypes_match, 1);
975
1095
  rb_define_method(cNDTypes, "ast", NDTypes_ast, 0);
976
1096
  rb_define_method(cNDTypes, "pretty", NDTypes_pretty, 0);
1097
+ rb_define_method(cNDTypes, "shape", NDTypes_shape, 0);
1098
+ rb_define_method(cNDTypes, "strides", NDTypes_strides, 0);
1099
+ rb_define_method(cNDTypes, "_apply", NDTypes_apply, 2);
1100
+ rb_define_method(cNDTypes, "_at", NDTypes_at, 2);
977
1101
 
978
1102
  /* Boolean functions */
979
1103
  rb_define_method(cNDTypes, "concrete?", NDTypes_ndt_is_concrete, 0);
@@ -986,6 +1110,7 @@ void Init_ruby_ndtypes(void)
986
1110
  rb_define_method(cNDTypes, "complex?", NDTypes_ndt_is_complex, 0);
987
1111
  rb_define_method(cNDTypes, "c_contiguous?", NDTypes_ndt_is_c_contiguous, 0);
988
1112
  rb_define_method(cNDTypes, "f_contiguous?", NDTypes_ndt_is_f_contiguous, 0);
1113
+ rb_define_method(cNDTypes, "var_contiguous?", NDTypes_ndt_is_var_contiguous, 0);
989
1114
  rb_define_method(cNDTypes, "==", NDTypes_eqeq, 1);
990
1115
  rb_define_method(cNDTypes, "!=", NDTypes_neq, 1);
991
1116
 
@@ -993,11 +1118,9 @@ void Init_ruby_ndtypes(void)
993
1118
  rb_define_singleton_method(cNDTypes, "deserialize", NDTypes_s_deserialize, 1);
994
1119
  rb_define_singleton_method(cNDTypes, "typedef", NDTypes_s_typedef, 2);
995
1120
  rb_define_singleton_method(cNDTypes, "instantiate", NDTypes_s_instantiate, 2);
1121
+ rb_define_singleton_method(cNDTypes, "from_format", NDTypes_s_from_format, 1);
996
1122
 
997
1123
  /* Constants */
998
1124
  rb_define_const(cNDTypes, "MAX_DIM", INT2NUM(NDT_MAX_DIM));
999
-
1000
- /* GC guard init */
1001
- rb_ndtypes_init_gc_guard();
1002
1125
  }
1003
1126