File Coverage

lib/PDL/Slices-pp-slice.c
Criterion Covered Total %
statement 22 22 100.0
branch 9 12 75.0
condition n/a
subroutine n/a
pod n/a
total 31 34 91.1


line stmt bran cond sub pod time code
1              
2             #line 453 "lib/PDL/PP.pm"
3             /*
4             * THIS FILE WAS GENERATED BY PDL::PP from lib/PDL/Slices.pd! Do not modify!
5             */
6              
7             #define PDL_FREE_CODE(trans, destroy, comp_free_code, ntpriv_free_code) \
8             if (destroy) { \
9             comp_free_code \
10             } \
11             if ((trans)->dims_redone) { \
12             ntpriv_free_code \
13             }
14              
15             #include "EXTERN.h"
16             #include "perl.h"
17             #include "XSUB.h"
18             #include "pdl.h"
19             #include "pdlcore.h"
20             #define PDL PDL_Slices
21             extern Core* PDL; /* Structure hold core C functions */
22              
23             #line 1846 "lib/PDL/PP.pm"
24             typedef struct pdl_params_slice {
25             #line 26 "lib/PDL/Slices-pp-slice.c"
26             pdl_slice_args *arglist;
27             PDL_Indx nargs;
28             PDL_Indx *odim;
29             PDL_Indx *idim;
30             PDL_Indx idim_top;
31             PDL_Indx odim_top;
32             PDL_Indx *start;
33             PDL_Indx *inc;
34             PDL_Indx *end;
35             } pdl_params_slice;
36              
37              
38             #line 1857 "lib/PDL/PP.pm"
39             pdl_error pdl_slice_redodims(pdl_trans *__privtrans) {
40             pdl_error PDL_err = {0, NULL, 0};
41             #line 42 "lib/PDL/Slices-pp-slice.c"
42 7539           pdl_params_slice *__params = __privtrans->params; (void)__params;
43 7539           pdl *__it = __privtrans->pdls[1]; (void) __it;
44 7539           PDL->hdr_childcopy(__privtrans); __privtrans->dims_redone = 1;
45              
46             #line 2367 "lib/PDL/Slices.pd"
47             PDL_Indx i;
48             PDL_Indx o_ndims_extra = PDLMAX(0, __privtrans->pdls[0]->ndims - __params->idim_top);
49              
50             /* slurped dims from the arg parsing, plus any extra broadcast dims */
51             PDL_RETERROR(PDL_err, PDL->reallocdims(__it,__params->odim_top + o_ndims_extra));;
52             __privtrans->incs = malloc(sizeof(*__privtrans->incs) * __privtrans->pdls[1]->ndims); /* CType.get_malloc */
53             ;
54             __privtrans->offs = 0; /* Offset vector to start of slice */
55              
56             for(i=0; i<__params->nargs; i++) {
57             /** Belt-and-suspenders **/
58             if ((__params->idim[i] < 0) && (__params->odim[i] < 0))
59             return PDL->make_error(PDL_EUSERERROR, "Error in slice:" "Hmmm, both dummy and squished -- this can never happen. I quit.");
60              
61             /** First handle dummy dims since there's no input from the parent **/
62             if (__params->idim[i] < 0) {
63             /* dummy dim - offset or diminc. */
64             __privtrans->pdls[1]->dims[ __params->odim[i] ] = __params->end[i] - __params->start[i] + 1;
65             __privtrans->incs[ __params->odim[i] ] = 0;
66             } else {
67             /** This is not a dummy dim -- deal with a regular slice along it. **/
68             /** Get parent dim size for this idim, and/or allow permissive slicing **/
69             PDL_Indx pdsize = __params->idim[i] < __privtrans->pdls[0]->ndims ?
70             __privtrans->pdls[0]->dims[__params->idim[i]] : 1;
71             PDL_Indx start = __params->start[i];
72             PDL_Indx end = __params->end[i];
73             if (
74             /** Trap special case: full slices of an empty dim are empty **/
75             (pdsize==0 && start==0 && end==-1 && (__params->inc[i] == 0 || __params->inc[i] == 1))
76             ||
77             /* the values given when PDL::slice gets empty ndarray for index */
78             (start==1 && end==0 && __params->inc[i] == 1)
79             ) {
80             __privtrans->pdls[1]->dims[__params->odim[i]] = 0;
81             __privtrans->incs[__params->odim[i]] = 0;
82             } else {
83             /** Regularize and bounds-check the start location **/
84             if (start < 0)
85             start += pdsize;
86             if (start < 0 || start >= pdsize) {
87             if (i >= __privtrans->pdls[0]->ndims) {
88             return PDL->make_error(PDL_EUSERERROR, "Error in slice:" "slice has too many dims (indexes dim %"IND_FLAG"; highest is %"IND_FLAG")",i,__privtrans->pdls[0]->ndims-1);
89             } else {
90             return PDL->make_error(PDL_EUSERERROR, "Error in slice:" "slice starts out of bounds in pos %"IND_FLAG" (start is %"IND_FLAG"; end is %"IND_FLAG"; inc is %"IND_FLAG"; source dim %"IND_FLAG" runs 0 to %"IND_FLAG")",i,start,end,__params->inc[i],__params->idim[i],pdsize-1);
91             }
92             }
93             if (__params->odim[i] < 0) {
94             /* squished dim - just update the offset. */
95             /* start is always defined and regularized if we are here here, since */
96             /* both idim[i] and odim[i] can't be <0 */
97             __privtrans->offs += start * __privtrans->pdls[0]->dimincs[ __params->idim[i] ];
98             } else /* normal operation */ {
99             /** Regularize and bounds-check the end location **/
100             if (end<0) end += pdsize;
101             if (end < 0 || end >= pdsize)
102             return PDL->make_error(PDL_EUSERERROR, "Error in slice:" "slice ends out of bounds in pos %"IND_FLAG" (end is %"IND_FLAG"; source dim %"IND_FLAG" runs 0 to %"IND_FLAG")",i,end,__params->idim[i],pdsize-1);
103             /* regularize inc */
104             PDL_Indx inc = __params->inc[i];
105             if (!inc)
106             inc = (start <= end) ? 1 : -1;
107             __privtrans->pdls[1]->dims[ __params->odim[i] ] = PDLMAX(0, (end - start + inc) / inc);
108             __privtrans->incs[ __params->odim[i] ] = __privtrans->pdls[0]->dimincs[ __params->idim[i] ] * inc;
109             __privtrans->offs += start * __privtrans->pdls[0]->dimincs[ __params->idim[i] ];
110             } /* end of normal slice case */
111             } /* end of trapped strange slice case */
112             } /* end of non-dummy slice case */
113             } /* end of nargs loop */
114              
115             /* Now fill in broadcast dimensions as needed. idim and odim persist from the parsing loop */
116             /* up above. */
117             for(i=0; i
118             __privtrans->pdls[1]->dims[ __params->odim_top + i ] = __privtrans->pdls[0]->dims[ __params->idim_top + i ];
119             __privtrans->incs[ __params->odim_top + i ] = __privtrans->pdls[0]->dimincs[ __params->idim_top + i ];
120             }
121              
122             PDL_RETERROR(PDL_err, PDL->setdims_careful(__it));;
123             #line 124 "lib/PDL/Slices-pp-slice.c"
124 7487           return PDL_err;
125             }
126              
127              
128             #line 1857 "lib/PDL/PP.pm"
129             pdl_error pdl_slice_free(pdl_trans *__privtrans, char destroy) {
130             pdl_error PDL_err = {0, NULL, 0};
131             #line 132 "lib/PDL/Slices-pp-slice.c"
132 7685           pdl_params_slice *__params = __privtrans->params; (void)__params;
133 7685           pdl *__it = __privtrans->pdls[1]; (void) __it;
134 7685 100         PDL_FREE_CODE(__privtrans, destroy, free(__params->odim); /* CType.get_free */
    100          
135             free(__params->idim); /* CType.get_free */
136             free(__params->start); /* CType.get_free */
137             free(__params->inc); /* CType.get_free */
138             free(__params->end); /* CType.get_free */
139             , free(__privtrans->incs); /* CType.get_free */
140 7685           ) return PDL_err;
141             }
142              
143             static pdl_datatypes pdl_slice_vtable_gentypes[] = { PDL_SB, PDL_B, PDL_S, PDL_US, PDL_L, PDL_UL, PDL_IND, PDL_ULL, PDL_LL, PDL_F, PDL_D, PDL_LD, PDL_CF, PDL_CD, PDL_CLD, -1 };
144             static PDL_Indx pdl_slice_vtable_realdims[] = { 0, 0 };
145             static char *pdl_slice_vtable_parnames[] = { "PARENT","CHILD" };
146             static short pdl_slice_vtable_parflags[] = {
147             0,
148             PDL_PARAM_ISCREAT|PDL_PARAM_ISCREATEALWAYS|PDL_PARAM_ISOUT|PDL_PARAM_ISWRITE
149             };
150             static pdl_datatypes pdl_slice_vtable_partypes[] = { -1, -1 };
151             static PDL_Indx pdl_slice_vtable_realdims_starts[] = { 0, 0 };
152             static PDL_Indx pdl_slice_vtable_realdims_ind_ids[] = { 0 };
153             static char *pdl_slice_vtable_indnames[] = { "" };
154             pdl_transvtable pdl_slice_vtable = {
155             0, PDL_ITRANS_ISAFFINE|PDL_ITRANS_TWOWAY|PDL_ITRANS_DO_DATAFLOW_ANY, pdl_slice_vtable_gentypes, 1, 2, NULL /*CORE21*/,
156             pdl_slice_vtable_realdims, pdl_slice_vtable_parnames,
157             pdl_slice_vtable_parflags, pdl_slice_vtable_partypes,
158             pdl_slice_vtable_realdims_starts, pdl_slice_vtable_realdims_ind_ids, 0,
159             0, pdl_slice_vtable_indnames,
160             pdl_slice_redodims, NULL, NULL,
161             pdl_slice_free,
162             sizeof(pdl_params_slice),"PDL::Slices::slice"
163             };
164              
165              
166 7651           pdl_error pdl_run_slice(pdl *PARENT,pdl *CHILD,pdl_slice_args *arglist) {
167 7651           pdl_error PDL_err = {0, NULL, 0};
168 7651 50         if (!PDL) return (pdl_error){PDL_EFATAL, "PDL core struct is NULL, can't continue",0};
169 7651           pdl_trans *__privtrans = PDL->create_trans(&pdl_slice_vtable);
170 7651 50         if (!__privtrans) return PDL->make_error_simple(PDL_EFATAL, "Couldn't create trans");
171 7651           pdl_params_slice *__params = __privtrans->params;
172 7651           __privtrans->pdls[0] = PARENT;
173 7651           __privtrans->pdls[1] = CHILD;
174 7651 50         PDL_RETERROR(PDL_err, PDL->type_coerce(__privtrans));
175 7651           PARENT = __privtrans->pdls[0];
176 7651           CHILD = __privtrans->pdls[1];
177 7651           (__params->arglist) = (arglist); /* CType.get_copy */
178              
179              
180             #line 2346 "lib/PDL/Slices.pd"
181             PDL_Indx nargs = 0;
182             pdl_slice_args *argsptr = arglist;
183             while (argsptr) nargs++, argsptr = argsptr->next;
184             __params->nargs = nargs;
185             __params->odim = malloc(sizeof(*__params->odim) * __params->nargs); /* CType.get_malloc */
186             __params->idim = malloc(sizeof(*__params->idim) * __params->nargs); /* CType.get_malloc */
187             __params->start = malloc(sizeof(*__params->start) * __params->nargs); /* CType.get_malloc */
188             __params->inc = malloc(sizeof(*__params->inc) * __params->nargs); /* CType.get_malloc */
189             __params->end = malloc(sizeof(*__params->end) * __params->nargs); /* CType.get_malloc */
190             ;
191             PDL_Indx i, idim, odim;
192             argsptr = arglist;
193             for(odim=idim=i=0; i
194             /* Copy parsed values into the limits */
195             __params->start[i] = argsptr->start;
196             __params->end[i] = argsptr->end;
197             __params->inc[i] = argsptr->inc;
198             /* Deal with dimensions */
199             __params->odim[i] = argsptr->squish ? -1 : odim++;
200             __params->idim[i] = argsptr->dummy ? -1 : idim++;
201             argsptr = argsptr->next;
202             } /* end of arg-parsing loop */
203             __params->idim_top = idim;
204             __params->odim_top = odim;
205             #line 206 "lib/PDL/Slices-pp-slice.c"
206 7651 100         PDL_RETERROR(PDL_err, PDL->make_trans_mutual(__privtrans));
207 7650           return PDL_err;
208             }