File Coverage

lib/PDL/Core/pdlcore.c
Criterion Covered Total %
statement 417 509 81.9
branch 948 9088 10.4
condition n/a
subroutine n/a
pod n/a
total 1365 9597 14.2


line stmt bran cond sub pod time code
1             #include "pdl.h" /* Data structure declarations */
2             #define PDL_IN_CORE /* access funcs directly not through PDL-> */
3             #include "pdlcore.h" /* Core declarations */
4             #include "pdlperl.h"
5              
6             extern struct Core PDL;
7              
8             /* Note this is *perl's* magic, similar in principle, but unrelated to pdlmagic.{h,c}
9             * This is used for linkage from a PDL object to the PDL struct.
10             * PDL objects also store the struct pointer in the SV as an int, or HV as a key,
11             * but looking up magic is faster than verifying the reftype and class.
12             */
13 75024           static int pdl_perl_extension_magic_free(pTHX_ SV* sv, MAGIC* mg) {
14             /* Do nothing, for now, because PDL destruction happens during DESTROY */
15 75024           return 0;
16             }
17             static MGVTBL pdl_perl_extension_magic_vtbl= {
18             0, /* get */
19             0, /* set */
20             0, /* length */
21             0, /* clear */
22             pdl_perl_extension_magic_free /* free */
23             #ifdef MGf_COPY
24             , 0 /* copy magic to new variable */
25             #endif
26             #ifdef MGf_DUP
27             , 0 /* dup for new threads */
28             #endif
29             #ifdef MGf_LOCAL
30             , 0 /* local */
31             #endif
32             };
33              
34 83705           void pdl_SetSV_PDL ( SV *sv, pdl *it ) {
35             SV *newref;
36 83705 100         if (!it->sv) {
37             MAGIC *magic;
38 75024           newref = newRV_noinc(it->sv = newSViv(PTR2IV(it)));
39 75024           (void)sv_bless(newref,gv_stashpv("PDL",TRUE));
40 75024           magic= sv_magicext(it->sv, NULL, PERL_MAGIC_ext,
41             &pdl_perl_extension_magic_vtbl, (const char*) it, 0);
42             (void)magic; // suppress warning
43             } else {
44 8681           newref = newRV_inc(it->sv);
45 8681           SvAMAGIC_on(newref);
46             }
47 83705           sv_setsv(sv,newref);
48 83705           SvREFCNT_dec(newref);
49 83705           }
50              
51             /* Size of data type information */
52 101807           size_t pdl_howbig (pdl_datatypes datatype) {
53             #define X(datatype, ctype, ...) \
54             return sizeof(ctype);
55 101807           PDL_GENERICSWITCH(PDL_TYPELIST_ALL, datatype, X, croak("Not a known data type code=%d", datatype))
56             #undef X
57             }
58              
59             /*
60             "Convert" a perl SV into a pdl (alright more like a mapping as
61             the data block is not actually copied in the most common case
62             of a single scalar) scalars are automatically converted to PDLs.
63             */
64 347479           pdl* pdl_SvPDLV ( SV* sv ) {
65              
66             pdl* ret;
67             SV *sv2;
68              
69 347479 100         if ( !SvROK(sv) ) {
70 7972 100         if (sv_derived_from(sv, "PDL")) /* object method called as class method */
71 2           pdl_pdl_barf("called object method on 'PDL' or similar");
72             /* The scalar is not a ref, so we can use direct conversion. */
73             PDL_Anyval data;
74 7970 50         ANYVAL_FROM_SV(data, sv, TRUE, -1, TRUE);
    50          
    100          
    100          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    100          
    100          
75 7970 50         PDLDEBUG_f(printf("pdl_SvPDLV type: %d\n", data.type));
76 7970           return pdl_scalar(data);
77             } /* End of scalar case */
78              
79             /* If execution reaches here, then sv is NOT a scalar
80             * (i.e. it is a ref).
81             */
82              
83             /* Make the common case fast - if the ref'd object has a pdl struct attached via magic,
84             * then return that before inspecting anything further. */
85 339507 100         if (SvMAGICAL(SvRV(sv))) {
86             MAGIC *magic;
87             /* Iterate magic attached to this SV/AV/HV, looking for one with our vtable */
88 340080 50         for (magic = SvMAGIC(SvRV(sv)); magic; magic = magic->mg_moremagic)
89 340080 100         if (magic->mg_virtual == &pdl_perl_extension_magic_vtbl)
90             /* If found, the mg_ptr points to the fields structure. */
91 339181           return (pdl*) magic->mg_ptr;
92             }
93              
94 326 100         if (SvTYPE(SvRV(sv)) == SVt_PVHV) {
95 197           HV *hash = (HV*)SvRV(sv);
96 197           SV **svp = hv_fetchs(hash,"PDL",0);
97 197 100         if (svp == NULL) {
98 46 100         if (sv_derived_from(sv, "Math::Complex")) { /* relies on M:C using hash */
99             PDL_Anyval data;
100 132 50         ANYVAL_FROM_MCOMPLEX(data, sv);
    50          
    50          
    100          
    50          
101 44           return pdl_scalar(data);
102             }
103 2           croak("Hash given as a pdl (%s) - but not {PDL} key!", sv_reftype(SvRV(sv), TRUE));
104             }
105              
106             /* This is the magic hook which checks to see if {PDL}
107             is a code ref, and if so executes it. It should
108             return a standard ndarray. This allows
109             all kinds of funky objects to be derived from PDL,
110             and allow normal PDL functions to still work so long
111             as the {PDL} code returns a standard ndarray on
112             demand - KGB */
113 156 50         if (SvROK(*svp) && SvTYPE(SvRV(*svp)) == SVt_PVCV) {
    100          
114 5           dSP;
115 5           ENTER;
116 5           SAVETMPS;
117 5 50         PUSHMARK(SP);
118 5 50         XPUSHs(sv);
119 5           PUTBACK;
120 5           int count = perl_call_sv(*svp, G_SCALAR);
121 5           SPAGAIN;
122 5 50         if (count != 1)
123 0           croak("Execution of PDL structure failed to return one value\n");
124 5           sv=newSVsv(POPs);
125 5           PUTBACK;
126 5 50         FREETMPS;
127 5           LEAVE;
128             } else {
129 146           sv = *svp;
130             }
131              
132 151 50         if (SvGMAGICAL(sv)) {
133 0           mg_get(sv);
134             }
135              
136 151 50         if ( !SvROK(sv) ) { /* Got something from a hash but not a ref */
137 0           croak("Hash given as pdl - but PDL key is not a ref!");
138             }
139             }
140              
141 280 100         if (SvTYPE(SvRV(sv)) == SVt_PVAV) {
142             /* This is similar to pdl_avref in Core.xs -- we do the same steps here. */
143 16           int datalevel = -1;
144 16           AV *av = (AV *)SvRV(sv);
145 16           AV *dims = (AV *)sv_2mortal((SV *)newAV());
146 16           av_store(dims,0,newSViv( (IV) av_len(av)+1 ) );
147              
148             /* Pull sizes using av_ndcheck */
149 16           av_ndcheck(av,dims,0,&datalevel);
150              
151 16           return pdl_from_array(av, dims, -1, NULL); /* -1 means pdltype autodetection */
152             } /* end of AV code */
153              
154 264 100         if (SvTYPE(SvRV(sv)) != SVt_PVMG)
155 2           croak("Error - tried to use an unknown data structure as a PDL");
156 262 100         if (!sv_derived_from( sv, "PDL"))
157 1           croak("Error - tried to use an unknown Perl object type as a PDL");
158              
159 261           sv2 = (SV*) SvRV(sv);
160              
161             /* Return the pdl * pointer */
162 261           ret = INT2PTR(pdl *, SvIV(sv2));
163 261 50         if (!ret) croak("Fatal error: ndarray address is NULL");
164              
165             /* Final check -- make sure it has the right magic number */
166 261 50         if (ret->magicno != PDL_MAGICNO)
167 0           croak("Fatal error: argument is probably not an ndarray, or\
168             magic no overwritten. You're in trouble, guv: %p %p %lu\n",sv2,ret,ret->magicno);
169              
170 261 50         if (ret->has_badvalue && ret->badvalue.type != ret->datatype)
    0          
171 0           barf("Badvalue has type=%d != pdltype=%d", ret->badvalue.type, ret->datatype);
172 261           return ret;
173             }
174              
175             /* Pack dims array - returns dims[] (pdl_smalloced) and ndims */
176 31194           PDL_Indx* pdl_packdims ( SV* sv, PDL_Indx *ndims ) {
177 31194 50         if (!(SvROK(sv) && SvTYPE(SvRV(sv))==SVt_PVAV)) /* Test */
    50          
178 0           return NULL;
179 31194           AV *array = (AV *) SvRV(sv); /* dereference */
180 31194           *ndims = (PDL_Indx) av_len(array) + 1; /* Number of dimensions */
181 31194           PDL_Indx *dims = (PDL_Indx *) pdl_smalloc( (*ndims) * sizeof(*dims) ); /* Array space */
182 31194 50         if (dims == NULL) return NULL;
183             PDL_Indx i;
184 55739 100         for (i=0; i<(*ndims); i++) {
185 24545           dims[i] = (PDL_Indx) SvIV(*(av_fetch( array, i, 0 )));
186             }
187 31194           return dims;
188             }
189              
190             /* Pack array of pdl* - returns pdls[] (pdl_smalloced) and npdls */
191 8           pdl ** pdl_packpdls( SV* sv, PDL_Indx *npdls ) {
192 8 100         if (!SvOK(sv)) { /* undef is OK, treat as empty */
193 3           *npdls = 0;
194 3           return NULL;
195             }
196 5 100         if (!SvROK(sv)) pdl_pdl_barf("Gave a non-reference as array-ref of PDLs");
197 4 50         if (SvTYPE(SvRV(sv))!=SVt_PVAV)
198 0           pdl_pdl_barf("Gave a non-array-reference as array-ref of PDLs");
199 4           AV *array = (AV *) SvRV(sv);
200 4 50         if (!array) pdl_pdl_barf("Failed to get AV from reference");
201 4           *npdls = (PDL_Indx) av_len(array) + 1;
202 4 100         if (!*npdls) return NULL;
203 3           pdl **pdls = (pdl **) pdl_smalloc( (*npdls) * sizeof(*pdls) );
204 3 50         if (!pdls) pdl_pdl_barf("Failed to allocate memory for pointers to PDLs");
205             PDL_Indx i;
206 9 100         for (i=0; i<(*npdls); i++) {
207 6           SV **s = av_fetch( array, i, 0 );
208 6 50         if (!s) pdl_pdl_barf("Failed to fetch SV #%"IND_FLAG, i);
209 6           pdls[i] = pdl_SvPDLV(*s);
210             }
211 3           return pdls;
212             }
213              
214             /* Unpack array of pdl* into SV* */
215 2           SV* pdl_unpackpdls( pdl **pdls, PDL_Indx npdls ) {
216 2           AV *array = newAV();
217 2 50         if (!array) return NULL;
218 2           av_extend(array, npdls + 1);
219             PDL_Indx i;
220 6 100         for (i=0; i
221 4           SV *sv = newSV(0);
222 4           pdl_SetSV_PDL(sv, pdls[i]);
223 4           av_push(array, sv);
224             }
225 2           return sv_2mortal(newRV_noinc((SV *)array));
226             }
227              
228 0           PDL_Indx pdl_safe_indterm( PDL_Indx dsz, PDL_Indx at, char *file, int lineno)
229             {
230 0 0         if (!(at >= 0 && at < dsz))
    0          
231 0 0         pdl_pdl_barf("access [%d] out of range [0..%d] (inclusive) at %s line %d",
232             at, dsz-1, file?file:"?", lineno);
233 0           return at;
234             }
235              
236             /*
237             pdl_smalloc - utility to get temporary memory space. Uses
238             a mortal *SV for this so it is automatically freed when the current
239             context is terminated without having to call free(). Naughty but
240             nice!
241             */
242 40317           void* pdl_smalloc ( STRLEN nbytes ) {
243 40317           SV* work = sv_2mortal(newSVpv("", 0));
244 40317 50         SvGROW( work, nbytes);
    100          
245 40317           return SvPV_nolen(work);
246             }
247              
248             /*********** Stuff for barfing *************/
249             /*
250             This routine barfs/warns in a thread-safe manner. If we're in the main thread,
251             this calls the perl-level barf/warn. If in a worker thread, we save the
252             message to barf/warn in the main thread later
253             For greppability: this is where pdl_pdl_barf and pdl_pdl_warn are defined
254             */
255              
256             #define GEN_PDL_BARF_OR_WARN_I_STDARG(type, iswarn) \
257             void pdl_pdl_##type(const char* pat, ...) \
258             { \
259             va_list args; \
260             va_start(args, pat); \
261             /* If we're in a worker thread, we queue the \
262             * barf/warn for later, and exit the thread ... \
263             */ \
264             if ( pdl_pthread_barf_or_warn(pat, iswarn, &args) ) \
265             return; \
266             /* ... otherwise we fall through and barf by calling \
267             * the perl-level PDL::barf() or PDL::cluck() \
268             */ \
269             dSP; \
270             ENTER; \
271             SAVETMPS; \
272             PUSHMARK(SP); \
273             SV *sv = sv_2mortal(newSV(0)); \
274             va_start(args, pat); \
275             int size = vsnprintf(NULL, 0, pat, args); \
276             va_end(args); \
277             if (size < 0) { \
278             sv_setpv(sv, "vsnprintf error"); \
279             } else { \
280             size += 2; /* For '\0' + 1 as CentOS 7 is off by 1 */ \
281             char buf[size]; \
282             va_start(args, pat); \
283             size = vsnprintf(buf, size, pat, args); \
284             va_end(args); \
285             sv_setpv(sv, size < 0 ? "vsnprintf error" : buf); \
286             } \
287             XPUSHs(sv); \
288             PUTBACK; \
289             call_pv(iswarn ? "PDL::cluck" : "PDL::barf", G_DISCARD); \
290             FREETMPS; \
291             LEAVE; \
292             }
293              
294 306 50         GEN_PDL_BARF_OR_WARN_I_STDARG(barf, 0)
    50          
    50          
    50          
    50          
    0          
