55 |
/* AUTORECODE transformation. */ |
/* AUTORECODE transformation. */ |
56 |
struct autorecode_trns |
struct autorecode_trns |
57 |
{ |
{ |
58 |
struct trns_header h; |
struct pool *pool; /* Contains AUTORECODE specs. */ |
|
struct pool *owner; /* Contains AUTORECODE specs. */ |
|
59 |
struct arc_spec *specs; /* AUTORECODE specifications. */ |
struct arc_spec *specs; /* AUTORECODE specifications. */ |
60 |
size_t spec_cnt; /* Number of specifications. */ |
size_t spec_cnt; /* Number of specifications. */ |
61 |
}; |
}; |
221 |
static void |
static void |
222 |
recode (const struct autorecode_pgm *arc) |
recode (const struct autorecode_pgm *arc) |
223 |
{ |
{ |
224 |
struct autorecode_trns *t; |
struct autorecode_trns *trns; |
|
struct pool *pool; |
|
225 |
size_t i; |
size_t i; |
226 |
|
|
227 |
pool = pool_create (); |
trns = pool_create_container (struct autorecode_trns, pool); |
228 |
t = xmalloc (sizeof *t); |
trns->specs = pool_nalloc (trns->pool, arc->var_cnt, sizeof *trns->specs); |
229 |
t->h.proc = autorecode_trns_proc; |
trns->spec_cnt = arc->var_cnt; |
|
t->h.free = autorecode_trns_free; |
|
|
t->owner = pool; |
|
|
t->specs = pool_nalloc (t->owner, arc->var_cnt, sizeof *t->specs); |
|
|
t->spec_cnt = arc->var_cnt; |
|
230 |
for (i = 0; i < arc->var_cnt; i++) |
for (i = 0; i < arc->var_cnt; i++) |
231 |
{ |
{ |
232 |
struct arc_spec *spec = &t->specs[i]; |
struct arc_spec *spec = &trns->specs[i]; |
233 |
void *const *p = hsh_sort (arc->src_values[i]); |
void *const *p = hsh_sort (arc->src_values[i]); |
234 |
int count = hsh_count (arc->src_values[i]); |
int count = hsh_count (arc->src_values[i]); |
235 |
int j; |
int j; |
246 |
|
|
247 |
for (j = 0; *p; p++, j++) |
for (j = 0; *p; p++, j++) |
248 |
{ |
{ |
249 |
struct arc_item *item = pool_alloc (t->owner, sizeof *item); |
struct arc_item *item = pool_alloc (trns->pool, sizeof *item); |
250 |
union value *vp = *p; |
union value *vp = *p; |
251 |
|
|
252 |
if (arc->src_vars[i]->type == NUMERIC) |
if (arc->src_vars[i]->type == NUMERIC) |
253 |
item->from.f = vp->f; |
item->from.f = vp->f; |
254 |
else |
else |
255 |
item->from.c = pool_strdup (t->owner, vp->c); |
item->from.c = pool_strdup (trns->pool, vp->c); |
256 |
item->to = arc->direction == ASCENDING ? j + 1 : count - j; |
item->to = arc->direction == ASCENDING ? j + 1 : count - j; |
257 |
hsh_force_insert (spec->items, item); |
hsh_force_insert (spec->items, item); |
258 |
} |
} |
259 |
} |
} |
260 |
add_transformation (&t->h); |
add_transformation (autorecode_trns_proc, autorecode_trns_free, trns); |
261 |
} |
} |
262 |
|
|
263 |
static int |
static int |
264 |
autorecode_trns_proc (struct trns_header * trns, struct ccase * c, |
autorecode_trns_proc (void *trns_, struct ccase *c, int case_idx UNUSED) |
|
int case_idx UNUSED) |
|
265 |
{ |
{ |
266 |
struct autorecode_trns *t = (struct autorecode_trns *) trns; |
struct autorecode_trns *trns = trns_; |
267 |
size_t i; |
size_t i; |
268 |
|
|
269 |
for (i = 0; i < t->spec_cnt; i++) |
for (i = 0; i < trns->spec_cnt; i++) |
270 |
{ |
{ |
271 |
struct arc_spec *spec = &t->specs[i]; |
struct arc_spec *spec = &trns->specs[i]; |
272 |
struct arc_item *item; |
struct arc_item *item; |
273 |
union value v; |
union value v; |
274 |
|
|
284 |
} |
} |
285 |
|
|
286 |
static void |
static void |
287 |
autorecode_trns_free (struct trns_header * trns) |
autorecode_trns_free (void *trns_) |
288 |
{ |
{ |
289 |
struct autorecode_trns *t = (struct autorecode_trns *) trns; |
struct autorecode_trns *trns = trns_; |
290 |
size_t i; |
size_t i; |
291 |
|
|
292 |
for (i = 0; i < t->spec_cnt; i++) |
for (i = 0; i < trns->spec_cnt; i++) |
293 |
hsh_destroy (t->specs[i].items); |
hsh_destroy (trns->specs[i].items); |
294 |
pool_destroy (t->owner); |
pool_destroy (trns->pool); |
295 |
} |
} |
296 |
|
|
297 |
/* AUTORECODE procedure. */ |
/* AUTORECODE procedure. */ |