1 /* PSPP - computes sample statistics.
2 Copyright (C) 2004 Free Software Foundation, Inc.
3 Written by Ben Pfaff <blp@gnu.org>.
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
29 #ifdef GLOBAL_DEBUGGING
38 /* Changes C not to share data with any other case.
39 C must be a case with a reference count greater than 1.
40 There should be no reason for external code to call this
41 function explicitly. It will be called automatically when
44 case_unshare (struct ccase *c)
49 assert (c->this == c);
50 assert (c->case_data != NULL);
51 assert (c->case_data->ref_cnt > 1);
55 case_create (c, c->case_data->value_cnt);
56 memcpy (c->case_data->values, cd->values,
57 sizeof *cd->values * cd->value_cnt);
60 /* Returns the number of bytes needed by a case with VALUE_CNT
63 case_size (size_t value_cnt)
65 return (offsetof (struct case_data, values)
66 + value_cnt * sizeof (union value));
69 #ifdef GLOBAL_DEBUGGING
70 /* Initializes C as a null case. */
72 case_nullify (struct ccase *c)
77 #endif /* GLOBAL_DEBUGGING */
79 #ifdef GLOBAL_DEBUGGING
80 /* Returns true iff C is a null case. */
82 case_is_null (const struct ccase *c)
84 return c->case_data == NULL;
86 #endif /* GLOBAL_DEBUGGING */
88 /* Initializes C as a new case that can store VALUE_CNT values.
89 The values have indeterminate contents until explicitly
92 case_create (struct ccase *c, size_t value_cnt)
94 if (!case_try_create (c, value_cnt))
98 #ifdef GLOBAL_DEBUGGING
99 /* Initializes CLONE as a copy of ORIG. */
101 case_clone (struct ccase *clone, const struct ccase *orig)
103 assert (orig != NULL);
104 assert (orig->this == orig);
105 assert (orig->case_data != NULL);
106 assert (orig->case_data->ref_cnt > 0);
107 assert (clone != NULL);
114 orig->case_data->ref_cnt++;
116 #endif /* GLOBAL_DEBUGGING */
118 #ifdef GLOBAL_DEBUGGING
119 /* Replaces DST by SRC and nullifies SRC.
120 DST and SRC must be initialized cases at entry. */
122 case_move (struct ccase *dst, struct ccase *src)
124 assert (src != NULL);
125 assert (src->this == src);
126 assert (src->case_data != NULL);
127 assert (src->case_data->ref_cnt > 0);
128 assert (dst != NULL);
134 #endif /* GLOBAL_DEBUGGING */
136 #ifdef GLOBAL_DEBUGGING
137 /* Destroys case C. */
139 case_destroy (struct ccase *c)
141 struct case_data *cd;
144 assert (c->this == c);
147 if (cd != NULL && --cd->ref_cnt == 0)
149 memset (cd->values, 0xcc, sizeof *cd->values * cd->value_cnt);
150 cd->value_cnt = 0xdeadbeef;
154 #endif /* GLOBAL_DEBUGGING */
156 /* Resizes case C from OLD_CNT to NEW_CNT values. */
158 case_resize (struct ccase *c, size_t old_cnt, size_t new_cnt)
162 case_create (&new, new_cnt);
163 case_copy (&new, 0, c, 0, old_cnt < new_cnt ? old_cnt : new_cnt);
168 /* Swaps cases A and B. */
170 case_swap (struct ccase *a, struct ccase *b)
172 struct case_data *t = a->case_data;
173 a->case_data = b->case_data;
177 /* Attempts to create C as a new case that holds VALUE_CNT
178 values. Returns nonzero if successful, zero if memory
179 allocation failed. */
181 case_try_create (struct ccase *c, size_t value_cnt)
183 c->case_data = malloc (case_size (value_cnt));
184 if (c->case_data != NULL)
186 #ifdef GLOBAL_DEBUGGING
189 c->case_data->value_cnt = value_cnt;
190 c->case_data->ref_cnt = 1;
195 #ifdef GLOBAL_DEBUGGING
202 /* Tries to initialize CLONE as a copy of ORIG.
203 Returns nonzero if successful, zero if memory allocation
206 case_try_clone (struct ccase *clone, const struct ccase *orig)
208 case_clone (clone, orig);
212 #ifdef GLOBAL_DEBUGGING
213 /* Copies VALUE_CNT values from SRC (starting at SRC_IDX) to DST
214 (starting at DST_IDX). */
216 case_copy (struct ccase *dst, size_t dst_idx,
217 const struct ccase *src, size_t src_idx,
220 assert (dst != NULL);
221 assert (dst->this == dst);
222 assert (dst->case_data != NULL);
223 assert (dst->case_data->ref_cnt > 0);
224 assert (dst_idx + value_cnt <= dst->case_data->value_cnt);
226 assert (src != NULL);
227 assert (src->this == src);
228 assert (src->case_data != NULL);
229 assert (src->case_data->ref_cnt > 0);
230 assert (src_idx + value_cnt <= dst->case_data->value_cnt);
232 if (dst->case_data->ref_cnt > 1)
234 if (dst->case_data != src->case_data || dst_idx != src_idx)
235 memmove (dst->case_data->values + dst_idx,
236 src->case_data->values + src_idx,
237 sizeof *dst->case_data->values * value_cnt);
239 #endif /* GLOBAL_DEBUGGING */
241 #ifdef GLOBAL_DEBUGGING
242 /* Copies case C to OUTPUT.
243 OUTPUT_SIZE is the number of `union values' in OUTPUT,
244 which must match the number of `union values' in C. */
246 case_to_values (const struct ccase *c, union value *output,
247 size_t output_size UNUSED)
250 assert (c->this == c);
251 assert (c->case_data != NULL);
252 assert (c->case_data->ref_cnt > 0);
253 assert (output_size == c->case_data->value_cnt);
254 assert (output != NULL || output_size == 0);
256 memcpy (output, c->case_data->values,
257 c->case_data->value_cnt * sizeof *output);
259 #endif /* GLOBAL_DEBUGGING */
261 #ifdef GLOBAL_DEBUGGING
262 /* Copies INPUT into case C.
263 INPUT_SIZE is the number of `union values' in INPUT,
264 which must match the number of `union values' in C. */
266 case_from_values (struct ccase *c, const union value *input,
267 size_t input_size UNUSED)
270 assert (c->this == c);
271 assert (c->case_data != NULL);
272 assert (c->case_data->ref_cnt > 0);
273 assert (input_size == c->case_data->value_cnt);
274 assert (input != NULL || input_size == 0);
276 if (c->case_data->ref_cnt > 1)
278 memcpy (c->case_data->values, input,
279 c->case_data->value_cnt * sizeof *input);
281 #endif /* GLOBAL_DEBUGGING */
283 #ifdef GLOBAL_DEBUGGING
284 /* Returns a pointer to the `union value' used for the
285 element of C numbered IDX.
286 The caller must not modify the returned data. */
288 case_data (const struct ccase *c, size_t idx)
291 assert (c->this == c);
292 assert (c->case_data != NULL);
293 assert (c->case_data->ref_cnt > 0);
294 assert (idx < c->case_data->value_cnt);
296 return &c->case_data->values[idx];
298 #endif /* GLOBAL_DEBUGGING */
300 #ifdef GLOBAL_DEBUGGING
301 /* Returns the numeric value of the `union value' in C numbered
304 case_num (const struct ccase *c, size_t idx)
307 assert (c->this == c);
308 assert (c->case_data != NULL);
309 assert (c->case_data->ref_cnt > 0);
310 assert (idx < c->case_data->value_cnt);
312 return c->case_data->values[idx].f;
314 #endif /* GLOBAL_DEBUGGING */
316 #ifdef GLOBAL_DEBUGGING
317 /* Returns the string value of the `union value' in C numbered
319 (Note that the value is not null-terminated.)
320 The caller must not modify the return value. */
322 case_str (const struct ccase *c, size_t idx)
325 assert (c->this == c);
326 assert (c->case_data != NULL);
327 assert (c->case_data->ref_cnt > 0);
328 assert (idx < c->case_data->value_cnt);
330 return c->case_data->values[idx].s;
332 #endif /* GLOBAL_DEBUGGING */
334 #ifdef GLOBAL_DEBUGGING
335 /* Returns a pointer to the `union value' used for the
336 element of C numbered IDX.
337 The caller is allowed to modify the returned data. */
339 case_data_rw (struct ccase *c, size_t idx)
342 assert (c->this == c);
343 assert (c->case_data != NULL);
344 assert (c->case_data->ref_cnt > 0);
345 assert (idx < c->case_data->value_cnt);
347 if (c->case_data->ref_cnt > 1)
349 return &c->case_data->values[idx];
351 #endif /* GLOBAL_DEBUGGING */
353 /* Compares the values of the VAR_CNT variables in VP
354 in cases A and B and returns a strcmp()-type result. */
356 case_compare (const struct ccase *a, const struct ccase *b,
357 struct variable *const *vp, size_t var_cnt)
359 return case_compare_2dict (a, b, vp, vp, var_cnt);
362 /* Compares the values of the VAR_CNT variables in VAP in case CA
363 to the values of the VAR_CNT variables in VBP in CB
364 and returns a strcmp()-type result. */
366 case_compare_2dict (const struct ccase *ca, const struct ccase *cb,
367 struct variable *const *vap, struct variable *const *vbp,
370 for (; var_cnt-- > 0; vap++, vbp++)
372 const struct variable *va = *vap;
373 const struct variable *vb = *vbp;
375 assert (va->type == vb->type);
376 assert (va->width == vb->width);
380 double af = case_num (ca, va->fv);
381 double bf = case_num (cb, vb->fv);
384 return af > bf ? 1 : -1;
388 const char *as = case_str (ca, va->fv);
389 const char *bs = case_str (cb, vb->fv);
390 int cmp = memcmp (as, bs, va->width);
399 /* Returns a pointer to the array of `union value's used for C.
400 The caller must *not* modify the returned data.
402 NOTE: This function breaks the case abstraction. It should
403 *not* be used often. Prefer the other case functions. */
405 case_data_all (const struct ccase *c)
408 assert (c->this == c);
409 assert (c->case_data != NULL);
410 assert (c->case_data->ref_cnt > 0);
412 return c->case_data->values;
415 /* Returns a pointer to the array of `union value's used for C.
416 The caller is allowed to modify the returned data.
418 NOTE: This function breaks the case abstraction. It should
419 *not* be used often. Prefer the other case functions. */
421 case_data_all_rw (struct ccase *c)
424 assert (c->this == c);
425 assert (c->case_data != NULL);
426 assert (c->case_data->ref_cnt > 0);
428 if (c->case_data->ref_cnt > 1)
430 return c->case_data->values;