295 24 50         GEN_PDL_BARF_OR_WARN_I_STDARG(warn, 1)
    50          
    50          
    50          
    50          
    50          
296              
297             /**********************************************************************
298             *
299             * CONSTRUCTOR/INGESTION HELPERS
300             *
301             * The following routines assist with the permissive constructor,
302             * which is designed to build a PDL out of basically anything thrown at it.
303             *
304             * They are all called by pdl_avref in Core.xs, which in turn is called by the constructors
305             * in Core.pm. The main entry point is pdl_from_array(), which calls
306             * av_ndcheck() to identify the necessary size of the output PDL, and then dispatches
307             * the copy into pdl_setav_ according to the type of the output PDL.
308             *
309             */
310              
311             /******************************
312             * av_ndcheck -
313             * traverse a Perl array ref recursively, following down any number of
314             * levels of references, and generate a minimal PDL dim list that can
315             * encompass them all according to permissive-constructor rules.
316             *
317             * Scalars, array refs, and PDLs may be mixed in the incoming AV.
318             *
319             * The routine works out the dimensions of a corresponding
320             * ndarray (in the AV dims) in reverse notation (vs PDL conventions).
321             *
322             * It does not enforce a rectangular array on the input, the idea being that
323             * omitted values will be set to zero or the undefval in the resulting ndarray,
324             * i.e. we can make ndarrays from 'sparse' array refs.
325             *
326             * Empty PDLs are treated like any other dimension -- i.e. their
327             * 0-length dimensions are thrown into the mix just like nonzero
328             * dimensions would be.
329             *
330             * The possible presence of empty PDLs forces us to pad out dimensions
331             * to unity explicitly in cases like
332             * [ Empty[2x0x2], 5 ]
333             * where simple parsing would yield a dimlist of
334             * [ 2,0,2,2 ]
335             * which is still Empty.
336             */
337              
338 9397           PDL_Indx av_ndcheck(AV* av, AV* dims, int level, int *datalevel)
339             {
340             PDL_Indx i, len, oldlen;
341 9397           int newdepth, depth = 0;
342 9397           int n_scalars = 0;
343             SV *el, **elp;
344             pdl *dest_pdl; /* Stores PDL argument */
345              
346 9397 50         if (dims==NULL) {
347 0           pdl_pdl_barf("av_ndcheck - got a null dim array! This is a bug in PDL.");
348             }
349              
350             /* Start with a clean slate */
351 9397 100         if (level==0) {
352 7661           av_clear(dims);
353             }
354              
355 9397           len = av_len(av); /* Loop over elements of the AV */
356 32558 100         for (i=0; i<= len; i++) {
357              
358 23161           newdepth = 0; /* Each element - find depth */
359 23161           elp = av_fetch(av,i,0);
360              
361 23161 50         el = elp ? *elp : 0; /* Get the ith element */
362 23161 50         if (el && SvROK(el)) { /* It is a reference */
    100          
363 2178 100         if (SvTYPE(SvRV(el)) == SVt_PVAV) { /* It is an array reference */
364              
365             /* Recurse to find depth inside the array reference */
366 1736           newdepth = 1 + av_ndcheck((AV *) SvRV(el), dims, level+1, datalevel);
367              
368 442 50         } else if ( (dest_pdl = pdl_SvPDLV(el)) ) {
369             /* It is a PDL - walk down its dimension list, exactly as if it
370             * were a bunch of nested array refs. We pull the ndims and dims
371             * fields out to local variables so that nulls can be treated specially.
372             */
373             int j;
374             short pndims;
375             PDL_Indx *dest_dims;
376 442 50         PDLDEBUG_f(printf("av_ndcheck calling ")); pdl_barf_if_error(pdl_make_physdims(dest_pdl));
377 442           pndims = dest_pdl->ndims;
378 442           dest_dims = dest_pdl->dims;
379 495 100         for (j=0;j
380 53           int jl = pndims-j+level;
381              
382 53           PDL_Indx siz = dest_dims[j];
383              
384 86           if ( av_len(dims) >= jl &&
385 33           av_fetch(dims,jl,0) != NULL &&
386 25 50         SvIOK(*(av_fetch(dims,jl,0)))) {
387              
388             /* We have already found something that specifies this dimension -- so */
389             /* we keep the size if possible, or enlarge if necessary. */
390 25           oldlen=(PDL_Indx)SvIV(*(av_fetch(dims,jl,0)));
391 25 100         if (siz > oldlen) {
392 4           sv_setiv(*(av_fetch(dims,jl,0)),(IV)(dest_dims[j]));
393             }
394              
395             } else {
396             /* Breaking new dimensional ground here -- if this is the first element */
397             /* in the arg list, then we can keep zero elements -- but if it is not */
398             /* the first element, we have to pad zero dims to unity (because the */
399             /* prior object had implicit size of 1 in all implicit dimensions) */
400 28 100         av_store(dims, jl, newSViv((IV)(siz?siz:(i?1:0))));
    100          
401             }
402             }
403              
404             /* We have specified all the dims in this PDL. Now pad out the implicit */
405             /* dims of size unity, to wipe out any dims of size zero we have already */
406             /* marked. */
407              
408 533 100         for (j=pndims+1; j <= av_len(dims); j++) {
409 91           SV **svp = av_fetch(dims,j,0);
410              
411 91 100         if (!svp){
412 2           av_store(dims, j, newSViv((IV)1));
413 89 50         } else if ( (int)SvIV(*svp) == 0 ) {
414 0           sv_setiv(*svp, (IV)1);
415             }
416             }
417              
418 442           newdepth= pndims;
419              
420             } else {
421 0           croak("av_ndcheck: non-array, non-PDL ref in structure\n\t(this is usually a problem with a pdl() call)");
422             }
423              
424             } else {
425             /* got a scalar (not a ref) */
426 20983           n_scalars++;
427              
428             }
429              
430 23161 100         if (newdepth > depth)
431 764           depth = newdepth;
432             }
433              
434 9397           len++; // convert from funky av_len return value to real count
435              
436 9397 100         if (av_len(dims) >= level && av_fetch(dims, level, 0) != NULL
    100          
437 1712 50         && SvIOK(*(av_fetch(dims, level, 0)))) {
438 1712           oldlen = (PDL_Indx) SvIV(*(av_fetch(dims, level, 0)));
439              
440 1712 100         if (len > oldlen)
441 445           sv_setiv(*(av_fetch(dims, level, 0)), (IV) len);
442             }
443             else
444 7685           av_store(dims,level,newSViv((IV) len));
445              
446             /* We found at least one element -- so pad dims to unity at levels earlier than this one */
447 9397 100         if (n_scalars) {
448 10503 100         for (i=0;i
449 1974           SV **svp = av_fetch(dims, i, 0);
450 1974 100         if (!svp) {
451 630           av_store(dims, i, newSViv((IV)1));
452 1344 50         } else if ( (PDL_Indx)SvIV(*svp) == 0) {
453 0           sv_setiv(*svp, (IV)1);
454             }
455             }
456              
457 8549 100         for (i=level+1; i <= av_len(dims); i++) {
458 20           SV **svp = av_fetch(dims, i, 0);
459 20 50         if (!svp) {
460 0           av_store(dims, i, newSViv((IV)1));
461 20 100         } else if ( (PDL_Indx)SvIV(*svp) == 0) {
462 2           sv_setiv(*svp, (IV)1);
463             }
464             }
465             }
466              
467 9397           return depth;
468             }
469              
470             /* helper function used in pdl_from_array */
471 16           static pdl_datatypes _detect_datatype(AV *av) {
472             SV **item;
473             AV *array;
474             PDL_Indx count, i;
475 16 50         if (!av) return PDL_D;
476 16           count = av_len(av);
477 35 100         for (i = 0; i < count; i++) {
478 19           item = av_fetch(av, i, 0);
479 19 50         if (*item) {
480 19 50         if (SvROK(*item)) {
481 0           array = (AV*)SvRV(*item);
482 0 0         if (_detect_datatype(array) == PDL_D) {
483 0           return PDL_D;
484             }
485             }
486 19 50         if (SvOK(*item) && !SvIOK(*item)) {
    50          
487 0           return PDL_D;
488             }
489             }
490             }
491             #if IVSIZE == 8
492 16           return PDL_LL;
493             #else
494             return PDL_L;
495             #endif
496             }
497              
498             /**********************************************************************
499             * pdl_from_array - dispatcher gets called only by pdl_avref (defined in
500             * Core.xs) - it breaks out to pdl_setav_, below, based on the
501             * type of the destination PDL.
502             */
503 7661           pdl* pdl_from_array(AV* av, AV* dims, pdl_datatypes dtype, pdl* dest_pdl)
504 7661           {
505 7661           PDL_Indx ndims, i, level=0;
506 7661           PDL_Anyval undefval = { PDL_INVALID, {0} };
507 7661           ndims = av_len(dims)+1;
508 7661           PDL_Indx dest_dims[ndims];
509 16006 100         for (i=0; i
510 8345           dest_dims[i] = SvIV(*(av_fetch(dims, ndims-1-i, 0))); /* reverse order */
511             }
512 7661 100         if (dest_pdl == NULL)
513 7659           dest_pdl = pdl_pdlnew();
514 7661 50         if (!dest_pdl) return dest_pdl;
515 7661           pdl_error err = pdl_setdims (dest_pdl, dest_dims, ndims);
516 7661 50         if (err.error) return NULL;
517 7661 100         if (dtype == -1) {
518 16           dtype = _detect_datatype(av);
519             }
520 7661           dest_pdl->datatype = dtype;
521 7661           err = pdl_allocdata (dest_pdl);
522 7661 50         if (err.error) return NULL;
523 7661           err = pdl_make_physical(dest_pdl);
524 7661 50         if (err.error) return NULL;
525             /******
526             * Copy the undefval to fill empty spots in the ndarray...
527             */
528 7661 50         PDLDEBUG_f(printf("pdl_from_array type: %d\n", dtype));
529 7661 50         ANYVAL_FROM_SV(undefval, NULL, TRUE, dtype, FALSE);
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    0          
    50          
    0          
    50          
530             #define X(dtype_dest, ctype_dest, ppsym_dest, ...) \
531             pdl_setav_ ## ppsym_dest(dest_pdl->data,av,dest_dims,ndims,level, undefval.value.ppsym_dest, dest_pdl);
532 7661           PDL_GENERICSWITCH(PDL_TYPELIST_ALL, dtype, X, return NULL)
533             #undef X
534 7661 50         if (dest_pdl->has_badvalue && dest_pdl->badvalue.type != dtype)
    0          
535 0           barf("Badvalue has type=%d != pdltype=%d", dest_pdl->badvalue.type, dtype);
536 7661           return dest_pdl;
537             }
538              
539             /* Compute offset of (x,y,z,...) position in row-major list */
540 25069           PDL_Indx pdl_get_offset(PDL_Indx* pos, PDL_Indx* dims, PDL_Indx *incs, PDL_Indx offset, PDL_Indx ndims) {
541             PDL_Indx i;
542             PDL_Indx result;
543 54395 100         for (i=0; i
544 29326 50         if (pos[i]<-dims[i] || pos[i]>=dims[i])
    50          
545 0           return -1;
546             }
547 25069           result = offset;
548 54395 100         for (i=0; i
549 29326 100         result += (pos[i]+((pos[i]<0)?dims[i]:0))*incs[i];
550             }
551 25069           return result;
552             }
553              
554             /*CORE21 unused*/
555 0           PDL_Anyval pdl_at0( pdl* it ) {
556 0           PDL_Anyval result = { PDL_INVALID, {0} };
557 0 0         if (it->nvals != 1) { return result; }
558 0 0         ANYVAL_FROM_CTYPE_OFFSET(result, it->datatype, PDL_REPRP(it), PDL_REPROFFS(it));
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
559 0           return result;
560             }
561              
562             /*CORE21 unused*/
563 0           PDL_Anyval pdl_at( void* x, pdl_datatypes datatype, PDL_Indx* pos, PDL_Indx* dims,
564             PDL_Indx* incs, PDL_Indx offset, PDL_Indx ndims) {
565 0           PDL_Anyval result = { PDL_INVALID, {0} };
566 0           PDL_Indx ioff = pdl_get_offset(pos, dims, incs, offset, ndims);
567 0 0         if (ioff < 0) return result;
568 0           ANYVAL_FROM_CTYPE_OFFSET(result, datatype, x, ioff);
569 0           return result;
570             }
571              
572             /* Set value at position (x,y,z...) */
573 92           pdl_error pdl_set( void* x, pdl_datatypes datatype, PDL_Indx* pos, PDL_Indx* dims, PDL_Indx* incs, PDL_Indx offs, PDL_Indx ndims, PDL_Anyval value) {
574 92           pdl_error PDL_err = {0, NULL, 0};
575 92           PDL_Indx ioff = pdl_get_offset(pos, dims, incs, offs, ndims);
576 92 50         if (ioff < 0)
577 0           return pdl_make_error_simple(PDL_EUSERERROR, "Position out of range");
578             PDL_Anyval typedval;
579 92           ANYVAL_TO_ANYVAL_NEWTYPE(value, typedval, datatype);
580 92 50         if (typedval.type < 0)
581 0           return pdl_make_error_simple(PDL_EUSERERROR, "Error making typedval");
582 92           ANYVAL_TO_CTYPE_OFFSET(x, ioff, datatype, typedval);
583 92           return PDL_err;
584             }
585              
586             /*
587             * pdl_kludge_copy_ - copy a PDL into a part of a being-formed PDL.
588             * It is only used by pdl_setav_, to handle the case where a PDL is part
589             * of the argument list.
590             *
591             * kludge_copy recursively walks down the dim list of both the source and dest
592             * pdls, copying values in as we go. It differs from PP copy in that it operates
593             * on only a portion of the output pdl.
594             *
595             * (If I were Lazier I would have popped up into the perl level and used broadcastloops to
596             * assign to a slice of the output pdl -- but this is probably a little faster.)
597             *
598             * -CED 17-Jun-2004
599             *
600             * Arguments:
601             * dest_off is an integer indicating which element along the current direction is being treated (for padding accounting)
602             * dest_data is a pointer into the destination PDL's data;
603             * dest_dims is a pointer to the destination PDL's dim list;
604             * ndims is the size of the destination PDL's dimlist;
605             * level is the conjugate dimension along which copying is happening (indexes dest_dims).
606             * "conjugate" means that it counts backward through the dimension array.
607             * stride is the increment in the data array corresponding to this dimension;
608             *
609             * pdl is the input PDL.
610             * plevel is the dim number for the input PDL, which works in the same sense as level.
611             * It is offset to account for the difference in dimensionality between the input and
612             * output PDLs. It is allowed to be negative (which is equivalent to the "permissive
613             * slicing" that treats missing dimensions as present and having size 1), but should
614             * not match or exceed pdl->ndims.
615             * source_data is the current offset data pointer into pdl->data.
616             *
617             * Kludge-copy works backward through the dim lists, so that padding is simpler: if undefval
618             * padding is required at any particular dimension level, the padding occupies a contiguous
619             * block of memory.
620             */
621              
622             #define INNERLOOP_X(datatype, ctype_src, ppsym_src, ...) \
623             /* copy data (unless the source pointer is null) */ \
624             i=0; \
625             if (source_data && dest_data && pdlsiz) { \
626             ctype_src *src_data_typed = source_data; \
627             char found_bad = 0; \
628             if (source_pdl->state & PDL_BADVAL) { \
629             if (source_pdl->has_badvalue && source_pdl->badvalue.type != datatype) \
630             barf("Source badvalue has type=%d != pdltype=%d", source_pdl->badvalue.type, datatype); \
631             ctype_src src_badval_c = source_pdl->has_badvalue ? source_pdl->badvalue.value.ppsym_src : PDL.bvals.ppsym_src; \
632             char src_badval_isnan = PDL_ISNAN_##ppsym_src(src_badval_c); \
633             for (; i
634             if (PDL_ISBAD2(src_data_typed[i], src_badval_c, ppsym_src, src_badval_isnan)) { \
635             dest_data[i] = dest_badval_c; \
636             found_bad = 1; \
637             } else \
638             dest_data[i] = src_data_typed[i]; \
639             } else \
640             for (; i
641             if (found_bad) dest_pdl->state |= PDL_BADVAL; /* just once */ \
642             } else { \
643             /* source_data or dest_data or pdlsiz are 0 */ \
644             if (dest_data) \
645             dest_data[i] = undefval; \
646             } \
647             /* pad out, in the innermost dimension */ \
648             if ( !oob ) { \
649             undef_count += dest_dims[0]-dest_off-i; \
650             for (; i< dest_dims[0]-dest_off; i++) dest_data[i] = undefval; \
651             }
652              
653             #define PDL_KLUDGE_COPY_X(X, datatype_dest, ctype_dest, ppsym_dest, ...) \
654             PDL_Indx pdl_kludge_copy_ ## ppsym_dest(PDL_Indx dest_off, /* Offset into the dest data array */ \
655             ctype_dest* dest_data, /* Data pointer in the dest data array */ \
656             PDL_Indx* dest_dims,/* Pointer to the dimlist for the dest pdl */ \
657             PDL_Indx ndims, /* Number of dimensions in the dest pdl */ \
658             PDL_Indx level, /* Recursion level */ \
659             PDL_Indx stride, /* Stride through memory for the current dim */ \
660             pdl* source_pdl, /* pointer to the source pdl */ \
661             PDL_Indx plevel, /* level within the source pdl */ \
662             void* source_data, /* Data pointer in the source pdl */ \
663             ctype_dest undefval,/* undefval for the dest pdl */ \
664             pdl* dest_pdl /* pointer to the dest pdl */ \
665             ) { \
666             PDL_Indx i; \
667             PDL_Indx undef_count = 0; \
668             /* Can't copy into a level deeper than the number of dims in the output PDL */ \
669             if (level > ndims ) { \
670             fprintf(stderr,"pdl_kludge_copy: level=%"IND_FLAG"; ndims=%"IND_FLAG"\n",level,ndims); \
671             croak("Internal error - please submit a bug report at https://github.com/PDLPorters/pdl/issues:\n pdl_kludge_copy: Assertion failed; ndims-1-level (%"IND_FLAG") < 0!.",ndims-1-level); \
672             } \
673             if (level >= ndims - 1) { \
674             /* We are in as far as we can go in the destination PDL, so direct copying is in order. */ \
675             PDL_Indx pdldim = source_pdl->ndims - 1 - plevel; /* which dim are we working in the source PDL? */ \
676             PDL_Indx pdlsiz; \
677             int oob = (ndims-1-level < 0); /* out-of-bounds flag */ \
678             /* Do bounds checking on the source dimension -- if we wander off the end of the \
679             * dimlist, we are doing permissive-slicing kind of stuff (not enough dims in the \
680             * source to fully account for the output dimlist); if we wander off the beginning, we \
681             * are doing dimensional padding. In either case, we just iterate once. \
682             */ \
683             if (pdldim < 0 || pdldim >= source_pdl->ndims) { \
684             pdldim = (pdldim < 0) ? (0) : (source_pdl->ndims - 1); \
685             pdlsiz = 1; \
686             } else { \
687             pdlsiz = source_pdl->dims[pdldim]; \
688             } \
689             if (dest_pdl->has_badvalue && dest_pdl->badvalue.type != datatype_dest) \
690             barf("Destination badvalue has type=%d != pdltype=%d", dest_pdl->badvalue.type, datatype_dest); \
691             ctype_dest dest_badval_c = dest_pdl->has_badvalue ? dest_pdl->badvalue.value.ppsym_dest : PDL.bvals.ppsym_dest; \
692             PDL_GENERICSWITCH(PDL_TYPELIST_ALL_, source_pdl->datatype, X, croak("Not a known data type code=%d", source_pdl->datatype)) \
693             return undef_count; \
694             } \
695             /* If we are here, we are not at the bottom level yet. So walk \
696             * across this dim and handle copying one dim deeper via recursion. \
697             * The loop is placed in a convenience block so we can define the \
698             * dimensional boundscheck flag -- that avoids having to evaluate the complex \
699             * ternary expression for every loop iteration. \
700             */ \
701             PDL_Indx limit = \
702             (plevel >= 0 && \
703             (source_pdl->ndims - 1 - plevel >= 0) \
704             ) \
705             ? (source_pdl->dims[ source_pdl->ndims-1-plevel ]) \
706             : 1; \
707             for (i=0; i < limit ; i++) \
708             undef_count += pdl_kludge_copy_ ## ppsym_dest(0, dest_data + stride * i, \
709             dest_dims, \
710             ndims, \
711             level+1, \
712             stride / ((dest_dims[ndims-2-level]) ? (dest_dims[ndims-2-level]) : 1), \
713             source_pdl, \
714             plevel+1, \
715             ((PDL_Byte *) source_data) + source_pdl->dimincs[source_pdl->ndims-1-plevel] * i * pdl_howbig(source_pdl->datatype), \
716             undefval, \
717             dest_pdl \
718             ); \
719             if (i >= dest_dims[ndims - 1 - level]) return undef_count; \
720             /* pad the rest of this dim to zero if there are not enough elements in the source PDL... */ \
721             PDL_Indx cursor, target; \
722             cursor = i * stride; \
723             target = dest_dims[ndims-1-level]*stride; \
724             undef_count += target - cursor; \
725             for (; cursor < target; cursor++) dest_data[cursor] = undefval; \
726             return undef_count; \
727             }
728 990 50         PDL_TYPELIST_ALL(PDL_KLUDGE_COPY_X, INNERLOOP_X,)
  34 50          
  288 50          
  36 0          
  2 50          
  556 50          
  10 0          
  0 50          
  0 0          
  0 0          
  0 0          
  2 0          
  12 0          
  4 0          
  42 0          
  4 0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    100          
    50          
    0          
    50          
    0          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    100          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    0          
    50          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    100          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    100          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    0          
    50          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    100          
    50          
    0          
    50          
    0          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    100          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    0          
    50          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    100          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    100          
    100          
    50          
    50          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    100          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    100          
    50          
    50          
    100          
    50          
    0          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    100          
    100          
    100          
    100          
    100          
    50          
    50          
    50          
    0          
    50          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    100          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    0          
    50          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    100          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    0          
    50          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    100          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    0          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    0          
    50          
    50          
    100          
    100          
    0          
    50          
    0          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    0          
    50          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    100          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    0          
    50          
    50          
    0          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    100          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
