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., 59 Temple Place - Suite 330, Boston, MA
28 #ifdef GLOBAL_DEBUGGING
37 /* Changes C not to share data with any other case.
38 C must be a case with a reference count greater than 1.
39 There should be no reason for external code to call this
40 function explicitly. It will be called automatically when
43 case_unshare (struct ccase *c)
48 assert (c->this == c);
49 assert (c->case_data != NULL);
50 assert (c->case_data->ref_cnt > 1);
54 case_create (c, c->case_data->value_cnt);
55 memcpy (c->case_data->values, cd->values,
56 sizeof *cd->values * cd->value_cnt);
59 /* Returns the number of bytes needed by a case with VALUE_CNT
62 case_size (size_t value_cnt)
64 return (offsetof (struct case_data, values)
65 + value_cnt * sizeof (union value));
68 #ifdef GLOBAL_DEBUGGING
69 /* Initializes C as a null case. */
71 case_nullify (struct ccase *c)
76 #endif /* GLOBAL_DEBUGGING */
78 #ifdef GLOBAL_DEBUGGING
79 /* Returns true iff C is a null case. */
81 case_is_null (const struct ccase *c)
83 return c->case_data == NULL;
85 #endif /* GLOBAL_DEBUGGING */
87 /* Initializes C as a new case that can store VALUE_CNT values.
88 The values have indeterminate contents until explicitly
91 case_create (struct ccase *c, size_t value_cnt)
93 if (!case_try_create (c, value_cnt))
97 #ifdef GLOBAL_DEBUGGING
98 /* Initializes CLONE as a copy of ORIG. */
100 case_clone (struct ccase *clone, const struct ccase *orig)
102 assert (orig != NULL);
103 assert (orig->this == orig);
104 assert (orig->case_data != NULL);
105 assert (orig->case_data->ref_cnt > 0);
106 assert (clone != NULL);
113 orig->case_data->ref_cnt++;
115 #endif /* GLOBAL_DEBUGGING */
117 #ifdef GLOBAL_DEBUGGING
118 /* Replaces DST by SRC and nullifies SRC.
119 DST and SRC must be initialized cases at entry. */
121 case_move (struct ccase *dst, struct ccase *src)
123 assert (src != NULL);
124 assert (src->this == src);
125 assert (src->case_data != NULL);
126 assert (src->case_data->ref_cnt > 0);
127 assert (dst != NULL);
133 #endif /* GLOBAL_DEBUGGING */
135 #ifdef GLOBAL_DEBUGGING
136 /* Destroys case C. */
138 case_destroy (struct ccase *c)
140 struct case_data *cd;
143 assert (c->this == c);
146 if (cd != NULL && --cd->ref_cnt == 0)
148 memset (cd->values, 0xcc, sizeof *cd->values * cd->value_cnt);
149 cd->value_cnt = 0xdeadbeef;
153 #endif /* GLOBAL_DEBUGGING */
155 /* Resizes case C from OLD_CNT to NEW_CNT values. */
157 case_resize (struct ccase *c, size_t old_cnt, size_t new_cnt)
161 case_create (&new, new_cnt);
162 case_copy (&new, 0, c, 0, old_cnt < new_cnt ? old_cnt : new_cnt);
167 /* Swaps cases A and B. */
169 case_swap (struct ccase *a, struct ccase *b)
171 struct case_data *t = a->case_data;
172 a->case_data = b->case_data;
176 /* Attempts to create C as a new case that holds VALUE_CNT
177 values. Returns nonzero if successful, zero if memory
178 allocation failed. */
180 case_try_create (struct ccase *c, size_t value_cnt)
182 c->case_data = malloc (case_size (value_cnt));
183 if (c->case_data != NULL)
185 #ifdef GLOBAL_DEBUGGING
188 c->case_data->value_cnt = value_cnt;
189 c->case_data->ref_cnt = 1;
194 #ifdef GLOBAL_DEBUGGING
201 /* Tries to initialize CLONE as a copy of ORIG.
202 Returns nonzero if successful, zero if memory allocation
205 case_try_clone (struct ccase *clone, const struct ccase *orig)
207 case_clone (clone, orig);
211 #ifdef GLOBAL_DEBUGGING
212 /* Copies VALUE_CNT values from SRC (starting at SRC_IDX) to DST
213 (starting at DST_IDX). */
215 case_copy (struct ccase *dst, size_t dst_idx,
216 const struct ccase *src, size_t src_idx,
219 assert (dst != NULL);
220 assert (dst->this == dst);
221 assert (dst->case_data != NULL);
222 assert (dst->case_data->ref_cnt > 0);
223 assert (dst_idx + value_cnt <= dst->case_data->value_cnt);
225 assert (src != NULL);
226 assert (src->this == src);
227 assert (src->case_data != NULL);
228 assert (src->case_data->ref_cnt > 0);
229 assert (src_idx + value_cnt <= dst->case_data->value_cnt);
231 if (dst->case_data->ref_cnt > 1)
233 if (dst->case_data != src->case_data || dst_idx != src_idx)
234 memmove (dst->case_data->values + dst_idx,
235 src->case_data->values + src_idx,
236 sizeof *dst->case_data->values * value_cnt);
238 #endif /* GLOBAL_DEBUGGING */
240 #ifdef GLOBAL_DEBUGGING
241 /* Copies case C to OUTPUT.
242 OUTPUT_SIZE is the number of `union values' in OUTPUT,
243 which must match the number of `union values' in C. */
245 case_to_values (const struct ccase *c, union value *output,
246 size_t output_size UNUSED)
249 assert (c->this == c);
250 assert (c->case_data != NULL);
251 assert (c->case_data->ref_cnt > 0);
252 assert (output_size == c->case_data->value_cnt);
253 assert (output != NULL || output_size == 0);
255 memcpy (output, c->case_data->values,
256 c->case_data->value_cnt * sizeof *output);
258 #endif /* GLOBAL_DEBUGGING */
260 #ifdef GLOBAL_DEBUGGING
261 /* Copies INPUT into case C.
262 INPUT_SIZE is the number of `union values' in INPUT,
263 which must match the number of `union values' in C. */
265 case_from_values (struct ccase *c, const union value *input,
266 size_t input_size UNUSED)
269 assert (c->this == c);
270 assert (c->case_data != NULL);
271 assert (c->case_data->ref_cnt > 0);
272 assert (input_size == c->case_data->value_cnt);
273 assert (input != NULL || input_size == 0);
275 if (c->case_data->ref_cnt > 1)
277 memcpy (c->case_data->values, input,
278 c->case_data->value_cnt * sizeof *input);
280 #endif /* GLOBAL_DEBUGGING */
282 #ifdef GLOBAL_DEBUGGING
283 /* Returns a pointer to the `union value' used for the
284 element of C numbered IDX.
285 The caller must not modify the returned data. */
287 case_data (const struct ccase *c, size_t idx)
290 assert (c->this == c);
291 assert (c->case_data != NULL);
292 assert (c->case_data->ref_cnt > 0);
293 assert (idx < c->case_data->value_cnt);
295 return &c->case_data->values[idx];
297 #endif /* GLOBAL_DEBUGGING */
299 #ifdef GLOBAL_DEBUGGING
300 /* Returns the numeric value of the `union value' in C numbered
303 case_num (const struct ccase *c, size_t idx)
306 assert (c->this == c);
307 assert (c->case_data != NULL);
308 assert (c->case_data->ref_cnt > 0);
309 assert (idx < c->case_data->value_cnt);
311 return c->case_data->values[idx].f;
313 #endif /* GLOBAL_DEBUGGING */
315 #ifdef GLOBAL_DEBUGGING
316 /* Returns the string value of the `union value' in C numbered
318 (Note that the value is not null-terminated.)
319 The caller must not modify the return value. */
321 case_str (const struct ccase *c, size_t idx)
324 assert (c->this == c);
325 assert (c->case_data != NULL);
326 assert (c->case_data->ref_cnt > 0);
327 assert (idx < c->case_data->value_cnt);
329 return c->case_data->values[idx].s;
331 #endif /* GLOBAL_DEBUGGING */
333 #ifdef GLOBAL_DEBUGGING
334 /* Returns a pointer to the `union value' used for the
335 element of C numbered IDX.
336 The caller is allowed to modify the returned data. */
338 case_data_rw (struct ccase *c, size_t idx)
341 assert (c->this == c);
342 assert (c->case_data != NULL);
343 assert (c->case_data->ref_cnt > 0);
344 assert (idx < c->case_data->value_cnt);
346 if (c->case_data->ref_cnt > 1)
348 return &c->case_data->values[idx];
350 #endif /* GLOBAL_DEBUGGING */
352 /* Returns a pointer to the array of `union value's used for C.
353 The caller must *not* modify the returned data.
355 NOTE: This function breaks the case abstraction. It should
356 *not* be used often. Prefer the other case functions. */
358 case_data_all (const struct ccase *c)
361 assert (c->this == c);
362 assert (c->case_data != NULL);
363 assert (c->case_data->ref_cnt > 0);
365 return c->case_data->values;
368 /* Returns a pointer to the array of `union value's used for C.
369 The caller is allowed to modify the returned data.
371 NOTE: This function breaks the case abstraction. It should
372 *not* be used often. Prefer the other case functions. */
374 case_data_all_rw (struct ccase *c)
377 assert (c->this == c);
378 assert (c->case_data != NULL);
379 assert (c->case_data->ref_cnt > 0);
381 if (c->case_data->ref_cnt > 1)
383 return c->case_data->values;