File Coverage

lib/Basic/Types/XS.xs
Criterion Covered Total %
statement 544 705 77.1
branch 301 522 57.6
condition n/a
subroutine n/a
pod n/a
total 845 1227 68.8


line stmt bran cond sub pod time code
1             #define PERL_NO_GET_CONTEXT // we'll define thread context if necessary (faster)
2             #include "EXTERN.h" // globals/constant import locations
3             #include "perl.h" // Perl symbols, structures and constants definition
4             #include "XSUB.h" // xsubpp functions and macros
5              
6 196           static SV * _new (SV * type, CV * cv) {
7             dTHX;
8 196           HV * hash = newHV();
9 196           hv_store(hash, "name", 4, type, 0);
10 196           hv_store(hash, "constraint", 10, (SV*)cv, 0);
11 196           return sv_bless(newRV_noinc((SV*)hash), gv_stashsv(newSVpv("Basic::Types::XS", 16), 0));
12             }
13              
14 8           int _sv_contains_numbers (SV * param, int dec) {
15             dTHX;
16             STRLEN retlen;
17 8           char * str = SvPV(param, retlen);
18 8           int i = 0;
19 34 100         for (i = 0; i < retlen; i++) {
20 31 100         if (!isdigit(str[i])) {
21 7 100         if ( !dec && str[i] == '.' ) {
    100          
22 2           dec = 1;
23             } else {
24 5           return 0;
25             }
26             }
27             }
28 3           return 1;
29             }
30              
31 17           int _sv_isa_bool (SV * param) {
32             dTHX;
33 17           int type = SvTYPE(param);
34 17 100         if (SvROK(param)) {
35 7           param = SvRV(param);
36 7           type = SvTYPE(param);
37             }
38              
39 17 100         if (type >= SVt_PVAV) {
40 3           return 0;
41             }
42              
43 14 100         if (!SvOK(param)) {
44 2           return 1;
45             }
46              
47 12 100         if (type == SVt_IV) {
48 5           int i = SvIV(param);
49 5 100         if (i == 0 || i == 1) {
    100          
50 4           return 1;
51             }
52 7 100         } else if (type == SVt_PV) {
53             STRLEN retlen;
54 6           char * i = SvPV(param, retlen);
55 6 100         if (!retlen || i[0] == 0 || i[0] == 1) {
    50          
    50          
56 2           return 1;
57             }
58             }
59              
60 6           return 0;
61             }
62              
63 20           char *get_caller(void) {
64             dTHX;
65 20 50         char *callr = HvNAME((HV*)CopSTASH(PL_curcop));
    50          
    50          
    0          
    50          
    50          
66 20           return callr;
67             }
68              
69 125           static char * get_error_message (SV * self, const char * type) {
70             dTHX;
71 125           SV ** sv = hv_fetch((HV*)SvRV(self), "message", 7, 0);
72 125 100         if (sv) {
73             STRLEN retlen;
74 10           char * msg = SvPV(*sv, retlen);
75 10 50         if (retlen > 0) {
76 10           return msg;
77             }
78             }
79 115           size_t len = 40 + strlen(type);
80 115           char *buffer = (char *)malloc(len);
81 115           snprintf(buffer, len, "value did not pass type constraint \"%s\"", type);
82 115           return buffer;
83             }
84              
85 220           static SV * set_default (SV * self, SV * param) {
86             dTHX;
87 220 100         if (!SvOK(param) && hv_exists((HV*)SvRV(self), "default", 7)) {
    100          
88 5           SV ** def = hv_fetch((HV*)SvRV(self), "default", 7, 0);
89 5 50         if (SvOK(*def)) {
90 5           dSP;
91 5 50         PUSHMARK(SP);
92 5           PUTBACK;
93 5           call_sv(*def, G_SCALAR);
94 5           SPAGAIN;
95 5           param = POPs;
96 5           PUTBACK;
97             }
98             }
99 220           return param;
100             }
101              
102 220           static SV * coerce (SV * self, SV * param) {
103             dTHX;
104 220 100         if (hv_exists((HV*)SvRV(self), "coerce", 6)) {
105 16           SV ** coe = hv_fetch((HV*)SvRV(self), "coerce", 6, 0);
106 16 50         if (SvOK(*coe)) {
107 16           dSP;
108 16 50         PUSHMARK(SP);
109 16 50         XPUSHs(newSVsv(param));
110 16           PUTBACK;
111 16           call_sv(*coe, G_SCALAR);
112 16           SPAGAIN;
113 16           param = POPs;
114 16           PUTBACK;
115             }
116             }
117 220           return param;
118             }
119              
120 7           int regex_match(SV *input_sv, SV **pattern_sv) {
121             dTHX;
122             STRLEN retlen;
123 7           char * input = SvPV(input_sv, retlen);
124             REGEXP *rx;
125 7 50         if (!pattern_sv || !SvROK(*pattern_sv)) {
    50          
126 0 0         char *pattern = (pattern_sv && SvOK(*pattern_sv)) ? SvPV_nolen(*pattern_sv) : "\\s+";
    0          
127 0           STRLEN patlen = strlen(pattern);
128 0           SV *pat_sv = newSVpvn(pattern, patlen);
129 0           rx = pregcomp(pat_sv, 0);
130 0           SvREFCNT_dec(pat_sv);
131 7 50         } else if (SvTYPE(SvRV(*pattern_sv)) == SVt_REGEXP) {
132 7           SvREFCNT_inc(*pattern_sv);
133 7           rx = (REGEXP *)SvRV(*pattern_sv);
134             }
135 7 50         if (!rx) {
136 0           return 0;
137             }
138 7           STRLEN pos = 0;
139 7           STRLEN last = 0;
140 7           I32 nmatch = pregexec(rx, input + pos, input + retlen, input, 0, input_sv, 0);
141 7 100         if (nmatch > 0) {
142 5           return 1;
143             } else {
144 2           return 0;
145             }
146             }
147              
148             MODULE = Basic::Types::XS::Definition PACKAGE = Basic::Types::XS::Definition
149             PROTOTYPES: DISABLE
150              
151             SV *
152             _Any(...)
153             CODE:
154 14           SV * self = CvXSUBANY(cv).any_ptr;
155 14 50         if (!self || !SvOK(self)) {
    50          
156 0           croak("Any type constraint not initialized");
157             }
158              
159 14 100         SV * param = items >= 1 ? newSVsv(ST(0)) : &PL_sv_undef;
160 14           param = set_default(self, param);
161 14           param = coerce(self, param);
162              
163 14 100         if (items < 1 ) {
164 1           char * custom_error = get_error_message(self, "Any");
165 1           croak("%s", custom_error);
166             }
167 13           SvREFCNT_inc(param);
168 13           RETVAL = param;
169             OUTPUT:
170             RETVAL
171              
172             SV *
173             Any(...)
174             CODE:
175 14           CV *type = newXS(NULL, XS_Basic__Types__XS__Definition__Any, __FILE__);
176 14           RETVAL = _new(newSVpv("Any", 3), type);
177 14           SvREFCNT_inc(type);
178 14           CvXSUBANY(type).any_ptr = (void *)RETVAL;
179 14           SvREFCNT_inc(RETVAL);
180 14           HV * self = (HV*)SvRV(RETVAL);
181 14           hv_store(self, "constraint", 10, (SV*)type, 0);
182 14 50         if (items % 2 != 0) {
183 0           croak("Any type constraint requires an even number of arguments");
184             }
185 14           int i = 0;
186 14 50         for (i = 0; i < items; i += 2) {
187 0           SV * key = ST(i);
188 0           SV * value = ST(i + 1);
189 0 0         if (!SvOK(key) || SvTYPE(key) != SVt_PV) {
    0          
190 0           croak("key must be a string");
191             }
192 0 0         if (!SvOK(value)) {
193 0           croak("value must be defined");
194             }
195             STRLEN keylen;
196 0           char * keystr = SvPV(key, keylen);
197 0           hv_store(self, keystr, keylen, newSVsv(value), 0);
198             }
199             OUTPUT:
200             RETVAL
201              
202             SV *
203             _Defined(...)
204             CODE:
205 13           SV * self = CvXSUBANY(cv).any_ptr;
206 13 50         if (!self || !SvOK(self)) {
    50          
207 0           croak("Defined type constraint not initialized");
208             }
209              
210 13 50         SV * param = items >= 1 ? newSVsv(ST(0)) : &PL_sv_undef;
211 13           param = set_default(self, param);
212 13           param = coerce(self, param);
213              
214 13 100         if (!SvOK(param)) {
215 1           char * custom_error = get_error_message(self, "Defined");
216 1           croak("%s", custom_error);
217             }
218 12           SvREFCNT_inc(param);
219 12           RETVAL = param;
220             OUTPUT:
221             RETVAL
222              
223             SV *
224             Defined(...)
225             CODE:
226 13           CV *type = newXS(NULL, XS_Basic__Types__XS__Definition__Defined, __FILE__);
227 13           RETVAL = _new(newSVpv("Defined", 7), type);
228 13           SvREFCNT_inc(type);
229 13           CvXSUBANY(type).any_ptr = (void *)RETVAL;
230 13           SvREFCNT_inc(RETVAL);
231 13           HV * self = (HV*)SvRV(RETVAL);
232 13           hv_store(self, "constraint", 10, (SV*)type, 0);
233 13 50         if (items % 2 != 0) {
234 0           croak("Defined type constraint requires an even number of arguments");
235             }
236 13           int i = 0;
237 13 50         for (i = 0; i < items; i += 2) {
238 0           SV * key = ST(i);
239 0           SV * value = ST(i + 1);
240 0 0         if (!SvOK(key) || SvTYPE(key) != SVt_PV) {
    0          
241 0           croak("key must be a string");
242             }
243 0 0         if (!SvOK(value)) {
244 0           croak("value must be defined");
245             }
246             STRLEN keylen;
247 0           char * keystr = SvPV(key, keylen);
248 0           hv_store(self, keystr, keylen, newSVsv(value), 0);
249             }
250             OUTPUT:
251             RETVAL
252              
253             SV *
254             _Ref(...)
255             CODE:
256 13           SV * self = CvXSUBANY(cv).any_ptr;
257 13 50         if (!self || !SvOK(self)) {
    50          
258 0           croak("Ref type constraint not initialized");
259             }
260              
261 13 50         SV * param = items >= 1 ? newSVsv(ST(0)) : &PL_sv_undef;
262 13           param = set_default(self, param);
263 13           param = coerce(self, param);
264              
265 13 100         if (!SvROK(param) || !SvOK(param)) {
    50          
266 7           char * custom_error = get_error_message(self, "Ref");
267 7           croak("%s", custom_error);
268             }
269 6           SvREFCNT_inc(param);
270 6           RETVAL = param;
271             OUTPUT:
272             RETVAL
273              
274             SV *
275             Ref(...)
276             CODE:
277 13           CV *type = newXS(NULL, XS_Basic__Types__XS__Definition__Ref, __FILE__);
278 13           RETVAL = _new(newSVpv("Ref", 3), type);
279 13           SvREFCNT_inc(type);
280 13           CvXSUBANY(type).any_ptr = (void *)RETVAL;
281 13           SvREFCNT_inc(RETVAL);
282 13           HV * self = (HV*)SvRV(RETVAL);
283 13           hv_store(self, "constraint", 10, (SV*)type, 0);
284 13 50         if (items % 2 != 0) {
285 0           croak("Ref type constraint requires an even number of arguments");
286             }
287 13           int i = 0;
288 13 50         for (i = 0; i < items; i += 2) {
289 0           SV * key = ST(i);
290 0           SV * value = ST(i + 1);
291 0 0         if (!SvOK(key) || SvTYPE(key) != SVt_PV) {
    0          
292 0           croak("key must be a string");
293             }
294 0 0         if (!SvOK(value)) {
295 0           croak("value must be defined");
296             }
297             STRLEN keylen;
298 0           char * keystr = SvPV(key, keylen);
299 0           hv_store(self, keystr, keylen, newSVsv(value), 0);
300             }
301             OUTPUT:
302             RETVAL
303              
304             SV *
305             _ScalarRef(...)
306             CODE:
307 13           SV * self = CvXSUBANY(cv).any_ptr;
308 13 50         if (!self || !SvOK(self)) {
    50          
309 0           croak("ScalarRef type constraint not initialized");
310             }
311              
312 13 50         SV * param = items >= 1 ? newSVsv(ST(0)) : &PL_sv_undef;
313 13           param = set_default(self, param);
314 13           param = coerce(self, param);
315              
316 13 100         if (!SvROK(param) || !SvOK(param) || (SvTYPE(SvRV(param)) >= SVt_PVAV)) {
    50          
    100          
317 11           char * custom_error = get_error_message(self, "ScalarRef");
318 11           croak("%s", custom_error);
319             }
320 2           SvREFCNT_inc(param);
321 2           RETVAL = param;
322             OUTPUT:
323             RETVAL
324              
325             SV *
326             ScalarRef(...)
327             CODE:
328 13           CV *type = newXS(NULL, XS_Basic__Types__XS__Definition__ScalarRef, __FILE__);
329 13           RETVAL = _new(newSVpv("ScalarRef", 9), type);
330 13           SvREFCNT_inc(type);
331 13           CvXSUBANY(type).any_ptr = (void *)RETVAL;
332 13           SvREFCNT_inc(RETVAL);
333 13           HV * self = (HV*)SvRV(RETVAL);
334 13           hv_store(self, "constraint", 10, (SV*)type, 0);
335 13 50         if (items % 2 != 0) {
336 0           croak("ScalarRef type constraint requires an even number of arguments");
337             }
338 13           int i = 0;
339 13 50         for (i = 0; i < items; i += 2) {
340 0           SV * key = ST(i);
341 0           SV * value = ST(i + 1);
342 0 0         if (!SvOK(key) || SvTYPE(key) != SVt_PV) {
    0          
343 0           croak("key must be a string");
344             }
345 0 0         if (!SvOK(value)) {
346 0           croak("value must be defined");
347             }
348             STRLEN keylen;
349 0           char * keystr = SvPV(key, keylen);
350 0           hv_store(self, keystr, keylen, newSVsv(value), 0);
351             }
352             OUTPUT:
353             RETVAL
354              
355             SV *
356             _ArrayRef(...)
357             CODE:
358 13           SV * self = CvXSUBANY(cv).any_ptr;
359 13 50         if (!self || !SvOK(self)) {
    50          
360 0           croak("ArrayRef type constraint not initialized");
361             }
362              
363 13 50         SV * param = items >= 1 ? newSVsv(ST(0)) : &PL_sv_undef;
364 13           param = set_default(self, param);
365 13           param = coerce(self, param);
366              
367 13 100         if (!SvROK(param) || !SvOK(param) || (SvTYPE(SvRV(param)) != SVt_PVAV)) {
    50          
    100          
368 9           char * custom_error = get_error_message(self, "ArrayRef");
369 9           croak("%s", custom_error);
370             }
371 4           SvREFCNT_inc(param);
372 4           RETVAL = param;
373             OUTPUT:
374             RETVAL
375              
376             SV *
377             ArrayRef(...)
378             CODE:
379 12           CV *type = newXS(NULL, XS_Basic__Types__XS__Definition__ArrayRef, __FILE__);
380 12           RETVAL = _new(newSVpv("ArrayRef", 8), type);
381 12           SvREFCNT_inc(type);
382 12           CvXSUBANY(type).any_ptr = (void *)RETVAL;
383 12           SvREFCNT_inc(RETVAL);
384 12           HV * self = (HV*)SvRV(RETVAL);
385 12           hv_store(self, "constraint", 10, (SV*)type, 0);
386 12 50         if (items % 2 != 0) {
387 0           croak("ArrayRef type constraint requires an even number of arguments");
388             }
389 12           int i = 0;
390 12 50         for (i = 0; i < items; i += 2) {
391 0           SV * key = ST(i);
392 0           SV * value = ST(i + 1);
393 0 0         if (!SvOK(key) || SvTYPE(key) != SVt_PV) {
    0          
394 0           croak("key must be a string");
395             }
396 0 0         if (!SvOK(value)) {
397 0           croak("value must be defined");
398             }
399             STRLEN keylen;
400 0           char * keystr = SvPV(key, keylen);
401 0           hv_store(self, keystr, keylen, newSVsv(value), 0);
402             }
403             OUTPUT:
404             RETVAL
405              
406             SV *
407             _HashRef(...)
408             CODE:
409 17           SV * self = CvXSUBANY(cv).any_ptr;
410 17 50         if (!self || !SvOK(self)) {
    50          
411 0           croak("HashRef type constraint not initialized");
412             }
413              
414 17 50         SV * param = items >= 1 ? newSVsv(ST(0)) : &PL_sv_undef;
415 17           param = set_default(self, param);
416 17           param = coerce(self, param);
417              
418 17 100         if (!SvROK(param) || !SvOK(param) || (SvTYPE(SvRV(param)) != SVt_PVHV)) {
    50          
    100          
419 10           char * custom_error = get_error_message(self, "HashRef");
420 10           croak("%s", custom_error);
421             }
422 7           SvREFCNT_inc(param);
423 7           RETVAL = param;
424             OUTPUT:
425             RETVAL
426              
427             SV *
428             HashRef(...)
429             CODE:
430 13           CV *type = newXS(NULL, XS_Basic__Types__XS__Definition__HashRef, __FILE__);
431 13           RETVAL = _new(newSVpv("HashRef", 7), type);
432 13           SvREFCNT_inc(type);
433 13           CvXSUBANY(type).any_ptr = (void *)RETVAL;
434 13           SvREFCNT_inc(RETVAL);
435 13           HV * self = (HV*)SvRV(RETVAL);
436 13           hv_store(self, "constraint", 10, (SV*)type, 0);
437 13 50         if (items % 2 != 0) {
438 0           croak("HashRef type constraint requires an even number of arguments");
439             }
440 13           int i = 0;
441 16 100         for (i = 0; i < items; i += 2) {
442 3           SV * key = ST(i);
443 3           SV * value = ST(i + 1);
444 3 50         if (!SvOK(key) || SvTYPE(key) != SVt_PV) {
    50          
445 0           croak("key must be a string");
446             }
447 3 50         if (!SvOK(value)) {
448 0           croak("value must be defined");
449             }
450             STRLEN keylen;
451 3           char * keystr = SvPV(key, keylen);
452 3           hv_store(self, keystr, keylen, newSVsv(value), 0);
453             }
454             OUTPUT:
455             RETVAL
456              
457             SV *
458             _CodeRef(...)
459             CODE:
460 11           SV * self = CvXSUBANY(cv).any_ptr;
461 11 50         if (!self || !SvOK(self)) {
    50          
462 0           croak("CodeRef type constraint not initialized");
463             }
464              
465 11 50         SV * param = items >= 1 ? newSVsv(ST(0)) : &PL_sv_undef;
466 11           param = set_default(self, param);
467 11           param = coerce(self, param);
468              
469 11 100         if (!SvROK(param) || !SvOK(param) || (SvTYPE(SvRV(param)) != SVt_PVCV)) {
    50          
    100          
470 10           char * custom_error = get_error_message(self, "CodeRef");
471 10           croak("%s", custom_error);
472             }
473 1           SvREFCNT_inc(param);
474 1           RETVAL = param;
475             OUTPUT:
476             RETVAL
477              
478             SV *
479             CodeRef(...)
480             CODE:
481 11           CV *type = newXS(NULL, XS_Basic__Types__XS__Definition__CodeRef, __FILE__);
482 11           RETVAL = _new(newSVpv("CodeRef", 7), type);
483 11           SvREFCNT_inc(type);
484 11           CvXSUBANY(type).any_ptr = (void *)RETVAL;
485 11           SvREFCNT_inc(RETVAL);
486 11           HV * self = (HV*)SvRV(RETVAL);
487 11           hv_store(self, "constraint", 10, (SV*)type, 0);
488 11 50         if (items % 2 != 0) {
489 0           croak("CodeRef type constraint requires an even number of arguments");
490             }
491 11           int i = 0;
492 11 50         for (i = 0; i < items; i += 2) {
493 0           SV * key = ST(i);
494 0           SV * value = ST(i + 1);
495 0 0         if (!SvOK(key) || SvTYPE(key) != SVt_PV) {
    0          
496 0           croak("key must be a string");
497             }
498 0 0         if (!SvOK(value)) {
499 0           croak("value must be defined");
500             }
501             STRLEN keylen;
502 0           char * keystr = SvPV(key, keylen);
503 0           hv_store(self, keystr, keylen, newSVsv(value), 0);
504             }
505             OUTPUT:
506             RETVAL
507              
508             SV *
509             _RegexpRef(...)
510             CODE:
511 12           SV * self = CvXSUBANY(cv).any_ptr;
512 12 50         if (!self || !SvOK(self)) {
    50          
513 0           croak("RegexpRef type constraint not initialized");
514             }
515              
516 12 50         SV * param = items >= 1 ? newSVsv(ST(0)) : &PL_sv_undef;
517 12           param = set_default(self, param);
518 12           param = coerce(self, param);
519              
520 12 100         if (!SvROK(param) || !SvOK(param) || (SvTYPE(SvRV(param)) != SVt_REGEXP)) {
    50          
    100          
521 11           char * custom_error = get_error_message(self, "RegexpRef");
522 11           croak("%s", custom_error);
523             }
524 1           SvREFCNT_inc(param);
525 1           RETVAL = param;
526             OUTPUT:
527             RETVAL
528              
529             SV *
530             RegexpRef(...)
531             CODE:
532 12           CV *type = newXS(NULL, XS_Basic__Types__XS__Definition__RegexpRef, __FILE__);
533 12           RETVAL = _new(newSVpv("RegexpRef", 9), type);
534 12           SvREFCNT_inc(type);
535 12           CvXSUBANY(type).any_ptr = (void *)RETVAL;
536 12           SvREFCNT_inc(RETVAL);
537 12           HV * self = (HV*)SvRV(RETVAL);
538 12           hv_store(self, "constraint", 10, (SV*)type, 0);
539 12 50         if (items % 2 != 0) {
540 0           croak("RegexpRef type constraint requires an even number of arguments");
541             }
542 12           int i = 0;
543 12 50         for (i = 0; i < items; i += 2) {
544 0           SV * key = ST(i);
545 0           SV * value = ST(i + 1);
546 0 0         if (!SvOK(key) || SvTYPE(key) != SVt_PV) {
    0          
547 0           croak("key must be a string");
548             }
549 0 0         if (!SvOK(value)) {
550 0           croak("value must be defined");
551             }
552             STRLEN keylen;
553 0           char * keystr = SvPV(key, keylen);
554 0           hv_store(self, keystr, keylen, newSVsv(value), 0);
555             }
556             OUTPUT:
557             RETVAL
558              
559             SV *
560             _GlobRef(...)
561             CODE:
562 13           SV * self = CvXSUBANY(cv).any_ptr;
563 13 50         if (!self || !SvOK(self)) {
    50          
564 0           croak("GlobRef type constraint not initialized");
565             }
566              
567 13 50         SV * param = items >= 1 ? newSVsv(ST(0)) : &PL_sv_undef;
568 13           param = set_default(self, param);
569 13           param = coerce(self, param);
570              
571 13 100         if (!SvROK(param) || !SvOK(param) || (SvTYPE(SvRV(param)) != SVt_PVGV)) {
    50          
    100          
572 12           char * custom_error = get_error_message(self, "GlobRef");
573 12           croak("%s", custom_error);
574             }
575 1           SvREFCNT_inc(param);
576 1           RETVAL = param;
577             OUTPUT:
578             RETVAL
579              
580             SV *
581             GlobRef(...)
582             CODE:
583 13           CV *type = newXS(NULL, XS_Basic__Types__XS__Definition__GlobRef, __FILE__);
584 13           RETVAL = _new(newSVpv("GlobRef", 7), type);
585 13           SvREFCNT_inc(type);
586 13           CvXSUBANY(type).any_ptr = (void *)RETVAL;
587 13           SvREFCNT_inc(RETVAL);
588 13           HV * self = (HV*)SvRV(RETVAL);
589 13           hv_store(self, "constraint", 10, (SV*)type, 0);
590 13 50         if (items % 2 != 0) {
591 0           croak("GlobRef type constraint requires an even number of arguments");
592             }
593 13           int i = 0;
594 13 50         for (i = 0; i < items; i += 2) {
595 0           SV * key = ST(i);
596 0           SV * value = ST(i + 1);
597 0 0         if (!SvOK(key) || SvTYPE(key) != SVt_PV) {
    0          
598 0           croak("key must be a string");
599             }
600 0 0         if (!SvOK(value)) {
601 0           croak("value must be defined");
602             }
603             STRLEN keylen;
604 0           char * keystr = SvPV(key, keylen);
605 0           hv_store(self, keystr, keylen, newSVsv(value), 0);
606             }
607             OUTPUT:
608             RETVAL
609              
610             SV *
611             _Str(...)
612             CODE:
613 19           SV * self = CvXSUBANY(cv).any_ptr;
614 19 50         if (!self || !SvOK(self)) {
    50          
615 0           croak("Str type constraint not initialized");
616             }
617              
618              
619 19 100         SV * param = items >= 1 ? newSVsv(ST(0)) : &PL_sv_undef;
620              
621 19           param = set_default(self, param);
622 19           param = coerce(self, param);
623              
624 19           int type = SvTYPE(param);
625 19 100         if (SvROK(param) || !SvOK(param) || (type > SVt_PV)) {
    100          
    50          
626 8           char * custom_error = get_error_message(self, "Str");
627 8           croak("%s", custom_error);
628             }
629 11           SvREFCNT_inc(param);
630 11           RETVAL = param;
631             OUTPUT:
632             RETVAL
633              
634             SV *
635             Str(...)
636             CODE:
637 13           CV *type = newXS(NULL, XS_Basic__Types__XS__Definition__Str, __FILE__);
638 13           RETVAL = _new(newSVpv("Str", 3), type);
639 13           SvREFCNT_inc(type);
640 13           CvXSUBANY(type).any_ptr = (void *)RETVAL;
641 13           SvREFCNT_inc(RETVAL);
642 13           HV * self = (HV*)SvRV(RETVAL);
643 13           hv_store(self, "constraint", 10, (SV*)type, 0);
644 13 50         if (items % 2 != 0) {
645 0           croak("Str type constraint requires an even number of arguments");
646             }
647 13           int i = 0;
648 16 100         for (i = 0; i < items; i += 2) {
649 3           SV * key = ST(i);
650 3           SV * value = ST(i + 1);
651 3 50         if (!SvOK(key) || SvTYPE(key) != SVt_PV) {
    50          
652 0           croak("key must be a string");
653             }
654 3 50         if (!SvOK(value)) {
655 0           croak("value must be defined");
656             }
657             STRLEN keylen;
658 3           char * keystr = SvPV(key, keylen);
659 3           hv_store(self, keystr, keylen, newSVsv(value), 0);
660             }
661             OUTPUT:
662             RETVAL
663              
664              
665             SV *
666             _StrMatch(...)
667             CODE:
668 7           SV * self = CvXSUBANY(cv).any_ptr;
669 7 50         if (!self || !SvOK(self)) {
    50          
670 0           croak("StrMatch type constraint not initialized");
671             }
672              
673 7 50         SV * param = items >= 1 ? newSVsv(ST(0)) : &PL_sv_undef;
674 7           param = set_default(self, param);
675 7           param = coerce(self, param);
676              
677 7           SV ** pattern_sv = hv_fetch((HV*)SvRV(self), "validate", 8, 0);
678              
679 7 50         if (SvTYPE(param) != SVt_PV || !regex_match(param, pattern_sv)) {
    100          
680 2           char * custom_error = get_error_message(self, "StrMatch");
681 2           croak("%s", custom_error);
682             }
683 5           SvREFCNT_inc(param);
684 5           RETVAL = param;
685             OUTPUT:
686             RETVAL
687              
688             SV *
689             StrMatch(...)
690             CODE:
691 5           CV *type = newXS(NULL, XS_Basic__Types__XS__Definition__StrMatch, __FILE__);
692 5           RETVAL = _new(newSVpv("StrMatch", 8), type);
693 5           SvREFCNT_inc(type);
694 5           CvXSUBANY(type).any_ptr = (void *)RETVAL;
695 5           SvREFCNT_inc(RETVAL);
696 5           HV * self = (HV*)SvRV(RETVAL);
697 5           hv_store(self, "constraint", 10, (SV*)type, 0);
698 5 50         if (items % 2 != 0) {
699 0           croak("StrMatch type constraint requires an even number of arguments");
700             }
701 5           int i = 0;
702 11 100         for (i = 0; i < items; i += 2) {
703 6           SV * key = ST(i);
704 6           SV * value = ST(i + 1);
705 6 50         if (!SvOK(key) || SvTYPE(key) != SVt_PV) {
    50          
706 0           croak("key must be a string");
707             }
708 6 50         if (!SvOK(value)) {
709 0           croak("value must be defined");
710             }
711             STRLEN keylen;
712 6           char * keystr = SvPV(key, keylen);
713 6           hv_store(self, keystr, keylen, newSVsv(value), 0);
714             }
715             OUTPUT:
716             RETVAL
717              
718              
719             SV *
720             _Num(...)
721             CODE:
722 16           SV * self = CvXSUBANY(cv).any_ptr;
723 16 50         if (!self || !SvOK(self)) {
    50          
724 0           croak("Num type constraint not initialized");
725             }
726              
727 16 50         SV * param = items >= 1 ? newSVsv(ST(0)) : &PL_sv_undef;
728 16           param = set_default(self, param);
729 16           param = coerce(self, param);
730              
731 16           int type = SvTYPE(param);
732 16 100         if (SvROK(param) || !SvOK(param) || (type != SVt_IV && type != SVt_NV)) {
    100          
    100          
    100          
733 9 100         if ( type != SVt_PV || ! _sv_contains_numbers(param, 0) ) {
    100          
734 7           char * custom_error = get_error_message(self, "Num");
735 7           croak("%s", custom_error);
736             }
737             }
738 9           SvREFCNT_inc(param);
739 9           RETVAL = param;
740             OUTPUT:
741             RETVAL
742              
743             SV *
744             Num(...)
745             CODE:
746 12           CV *type = newXS(NULL, XS_Basic__Types__XS__Definition__Num, __FILE__);
747 12           RETVAL = _new(newSVpv("Num", 3), type);
748 12           SvREFCNT_inc(type);
749 12           CvXSUBANY(type).any_ptr = (void *)RETVAL;
750 12           SvREFCNT_inc(RETVAL);
751 12           HV * self = (HV*)SvRV(RETVAL);
752 12           hv_store(self, "constraint", 10, (SV*)type, 0);
753 12 50         if (items % 2 != 0) {
754 0           croak("Num type constraint requires an even number of arguments");
755             }
756 12           int i = 0;
757 15 100         for (i = 0; i < items; i += 2) {
758 3           SV * key = ST(i);
759 3           SV * value = ST(i + 1);
760 3 50         if (!SvOK(key) || SvTYPE(key) != SVt_PV) {
    50          
761 0           croak("key must be a string");
762             }
763 3 50         if (!SvOK(value)) {
764 0           croak("value must be defined");
765             }
766             STRLEN keylen;
767 3           char * keystr = SvPV(key, keylen);
768 3           hv_store(self, keystr, keylen, newSVsv(value), 0);
769             }
770             OUTPUT:
771             RETVAL
772              
773             SV *
774             _Int(...)
775             CODE:
776 12           SV * self = CvXSUBANY(cv).any_ptr;
777 12 50         if (!self || !SvOK(self)) {
    50          
778 0           croak("Int type constraint not initialized");
779             }
780              
781 12 50         SV * param = items >= 1 ? newSVsv(ST(0)) : &PL_sv_undef;
782 12           param = set_default(self, param);
783 12           param = coerce(self, param);
784              
785 12           int type = SvTYPE(param);
786 12 100         if (SvROK(param) || !SvOK(param) || (type != SVt_IV)) {
    100          
    100          
787 9 100         if ( type != SVt_PV || ! _sv_contains_numbers(param, 1) ) {
    100          
788 8           char * custom_error = get_error_message(self, "Int");
789 8           croak("%s", custom_error);
790             }
791             }
792 4           SvREFCNT_inc(param);
793 4           RETVAL = param;
794             OUTPUT:
795             RETVAL
796              
797             SV *
798             Int(...)
799             CODE:
800 11           CV *type = newXS(NULL, XS_Basic__Types__XS__Definition__Int, __FILE__);
801 11           RETVAL = _new(newSVpv("Int", 3), type);
802 11           SvREFCNT_inc(type);
803 11           CvXSUBANY(type).any_ptr = (void *)RETVAL;
804 11           SvREFCNT_inc(RETVAL);
805 11           HV * self = (HV*)SvRV(RETVAL);
806 11           hv_store(self, "constraint", 10, (SV*)type, 0);
807 11 50         if (items % 2 != 0) {
808 0           croak("Int type constraint requires an even number of arguments");
809             }
810 11           int i = 0;
811 11 50         for (i = 0; i < items; i += 2) {
812 0           SV * key = ST(i);
813 0           SV * value = ST(i + 1);
814 0 0         if (!SvOK(key) || SvTYPE(key) != SVt_PV) {
    0          
815 0           croak("key must be a string");
816             }
817 0 0         if (!SvOK(value)) {
818 0           croak("value must be defined");
819             }
820             STRLEN keylen;
821 0           char * keystr = SvPV(key, keylen);
822 0           hv_store(self, keystr, keylen, newSVsv(value), 0);
823             }
824             OUTPUT:
825             RETVAL
826              
827             SV *
828             _Bool(...)
829             CODE:
830 17           SV * self = CvXSUBANY(cv).any_ptr;
831 17 50         if (!self || !SvOK(self)) {
    50          
832 0           croak("Bool type constraint not initialized");
833             }
834              
835 17 50         SV * param = items >= 1 ? newSVsv(ST(0)) : &PL_sv_undef;
836 17           param = set_default(self, param);
837 17           param = coerce(self, param);
838              
839 17 100         if (!_sv_isa_bool(param)) {
840 9           char * custom_error = get_error_message(self, "Bool");
841 9           croak("%s", custom_error);
842             }
843 8           SvREFCNT_inc(param);
844 8           RETVAL = param;
845             OUTPUT:
846             RETVAL
847              
848             SV *
849             Bool(...)
850             CODE:
851 17           CV *type = newXS(NULL, XS_Basic__Types__XS__Definition__Bool, __FILE__);
852 17           RETVAL = _new(newSVpv("Bool", 4), type);
853 17           SvREFCNT_inc(type);
854 17           CvXSUBANY(type).any_ptr = (void *)RETVAL;
855 17           SvREFCNT_inc(RETVAL);
856 17           HV * self = (HV*)SvRV(RETVAL);
857 17           hv_store(self, "constraint", 10, (SV*)type, 0);
858 17 50         if (items % 2 != 0) {
859 0           croak("Bool type constraint requires an even number of arguments");
860             }
861 17           int i = 0;
862 17 50         for (i = 0; i < items; i += 2) {
863 0           SV * key = ST(i);
864 0           SV * value = ST(i + 1);
865 0 0         if (!SvOK(key) || SvTYPE(key) != SVt_PV) {
    0          
866 0           croak("key must be a string");
867             }
868 0 0         if (!SvOK(value)) {
869 0           croak("value must be defined");
870             }
871             STRLEN keylen;
872 0           char * keystr = SvPV(key, keylen);
873 0           hv_store(self, keystr, keylen, newSVsv(value), 0);
874             }
875             OUTPUT:
876             RETVAL
877              
878             SV *
879             _Object(...)
880             CODE:
881 10           SV * self = CvXSUBANY(cv).any_ptr;
882 10 50         if (!self || !SvOK(self)) {
    50          
883 0           croak("Object type constraint not initialized");
884             }
885              
886 10 50         SV * param = items >= 1 ? newSVsv(ST(0)) : &PL_sv_undef;
887 10           param = set_default(self, param);
888 10           param = coerce(self, param);
889              
890 10 100         if (!SvROK(param) || !SvOK(param) || !SvSTASH(SvRV(param))) {
    50          
    50          
891 6           char * custom_error = get_error_message(self, "Object");
892 6           croak("%s", custom_error);
893             }
894 4           SvREFCNT_inc(param);
895 4           RETVAL = param;
896             OUTPUT:
897             RETVAL
898              
899             SV *
900             Object(...)
901             CODE:
902 10           CV *type = newXS(NULL, XS_Basic__Types__XS__Definition__Object, __FILE__);
903 10           RETVAL = _new(newSVpv("Object", 6), type);
904 10           SvREFCNT_inc(type);
905 10           CvXSUBANY(type).any_ptr = (void *)RETVAL;
906 10           SvREFCNT_inc(RETVAL);
907 10           HV * self = (HV*)SvRV(RETVAL);
908 10           hv_store(self, "constraint", 10, (SV*)type, 0);
909 10 50         if (items % 2 != 0) {
910 0           croak("Object type constraint requires an even number of arguments");
911             }
912 10           int i = 0;
913 10 50         for (i = 0; i < items; i += 2) {
914 0           SV * key = ST(i);
915 0           SV * value = ST(i + 1);
916 0 0         if (!SvOK(key) || SvTYPE(key) != SVt_PV) {
    0          
917 0           croak("key must be a string");
918             }
919 0 0         if (!SvOK(value)) {
920 0           croak("value must be defined");
921             }
922             STRLEN keylen;
923 0           char * keystr = SvPV(key, keylen);
924 0           hv_store(self, keystr, keylen, newSVsv(value), 0);
925             }
926             OUTPUT:
927             RETVAL
928              
929             SV *
930             _ClassName(...)
931             CODE:
932 12           SV * self = CvXSUBANY(cv).any_ptr;
933 12 50         if (!self || !SvOK(self)) {
    50          
934 0           croak("ClassName type constraint not initialized");
935             }
936              
937 12 50         SV * param = items >= 1 ? newSVsv(ST(0)) : &PL_sv_undef;
938 12           param = set_default(self, param);
939 12           param = coerce(self, param);
940              
941 12 50         if (!SvOK(param) || SvROK(param) || SvTYPE(param) != SVt_PV) {
    100          
    100          
942             // Not a defined, non-reference string
943 3           char * custom_error = get_error_message(self, "ClassName");
944 3           croak("%s", custom_error);
945             }
946             STRLEN len;
947 9           const char *pkg = SvPV(param, len);
948 9           HV *stash = gv_stashpvn(pkg, len, 0);
949 9 100         if (!stash) {
950 4           char * custom_error = get_error_message(self, "ClassName");
951 4           croak("%s", custom_error);
952             }
953 5           SvREFCNT_inc(param);
954 5           RETVAL = param;
955             OUTPUT:
956             RETVAL
957              
958             SV *
959             ClassName(...)
960             CODE:
961 12           CV *type = newXS(NULL, XS_Basic__Types__XS__Definition__ClassName, __FILE__);
962 12           RETVAL = _new(newSVpv("ClassName", 9), type);
963 12           SvREFCNT_inc(type);
964 12           CvXSUBANY(type).any_ptr = (void *)RETVAL;
965 12           SvREFCNT_inc(RETVAL);
966 12           HV * self = (HV*)SvRV(RETVAL);
967 12           hv_store(self, "constraint", 10, (SV*)type, 0);
968 12 50         if (items % 2 != 0) {
969 0           croak("ClassName type constraint requires an even number of arguments");
970             }
971 12           int i = 0;
972 12 50         for (i = 0; i < items; i += 2) {
973 0           SV * key = ST(i);
974 0           SV * value = ST(i + 1);
975 0 0         if (!SvOK(key) || SvTYPE(key) != SVt_PV) {
    0          
976 0           croak("key must be a string");
977             }
978 0 0         if (!SvOK(value)) {
979 0           croak("value must be defined");
980             }
981             STRLEN keylen;
982 0           char * keystr = SvPV(key, keylen);
983 0           hv_store(self, keystr, keylen, newSVsv(value), 0);
984             }
985             OUTPUT:
986             RETVAL
987              
988             SV *
989             _Enum(...)
990             CODE:
991 8           SV * self = CvXSUBANY(cv).any_ptr;
992 8 50         if (!self || !SvOK(self)) {
    50          
993 0           croak("Enum type constraint not initialized");
994             }
995              
996 8 100         SV * param = items >= 1 ? newSVsv(ST(0)) : &PL_sv_undef;
997 8           param = set_default(self, param);
998 8           param = coerce(self, param);
999              
1000 8 100         if (!SvOK(param) || SvTYPE(param) != SVt_PV) {
    100          
1001 3           char * custom_error = get_error_message(self, "Enum");
1002 3           croak("%s", custom_error);
1003             }
1004 5           HV * self_hv = (HV*)SvRV(self);
1005 5 50         if (!hv_exists(self_hv, "validate", 8)) {
1006 0           croak("Enum type constraint not initialized with validation values");
1007             }
1008              
1009 5           SV * validate = *hv_fetch(self_hv, "validate", 8, 0);
1010 5 50         if (!SvROK(validate) || SvTYPE(SvRV(validate)) != SVt_PVAV) {
    50          
1011 0           croak("Enum type constraint validation values must be an array reference");
1012             }
1013            
1014             STRLEN retlen;
1015 5           char * param_str = SvPV(param, retlen);
1016 5           AV * enm = (AV*)SvRV(validate);
1017 5           int len = av_len(enm);
1018 5           int found = 0, i = 0;
1019 14 100         for (i = 0; i <= len; i++) {
1020 11           SV * val = *av_fetch(enm, i, 0);
1021 11 50         if (SvOK(val) && SvTYPE(val) == SVt_PV ) {
    50          
1022 11           char * val_str = SvPV(val, retlen);
1023 11 100         if (strcmp(val_str, param_str) == 0) {
1024 2           found = 1;
1025 2           break;
1026             }
1027             }
1028             }
1029            
1030 5 100         if (found == 0) {
1031 3           char * custom_error = get_error_message(self, "Enum");
1032 3           croak("%s", custom_error);
1033             }
1034            
1035 2           SvREFCNT_inc(param);
1036 2           RETVAL = param;
1037             OUTPUT:
1038             RETVAL
1039              
1040             SV *
1041             Enum(...)
1042             CODE:
1043 2           CV *type = newXS(NULL, XS_Basic__Types__XS__Definition__Enum, __FILE__);
1044 2           RETVAL = _new(newSVpv("Enum", 4), type);
1045 2           SvREFCNT_inc(type);
1046 2           CvXSUBANY(type).any_ptr = (void *)RETVAL;
1047 2           SvREFCNT_inc(RETVAL);
1048 2           HV * self = (HV*)SvRV(RETVAL);
1049 2           hv_store(self, "constraint", 10, (SV*)type, 0);
1050 2 50         if (items % 2 != 0) {
1051 0           croak("Enum type constraint requires an even number of arguments");
1052             }
1053 2           int i = 0;
1054 5 100         for (i = 0; i < items; i += 2) {
1055 3           SV * key = ST(i);
1056 3           SV * value = ST(i + 1);
1057 3 50         if (!SvOK(key) || SvTYPE(key) != SVt_PV) {
    50          
1058 0           croak("key must be a string");
1059             }
1060 3 50         if (!SvOK(value)) {
1061 0           croak("value must be defined");
1062             }
1063             STRLEN keylen;
1064 3           char * keystr = SvPV(key, keylen);
1065 3           hv_store(self, keystr, keylen, newSVsv(value), 0);
1066             }
1067             OUTPUT:
1068             RETVAL
1069              
1070             MODULE = Basic::Types::XS PACKAGE = Basic::Types::XS
1071             PROTOTYPES: ENABLE
1072             FALLBACK: TRUE
1073              
1074             SV *
1075             default(self, value)
1076             SV *self
1077             SV *value
1078             CODE:
1079 1 50         if (!self || !SvROK(self)) {
    50          
1080 0           croak("constraint not initialized");
1081             }
1082 1 50         if (!SvROK(value) || SvTYPE(SvRV(value)) != SVt_PVCV) {
    50          
1083 0           croak("value must be a coderef");
1084             }
1085 1           SvREFCNT_inc(self);
1086 1           HV * self_hv = (HV*)SvRV(self);
1087 1           hv_store(self_hv, "default", 7, newSVsv(value), 0);
1088 1           RETVAL = self;
1089             OUTPUT:
1090             RETVAL
1091              
1092             SV *
1093             coerce(self, value)
1094             SV *self
1095             SV *value
1096             CODE:
1097 1 50         if (!self || !SvROK(self)) {
    50          
1098 0           croak("constraint not initialized");
1099             }
1100 1 50         if (!SvROK(value) || SvTYPE(SvRV(value)) != SVt_PVCV) {
    50          
1101 0           croak("value must be a coderef");
1102             }
1103 1           SvREFCNT_inc(self);
1104 1           HV * self_hv = (HV*)SvRV(self);
1105 1           hv_store(self_hv, "coerce", 6, newSVsv(value), 0);
1106 1           RETVAL = self;
1107             OUTPUT:
1108             RETVAL
1109              
1110             SV *
1111             message(self, value)
1112             SV *self
1113             SV *value
1114             CODE:
1115 2 50         if (!self || !SvROK(self)) {
    50          
1116 0           croak("constraint not initialized");
1117             }
1118 2           SvREFCNT_inc(self);
1119 2           HV * self_hv = (HV*)SvRV(self);
1120 2           hv_store(self_hv, "message", 7, newSVsv(value), 0);
1121 2           RETVAL = self;
1122             OUTPUT:
1123             RETVAL
1124              
1125             SV *
1126             validate(self, value)
1127             SV *self
1128             SV *value
1129             OVERLOAD: &
1130             CODE:
1131 0 0         if (!self || !SvROK(self)) {
    0          
1132 0           croak("constraint not initialized");
1133             }
1134 0           SvREFCNT_inc(self);
1135 0           HV * self_hv = (HV*)SvRV(self);
1136 0           hv_store(self_hv, "validate", 8, newSVsv(value), 0);
1137 0           RETVAL = self;
1138             OUTPUT:
1139             RETVAL
1140              
1141             CV *
1142             constraint(...)
1143             OVERLOAD: &{}
1144             CODE:
1145 221           SV * self = ST(0);
1146 221 50         if (!SvROK(self) || SvTYPE(SvRV(self)) != SVt_PVHV) {
    50          
1147 0           croak("first argument must be a Basic::Types::XS object");
1148             }
1149 221           SvREFCNT_inc(self);
1150 221           SV * cb = *hv_fetch((HV*)SvRV(self), "constraint", 10, 0);
1151 221           RETVAL = (CV*)cb;
1152             OUTPUT:
1153             RETVAL
1154              
1155             void
1156             import( ...)
1157             CODE:
1158 20           char *pkg = get_caller();
1159             STRLEN retlen;
1160 20           int i = 1;
1161 44 100         for (i = 1; i < items; i++) {
1162 24           char * ex = SvPV(ST(i), retlen);
1163 24           char name [strlen(pkg) + 2 + retlen];
1164 24           sprintf(name, "%s::%s", pkg, ex);
1165 24 100         if (strcmp(ex, "Any") == 0) {
1166 1           newXS(name, XS_Basic__Types__XS__Definition_Any, __FILE__);
1167 23 100         } else if (strcmp(ex, "Defined") == 0) {
1168 1           newXS(name, XS_Basic__Types__XS__Definition_Defined, __FILE__);
1169 22 100         } else if (strcmp(ex, "Str") == 0) {
1170 3           newXS(name, XS_Basic__Types__XS__Definition_Str, __FILE__);
1171 19 100         } else if (strcmp(ex, "Num") == 0) {
1172 2           newXS(name, XS_Basic__Types__XS__Definition_Num, __FILE__);
1173 17 100         } else if (strcmp(ex, "Int") == 0) {
1174 2           newXS(name, XS_Basic__Types__XS__Definition_Int, __FILE__);
1175 15 100         } else if (strcmp(ex, "Ref") == 0) {
1176 1           newXS(name, XS_Basic__Types__XS__Definition_Ref, __FILE__);
1177 14 100         } else if (strcmp(ex, "ScalarRef") == 0) {
1178 1           newXS(name, XS_Basic__Types__XS__Definition_ScalarRef, __FILE__);
1179 13 100         } else if (strcmp(ex, "ArrayRef") == 0) {
1180 2           newXS(name, XS_Basic__Types__XS__Definition_ArrayRef, __FILE__);
1181 11 100         } else if (strcmp(ex, "HashRef") == 0) {
1182 2           newXS(name, XS_Basic__Types__XS__Definition_HashRef, __FILE__);
1183 9 100         } else if (strcmp(ex, "CodeRef") == 0) {
1184 1           newXS(name, XS_Basic__Types__XS__Definition_CodeRef, __FILE__);
1185 8 100         } else if (strcmp(ex, "RegexpRef") == 0) {
1186 1           newXS(name, XS_Basic__Types__XS__Definition_RegexpRef, __FILE__);
1187 7 100         } else if (strcmp(ex, "GlobRef") == 0) {
1188 1           newXS(name, XS_Basic__Types__XS__Definition_GlobRef, __FILE__);
1189 6 100         } else if (strcmp(ex, "Bool") == 0) {
1190 1           newXS(name, XS_Basic__Types__XS__Definition_Bool, __FILE__);
1191 5 100         } else if (strcmp(ex, "Object") == 0) {
1192 1           newXS(name, XS_Basic__Types__XS__Definition_Object, __FILE__);
1193 4 100         } else if (strcmp(ex, "ClassName") == 0) {
1194 1           newXS(name, XS_Basic__Types__XS__Definition_ClassName, __FILE__);
1195 3 100         } else if (strcmp(ex, "StrMatch") == 0) {
1196 2           newXS(name, XS_Basic__Types__XS__Definition_StrMatch, __FILE__);
1197 1 50         } else if (strcmp(ex, "Enum") == 0) {
1198 1           newXS(name, XS_Basic__Types__XS__Definition_Enum, __FILE__);
1199             } else {
1200 0           croak("Unknown type constraint: %s", ex);
1201             }
1202             }