729             #undef PDL_KLUDGE_COPY_X
730             #undef INNERLOOP_X
731              
732             /*
733             * pdl_setav_ loads a new PDL with values from a Perl AV, another PDL, or
734             * a mix of both. Heterogeneous sizes are handled by padding the new PDL's
735             * values out to size with the undefval. It is only called by pdl_setav in Core.XS,
736             * via the trampoline pdl_from_array just above. pdl_from_array dispatches execution
737             * to pdl_setav_ according to the type of the destination PDL.
738             *
739             * The code is complicated by the "bag-of-stuff" nature of AVs. We handle
740             * Perl scalars, AVs, *and* PDLs (via pdl_kludge_copy).
741             *
742             * - dest_data is the data pointer from a PDL
743             * - av is the array ref (or PDL) to use to fill the data with,
744             * - dest_dims is the dimlist
745             * - ndims is the size of the dimlist
746             * - level is the recursion level, which is also the dimension that we are filling
747             */
748             #define PDL_SETAV_X(datatype_dest, ctype_dest, ppsym_dest, ...) \
749             PDL_Indx pdl_setav_ ## ppsym_dest(ctype_dest* dest_data, AV* av, \
750             PDL_Indx* dest_dims, PDL_Indx ndims, PDL_Indx level, ctype_dest undefval, pdl *dest_pdl) \
751             { \
752             PDL_Indx cursz = dest_dims[ndims-1-level]; /* we go from the highest dim inward */ \
753             PDL_Indx len = av_len(av); \
754             PDL_Indx i,stride=1; \
755             PDL_Indx undef_count = 0; \
756             for (i=0;i
757             stride *= dest_dims[i]; \
758             } \
759             for (i=0;i<=len;i++,dest_data += stride) { /* note len is actually highest index, not element count */ \
760             /* Fetch the next value from the AV */ \
761             SV **elp = av_fetch(av,i,0); \
762             SV *el = (elp ? *elp : 0); \
763             if ( el && SVavref(el) ) { \
764             /* If the element was an AV ref, recurse to walk through that AV, one dim lower */ \
765             undef_count += pdl_setav_ ## ppsym_dest(dest_data, (AV *) SvRV(el), dest_dims, ndims, level+1, undefval, dest_pdl); \
766             \
767             } else if ( el && SvROK(el) ) { \
768             /* If the element was a ref but not an AV, then it should be a PDL */ \
769             pdl *pdl; \
770             if ( !(pdl = pdl_SvPDLV(el)) ) { \
771             /* The element is a non-PDL, non-AV ref. Not allowed. */ \
772             croak("Non-array, non-PDL element in list"); \
773             } \
774             /* The element was a PDL - use pdl_kludge_copy to copy it into the destination */ \
775             pdl_barf_if_error(pdl_make_physical(pdl)); \
776             PDL_Indx pddex = ndims - 2 - level; \
777             PDL_Indx pd = (pddex >= 0 && pddex < ndims ? dest_dims[ pddex ] : 0); \
778             if (!pd) \
779             pd = 1; \
780             undef_count += pdl_kludge_copy_ ## ppsym_dest(0, dest_data,dest_dims,ndims, level+1, stride / pd , pdl, 0, pdl->data, undefval, dest_pdl); \
781             } else { /* el==0 || SvROK(el)==0: this is a scalar or undef element */ \
782             if ( PDL_SV_IS_UNDEF(el) ) { /* undef case */ \
783             *dest_data = (ctype_dest) undefval; \
784             undef_count++; \
785             } else { /* scalar case */ \
786             if (!SvIOK(el)) { /* cf ANYVAL_FROM_SV, COPYCONVERT */ \
787             NV tmp_NV = SvNV(el); \
788             *dest_data = PDL_GENTYPE_IS_UNSIGNED_##ppsym_dest \
789             ? (ctype_dest)(intmax_t) tmp_NV \
790             : (ctype_dest) tmp_NV; \
791             } else if (SvIsUV(el)) { \
792             *dest_data = (ctype_dest) SvUV(el); \
793             } else { \
794             *dest_data = (ctype_dest) SvIV(el); \
795             } \
796             } \
797             /* Pad dim if we are not deep enough */ \
798             if (level < ndims-1) { \
799             ctype_dest *cursor = dest_data; \
800             ctype_dest *target = dest_data + stride; \
801             undef_count += stride; \
802             for ( cursor++; cursor < target; cursor++ ) \
803             *cursor = (ctype_dest)undefval; \
804             } \
805             } \
806             } /* end of element loop through the supplied AV */ \
807             /* in case this dim is incomplete set any remaining elements to the undefval */ \
808             if (len < cursz-1 ) { \
809             ctype_dest *target = dest_data + stride * (cursz - 1 - len); \
810             undef_count += target - dest_data; \
811             for ( ; dest_data < target; dest_data++ ) \
812             *dest_data = (ctype_dest) undefval; \
813             } \
814             /* If the Perl scalar PDL::debug is set, announce padding */ \
815             if (level==0 && undef_count) { \
816             if (SvTRUE(get_sv("PDL::debug",0))) { \
817             fflush(stdout); \
818             fprintf(stderr,"Warning: pdl_setav_" #ppsym_dest " converted undef to $PDL::undefval (%g) %"IND_FLAG" time%s\\n",(double)undefval,undef_count,undef_count==1?"":"s"); \
819             fflush(stderr); \
820             } \
821             } \
822             return undef_count; \
823             }
824              
825 33495 100         PDL_TYPELIST_ALL(PDL_SETAV_X,)
  72 50          
  544 50          
  89 100          
  51 100          
  11853 50          
  1234 100          
  221 50          
  16 50          
  655 0          
  10 50          
  17939 50          
  115 50          
  96 50          
  586 0          
  14 0          
    0          
    50          
    50          
    50          
    0          
    100          
    50          
    0          
    100          
    50          
    0          
    0          
    100          
    50          
    50          
    100          
    100          
    50          
    100          
    50          
    50          
    0          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    100          
    50          
    50          
    0          
    100          
    50          
    0          
    100          
    50          
    0          
    0          
    100          
    50          
    50          
    100          
    100          
    50          
    100          
    50          
    50          
    0          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    50          
    50          
    50          
    0          
    100          
    50          
    0          
    100          
    50          
    0          
    0          
    100          
    50          
    50          
    100          
    100          
    50          
    100          
    50          
    50          
    0          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    100          
    50          
    50          
    0          
    100          
    50          
    0          
    100          
    50          
    0          
    0          
    100          
    50          
    50          
    100          
    100          
    50          
    100          
    50          
    100          
    50          
    100          
    50          
    50          
    100          
    100          
    100          
    50          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
    0          
    100          
    50          
    50          
    100          
    100          
    50          
    100          
    50          
    50          
    0          
    50          
    50          
    50          
    100          
    50          
    0          
    0          
    100          
    50          
    50          
    0          
    100          
    100          
    100          
    100          
    100          
    50          
    0          
    100          
    50          
    50          
    100          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    0          
    0          
    0          
    50          
    100          
    50          
    0          
    100          
    50          
    0          
    100          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    0          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    0          
    0          
    0          
    50          
    50          
    50          
    0          
    100          
    50          
    0          
    50          
    50          
    0          
    0          
    100          
    50          
    50          
    100          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    100          
    50          
    50          
    0          
    100          
    50          
    50          
    0          
    100          
    50          
    0          
    100          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    0          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    0          
    0          
    0          
    50          
    50          
    50          
    0          
    100          
    50          
    0          
    50          
    50          
    0          
    0          
    100          
    50          
    50          
    100          
    100          
    50          
    100          
    50          
    50          
    0          
    50          
    50          
    50          
    100          
    50          
    100          
    50          
    100          
    50          
    50          
    0          
    100          
    50          
    0          
    100          
    100          
    50          
    0          
    100          
    50          
    50          
    100          
    100          
    50          
    100          
    50          
    50          
    0          
    50          
    50          
    50          
    100          
    50          
    50          
    0          
    100          
    50          
    50          
    0          
    100          
    50          
    0          
    100          
    50          
    0          
    0          
    100          
    50          
    50          
    100          
    100          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    0          
    100          
    50          
    100          
    100          
    100          
    50          
    0          
    100          
    100          
    50          
    0          
    100          
    50          
    50          
    100          
    100          
    50          
    100          
    50          
    50          
    0          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    50          
    50          
    50          
    0          
    100          
    50          
    0          
    100          
    50          
    0          
    0          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    50          
    0          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    50          
    50          
    50          
    0          
    100          
    50          
    0          
    50          
    50          
    0          
    0          
826             #undef PDL_SETAV_X
827              
828 4794           SV *pdl_hdr_copy(SV *hdrp) {
829             /* call the perl routine _hdr_copy */
830 4794           dSP;
831 4794           ENTER;
832 4794           SAVETMPS;
833 4794 50         PUSHMARK(SP);
834 4794 50         XPUSHs( hdrp );
835 4794           PUTBACK;
836 4794           int count = call_pv("PDL::_hdr_copy",G_SCALAR);
837 4794           SPAGAIN;
838 4794 50         if (count != 1)
839 0           croak("PDL::_hdr_copy didn\'t return a single value - please report this bug (B).");
840 4794           SV *retval = (SV *) POPs ;
841 4794 50         if (SvROK(retval))
842 4794           (void)SvREFCNT_inc(retval);
843 4794 50         FREETMPS;
844 4794           LEAVE;
845 4794           return retval;
846             }
847              
848             /*
849             examine the various PDLs that form the output PDL,
850             and copy headers as necessary. The first header found with the hdrcpy
851             bit set is used. This used to do just a simple ref copy but now
852             it uses the perl routine PDL::_hdr_copy to do the dirty work. That
853             routine makes a deep copy of the header. Copies of the deep copy
854             are distributed to all the names of the ndarray that are not the source
855             of the header. I believe that is the Right Thing to do but I could be
856             wrong.
857             Here's the flow:
858             - Check the hdrcpy flag. If it's set, then check the header
859             to see if it exists. If it does, we need to call the
860             perl-land PDL::_hdr_copy routine. There are some shenanigans
861             to keep the return value from evaporating before we've had a
862             chance to do our bit with it.
863             - For each output argument in the function signature, try to put
864             a reference to the new header into that argument's header slot.
865             (For functions with multiple outputs, this produces multiple linked
866             headers -- that could be Wrong; fixing it would require making
867             yet more explicit copies!)
868             - Remortalize the return value from PDL::_hdr_copy, so that we don't
869             leak memory.
870             --CED 12-Apr-2003
871             */
872 87772           void pdl_hdr_childcopy(pdl_trans *trans) {
873 87772           void *hdrp = NULL;
874 87772           char propagate_hdrcpy = 0;
875 87772           pdl_transvtable *vtable = trans->vtable;
876 87772           pdl **pdls = trans->pdls;
877             PDL_Indx i;
878 267950 100         for (i=0; inpdls; i++) {
879 184972           pdl *pdl = pdls[i];
880 184972           short flags = vtable->par_flags[i];
881 184972 100         if (!(flags & PDL_PARAM_ISTEMP) && (!(flags & PDL_PARAM_ISCREAT) ||
    100          
882 77936 50         ((flags & PDL_PARAM_ISCREAT) && !PDL_DIMS_FROM_TRANS(trans,pdl))) &&
    100          
    100          
883 114394 100         pdl->hdrsv && (pdl->state & PDL_HDRCPY)
    100          
884             ) {
885 4794           hdrp = pdl->hdrsv;
886 4794           propagate_hdrcpy = ((pdl->state & PDL_HDRCPY) != 0);
887 4794           break;
888             }
889             }
890 87772 100         if (!hdrp) return;
891 4794 50         SV *hdr_copy = ((hdrp == &PL_sv_undef) ? &PL_sv_undef : pdl_hdr_copy(hdrp));
892             /* Found the header -- now copy it into all the right places */
893 16705 100         for (i=0; inpdls; i++) {
894 11911           pdl *pdl = pdls[i];
895 11911           short flags = vtable->par_flags[i];
896 11911 100         if (!(flags & PDL_PARAM_ISCREAT)) continue;
897 4795 100         if (pdl->hdrsv != hdrp) {
898 4785 100         if (pdl->hdrsv && pdl->hdrsv != &PL_sv_undef)
    50          
899 1152           (void)SvREFCNT_dec( pdl->hdrsv );
900 4785 50         if (hdr_copy != &PL_sv_undef) (void)SvREFCNT_inc(hdr_copy);
901 4785           pdl->hdrsv = hdr_copy;
902             }
903 4795 50         if (propagate_hdrcpy) pdl->state |= PDL_HDRCPY;
904             }
905 4794 50         if (hdr_copy != &PL_sv_undef)
906 4794           SvREFCNT_dec(hdr_copy); /* make hdr_copy mortal again */
907             }
908              
909 0           void pdl_dump_slice_args(pdl_slice_args* args) {
910 0           printf("slice_args (%p):\n", args);
911 0 0         while (args) {
912 0           printf(" start=%"IND_FLAG", end=%"IND_FLAG", inc=%"IND_FLAG", squish=%d, dummy=%d, next=%p\n",
913 0           args->start, args->end, args->inc, args->squish, args->dummy, args->next
914             );
915 0           args = args->next;
916             }
917 0           }
918              
919             /****************************************************************/
920             /*** String handling part of slice is here. Parse out each ***/
921             /*** term: ***/
922             /*** (or NV) - extract one element from this dim ***/
923             /*** : - extract to ; autoreverse if nec. ***/
924             /*** :: - extract to , stepping by ***/
925             /*** () - extract element and discard this dim ***/
926             /*** * - insert a dummy dimension of size ***/
927             /*** : - keep this dim in its entirety ***/
928             /*** X - keep this dim in its entirety ***/
929             /****************************************************************/
930 6671           pdl_error pdl_slice_args_parse_string(char* s, pdl_slice_args *retvalp) {
931 6671 50         PDLDEBUG_f(printf("slice_args_parse_string input: '%s'\n", s));
932 6671           pdl_error PDL_error = {0, NULL, 0};
933 6671           int subargno = 0;
934 6671           char flagged = 0;
935 6671           char squish_closed = 0, squish_flag = 0, dummy_flag = 0;
936 6671           pdl_slice_args this_arg = {0,-1,0}; /* start,end,inc 0=do in RedoDims */
937 6671           PDL_Indx i = 0;
938 23731 100         while(*s) {
939 17060 100         if ( isspace( *s ) ) {
940 5           s++; /* ignore and loop again */
941 5           continue;
942             }
943             /* not whitespace */
944 17055           switch(*(s++)) {
945 626           case '*':
946 626 50         if (flagged || subargno)
    50          
947 0           return pdl_make_error(PDL_EUSERERROR, "slice: Erroneous '*' (arg %d)",i);
948 626           dummy_flag = flagged = 1;
949 626           this_arg.start = 1; /* default this number to 1 (size 1); '*0' yields an empty */
950 626           this_arg.end = 1; /* no second arg allowed - default to 1 so start is element count */
951 626           this_arg.inc = -1; /* -1 so we count down to end from start */
952 626           break;
953 1455           case '(':
954 1455 50         if (flagged || subargno)
    50          
955 0           return pdl_make_error(PDL_EUSERERROR, "slice: Erroneous '(' (arg %d)",i);
956 1455           squish_flag = flagged = 1;
957 1455           break;
958 17           case 'X': case 'x':
959 17 50         if (flagged || subargno > 1)
    50          
960 0           return pdl_make_error(PDL_EUSERERROR, "slice: Erroneous 'X' (arg %d)",i);
961 17 50         if (subargno==0) {
962 17           flagged = 1;
963             } else /* subargno is 1 - squish */ {
964 0           squish_flag = squish_closed = flagged = 1;
965             }
966 17           break;
967 9458           case '+': case '-':
968             case '0': case '1': case '2': case '3': case '4':
969             case '5': case '6': case '7': case '8': case '9':
970 9458           switch(subargno) {
971 5846           case 0: /* first arg - change default to 1 element */
972 5846           this_arg.end = this_arg.start = strtoll(--s, &s, 10);
973 5846 100         if (dummy_flag)
974 624           this_arg.start = 1;
975 5846           break;
976 3591           case 1: /* second arg - parse and keep end */
977 3591           this_arg.end = strtoll(--s, &s, 10);
978 3591           break;
979 21           case 2: /* third arg - parse and keep inc */
980 21 50         if ( squish_flag || dummy_flag )
    50          
981 0           return pdl_make_error(PDL_EUSERERROR, "slice: erroneous third field in slice specifier (arg %d)",i);
982 21           this_arg.inc = strtoll(--s, &s, 10);
983 21           break;
984 0           default: /* oops */
985 0           return pdl_make_error(PDL_EUSERERROR, "slice: too many subargs in scalar slice specifier %d",i);
986             break;
987             }
988 9458           break;
989 1455           case ')':
990 1455 50         if ( squish_closed || !squish_flag || subargno > 0)
    50          
    50          
991 0           return pdl_make_error(PDL_EUSERERROR, "slice: erroneous ')' (arg %d)",i);
992 1455           squish_closed = 1;
993 1455           break;
994 4044           case ':':
995 4044 50         if (squish_flag && !squish_closed)
    0          
996 0           return pdl_make_error(PDL_EUSERERROR, "slice: must close squishing parens (arg %d)",i);
997 4044 100         if ( subargno == 0 )
998 4023           this_arg.end = -1; /* Set ":" default to get the rest of the range */
999 4044 50         if ( subargno > 1 )
1000 0           return pdl_make_error(PDL_EUSERERROR, "slice: too many ':'s in scalar slice specifier %d",i);
1001 4044           subargno++;
1002 4044           break;
1003 0           case ',':
1004 0           return pdl_make_error_simple(PDL_EUSERERROR, "slice: ',' not allowed (yet) in scalar slice specifiers!");
1005             break;
1006 0           default:
1007 0           return pdl_make_error(PDL_EUSERERROR, "slice: unexpected '%c' in slice specifier (arg %d)",*s,i);
1008             break;
1009             }
1010 17055           i++;
1011             } /* end of parse loop */
1012 6671           this_arg.squish = squish_flag;
1013 6671           this_arg.dummy = dummy_flag;
1014 6671 50         PDLDEBUG_f(pdl_dump_slice_args(&this_arg));
1015 6671           *retvalp = this_arg;
1016 6671           return PDL_error;
1017             }
1018              
1019 7651           pdl_slice_args* pdl_slice_args_parse_sv(SV* sv) {
1020             /*** Make sure we got an array ref as input and extract its corresponding AV ***/
1021 7651 50         if (!(sv && SvROK(sv) && SvTYPE(SvRV(sv))==SVt_PVAV))
    50          
    50          
1022 0           barf("slice requires an ARRAY ref containing zero or more arguments");
1023 7651           pdl_slice_args* retval = NULL, *this_arg_ptr = NULL;
1024 7651           AV *arglist = (AV *)(SvRV(sv));
1025             /* Detect special case of a single comma-delimited string; in that case, */
1026             /* split out our own arglist. */
1027 7651 100         if (av_len(arglist) == 0) {
1028             /*** single-element list: pull first element ***/
1029 7596           SV **svp = av_fetch(arglist, 0, 0);
1030 7596 50         if (svp && *svp && *svp != &PL_sv_undef && SvPOKp(*svp)) {
    50          
    50          
    100          
1031             /*** The element exists and is not undef and has a cached string value ***/
1032             char *s,*ss;
1033 5333           s = ss = SvPVbyte_nolen(*svp);
1034 23573 100         for (; *ss && *ss != ','; ss++) {}
    100          
1035 5333 100         if (*ss == ',') {
1036             char *s1;
1037             /* the string contains at least one comma. ATTACK! */
1038             /* We make a temporary array and populate it with */
1039             /* SVs containing substrings -- basically split(/\,/)... */
1040 1160           AV *al = (AV *)sv_2mortal((SV *)(newAV()));
1041             do {
1042 7553 100         for (s1=s; *s1 && *s1 != ','; s1++);
    100          
1043 2463           av_push(al, newSVpvn(s, s1-s));
1044 2463 100         s = (*s1==',') ? ++s1 : s1;
1045 2463 100         } while(*s);
1046 1160           arglist = al; /* al is ephemeral and will evaporate at the next perl gc */
1047             } /* end of contains-comma case */
1048             } /* end of nontrivial single-element detection */
1049             }/* end of single-element detection */
1050 7651           PDL_Indx nargs = av_len( arglist ) + 1;
1051             /**********************************************************************/
1052             /**** Loop over the elements of the AV input and parse into values ****/
1053             /**** in the start/inc/end array ****/
1054             PDL_Indx i;
1055 16656 100         for (i=0; i
1056 9005           char all_flag = 0;
1057 9005           pdl_slice_args this_arg = {0,-1,0}; /* start,end,inc 0=do in RedoDims */
1058 9005           SV **thisp = av_fetch( arglist, i, 0 );
1059 9005 50         SV *this = (thisp ? *thisp : 0 );
1060             /** Keep the whole dimension if the element is undefined or missing **/
1061 9005 50         all_flag = ( (!this) || (this==&PL_sv_undef) );
    50          
1062 9005 50         if (!all_flag) {
1063             /* Main branch -- this element is not an empty string */
1064 9005 100         if (SvROK(this)) {
1065             /*** It's a reference - it better be an array ref. ***/
1066 119 50         if ( SvTYPE(SvRV(this)) != SVt_PVAV )
1067 0           barf("slice: non-ARRAY ref in the argument list!");
1068             /*** It *is* an array ref! Expand it into an AV so we can read it. ***/
1069 119           AV *sublist = (AV *)(SvRV(this));
1070 119 50         PDL_Indx nelem = !sublist ? 0 : av_len(sublist) + 1;
1071 119 50         if (nelem > 3) barf("slice: array refs can have at most 3 elements!");
1072 119 100         if (nelem==0) { /* No elements - keep it all */
1073 13           all_flag = 1;
1074             } else /* Got at least one element */{
1075             /* Load the first into start and check for dummy or all-clear */
1076             /* (if element is missing use the default value already in start) */
1077 106           SV **svp = av_fetch(sublist, 0, 0);
1078 106 50         if (svp && *svp && *svp != &PL_sv_undef) {
    50          
    50          
1079             /* There is a first element. Check if it's a string, then an IV */
1080 106 50         if ( SvPOKp(*svp)) {
1081 0           char *str = SvPVbyte_nolen(*svp);
1082 0           switch(*str) {
1083 0           case 'X':
1084 0           all_flag = 1; break;
1085 0           case '*':
1086 0           this_arg.dummy = 1;
1087 0           this_arg.start = 1; /* start is 1 so 2nd field is element count */
1088 0           this_arg.end = 1; /* size defaults to 1 for dummy dims */
1089 0           this_arg.inc = 1; /* inc is forced to 1 so ['*',0] gives an empty */
1090 0           break;
1091 0           default: /* Doesn't start with '*' or 'X' */
1092 0           this_arg.end = this_arg.start = SvIV(*svp); /* end defaults to start if start is present */
1093 0           break;
1094             }
1095             } else /* the element has no associated string - just parse */ {
1096 106           this_arg.end = this_arg.start = SvIV(*svp); /* end defaults to start if start is present */
1097             }
1098             } /* end of defined check. if it's undef, leave the n's at their default value. */
1099             /* Read the second element into end and check for alternate squish syntax */
1100 106 100         if ( (nelem > 1) && (!all_flag) ) {
    50          
1101 102           svp = av_fetch(sublist, 1, 0);
1102 102 50         if ( svp && *svp && *svp != &PL_sv_undef ) {
    50          
    50          
1103 102 50         if ( SvPOKp(*svp) ) {
1104             /* Second element has a string - make sure it's not 'X'. */
1105 0           char *str = SvPVbyte_nolen(*svp);
1106 0 0         if (*str == 'X') {
1107 0           this_arg.squish = 1;
1108 0           this_arg.end = this_arg.start;
1109             } else {
1110 0           this_arg.end = SvIV(*svp);
1111             }
1112             } else {
1113             /* Not a PDL, no string -- just get the IV */
1114 102           this_arg.end = SvIV(*svp);
1115             }
1116             } /* If not defined, leave at the default */
1117             } /* End of second-element check */
1118             /*** Now try to read the third element (inc). ***/
1119 106 100         if ((nelem > 2) && !(all_flag) && !(this_arg.squish) && !(this_arg.dummy)) {
    50          
    50          
    50          
1120 32           svp = av_fetch(sublist, 2, 0);
1121 32 50         if ( svp && *svp && *svp != &PL_sv_undef ) {
    50          
    50          
1122             STRLEN len;
1123 32           SvPV( *svp, len );
1124 32 50         if (len>0) { /* nonzero length -> actual value given */
1125 32           this_arg.inc = SvIV(*svp); /* if the step is passed in as 0, it is a squish */
1126 32 100         if (this_arg.inc==0) {
1127 29           this_arg.end = this_arg.start;
1128 29           this_arg.squish = 1;
1129             }
1130             }
1131             } /* end of nontrivial third-element parsing */
1132             } /* end of third-element parsing */
1133             } /* end of nontrivial sublist parsing */
1134             } else /* this argument is not an ARRAY ref - parse as a scalar */ {
1135 8886 100         if (SvPOKp(this)) {
1136             /* this argument has a cached string */
1137             STRLEN len;
1138 6671           char *s = SvPVbyte(this, len);
1139 6671           pdl_barf_if_error(pdl_slice_args_parse_string(s, &this_arg));
1140             } else /* end of string parsing */ {
1141             /* Simplest case -- there's no cached string, so it */
1142             /* must be a number. In that case it's a simple */
1143             /* extraction. Treated as a separate case for speed. */
1144 2215           this_arg.end = this_arg.start = SvNV(this);
1145 2215           this_arg.inc = 0;
1146             }
1147             } /* end of scalar handling */
1148             } /* end of defined-element handling (!all_flag) */
1149 9005 50         if ( (!all_flag) + (!this_arg.squish) + (!this_arg.dummy) < 2 )
1150 0           barf("Looks like you triggered a bug in slice. two flags set in dim %d",i);
1151             /* Force all_flag case to be a "normal" slice */
1152 9005 100         if (all_flag) {
1153 13           this_arg.start = 0;
1154 13           this_arg.end = -1;
1155 13           this_arg.inc = 1;
1156             }
1157 9005 100         if (!retval)
1158 7646           this_arg_ptr = retval = pdl_smalloc(sizeof(*retval));
1159             else {
1160 1359           this_arg_ptr = this_arg_ptr->next = pdl_smalloc(sizeof(*retval));
1161             }
1162 9005 50         if (!this_arg_ptr) croak("Out of Memory\n");
1163             /* Copy parsed values into the limits */
1164 9005           *this_arg_ptr = this_arg;
1165             } /* end of arg-parsing loop */
1166 7651 50         PDLDEBUG_f(pdl_dump_slice_args(retval));
1167 7651           return retval;
1168             }
1169              
1170             /* pdl_seed() - prefix as "seed" #define-d by Perl
1171             *
1172             * Used to seed PDL's built-in RNG.
1173             */
1174 5           uint64_t pdl_pdl_seed(void) {
1175             /* This implementation is from section 7.1 Seeding of
1176             *
1177             * Helmut G. Katzgraber. "Random Numbers in Scientific Computing:
1178             * An Introduction". .
1179             */
1180             uint64_t s, pid;
1181             /* Start of Perl-specific symbols */
1182             Time_t seconds;
1183 5           pid = (uint64_t)PerlProc_getpid();
1184 5           (void)time(&seconds);
1185             /* End of Perl-specific symbols */
1186 5           s = (uint64_t)seconds;
1187 5           return ((s*181)*((pid-83)*359))%104729;
1188             }
1189              
1190             /* Pack strings array - returns strings[] (pdl_smalloced) and nstrings */
1191 0           char ** pdl_packstrings ( SV* sv, PDL_Indx *nstrings ) {
1192 0 0         if (!(SvROK(sv) && SvTYPE(SvRV(sv))==SVt_PVAV)) /* Test */
    0          
1193 0           return NULL;
1194 0           AV *array = (AV *) SvRV(sv); /* dereference */
1195 0           *nstrings = (PDL_Indx) av_len(array) + 1; /* Number of entities */
1196 0           char **strings = pdl_smalloc( (*nstrings) * sizeof(*strings) ); /* Array space */
1197 0 0         if (strings == NULL) return NULL;
1198             PDL_Indx i;
1199 0 0         for (i=0; i<(*nstrings); i++) {
1200 0           strings[i] = SvPV_nolen(*(av_fetch( array, i, 0 )));
1201             }
1202 0           return strings;
1203             }