SDDS ToolKit Programs and Libraries for C and Python
Loading...
Searching...
No Matches
sddsselect.c
Go to the documentation of this file.
1/**
2 * @file sddsselect.c
3 * @brief Creates an SDDS data set from another data set based on matching data in a third data set.
4 *
5 * @details
6 * This program selects rows from `<input1>` that have (or do not have, if inverted) a matching entry in `<input2>`,
7 * based on specified matching or equating columns. The output is written to `<output>`, or `<input1>` is replaced
8 * if `<output>` is not provided. It supports various options to customize the matching behavior, data processing,
9 * and output format.
10 *
11 * @section Usage
12 * ```
13 * sddsselect [<input1>] <input2> [<output>]
14 * [-pipe[=input][,output]]
15 * [-match=<column-name>[=<column-name>]]
16 * [-equate=<column-name>[=<column-name>]]
17 * [-hashLookup]
18 * [-invert]
19 * [-reuse[=rows][,page]]
20 * [-majorOrder=row|column]
21 * [-nowarnings]
22 * ```
23 *
24 * @section Options
25 * | Optional | Description |
26 * |---------------------------------------|---------------------------------------------------------------------------------------|
27 * | `-pipe` | Use pipe for input and/or output. |
28 * | `-match` | Specify columns to match between `<input1>` and `<input2>`. |
29 * | `-equate` | Specify columns to equate between `<input1>` and `<input2>`. |
30 * | `-hashLookup` | Use a hash table for matching instead of sorted key lists. |
31 * | `-invert` | Invert the selection to keep non-matching rows. |
32 * | `-reuse` | Allow reusing rows or specify page reuse. |
33 * | `-majorOrder` | Set the output file to row or column major order. |
34 * | `-nowarnings` | Suppress warning messages. |
35 *
36 * @subsection Incompatibilities
37 * - Only one of `-match` or `-equate` may be specified.
38 *
39 * @copyright
40 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
41 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
42 *
43 * @license
44 * This file is distributed under the terms of the Software License Agreement
45 * found in the file LICENSE included with this distribution.
46 *
47 * @author
48 * M. Borland, C. Saunders, R. Soliday, H. Shang
49 */
50
51#include "mdb.h"
52#include "SDDS.h"
53#include "SDDSaps.h"
54#include "scan.h"
55
56/* Enumeration for option types */
57enum option_type {
58 SET_MATCH_COLUMN,
59 SET_EQUATE_COLUMN,
60 SET_NOWARNINGS,
61 SET_INVERT,
62 SET_REUSE,
63 SET_PIPE,
64 SET_MAJOR_ORDER,
65 SET_HASH_LOOKUP,
66 N_OPTIONS
67};
68
69char *option[N_OPTIONS] = {
70 "match",
71 "equate",
72 "nowarnings",
73 "invert",
74 "reuse",
75 "pipe",
76 "majorOrder",
77 "hashlookup",
78};
79
80char *USAGE = "\n\
81sddsselect [<input1>] <input2> [<output>]\n\
82 [-pipe[=input][,output]]\n\
83 [-match=<column-name>[=<column-name>]]\n\
84 [-equate=<column-name>[=<column-name>]] \n\
85 [-hashLookup]\n\
86 [-invert]\n\
87 [-reuse[=rows][,page]] \n\
88 [-majorOrder=row|column]\n\
89 [-nowarnings]\n\
90Options:\n\
91 -pipe[=input][,output] Use pipe for input and/or output.\n\
92 -match=<column1>[=<column2>] Specify columns to match between input1 and input2.\n\
93 -equate=<column1>[=<column2>] Specify columns to equate between input1 and input2.\n\
94 -hashLookup Use a hash table for key lookups (non-wildcard match/equate).\n\
95 -invert Invert the selection to keep non-matching rows.\n\
96 -reuse[=rows][,page] Allow reusing rows or specify page reuse.\n\
97 -majorOrder=row|column Set the output file to row or column major order.\n\
98 -nowarnings Suppress warning messages.\n\
99\n\
100Example:\n\
101 sddsselect -match=colA=colB input1.sdds input2.sdds output.sdds\n\
102\n\
103Program by Michael Borland. (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")\n";
104
105int main(int argc, char **argv) {
106 SDDS_DATASET SDDS_1, SDDS_2, SDDS_output;
107 long i, j, i_arg, reuse, reusePage;
108 int64_t rows1, rows2, i1, i2;
109 SCANNED_ARG *s_arg;
110 char s[200], *ptr;
111 char **match_column, **equate_column;
112 long match_columns, equate_columns;
113 char *input1, *input2, *output;
114 long tmpfile_used, retval1, retval2;
115 long warnings, invert;
116 unsigned long pipeFlags, majorOrderFlag;
117 KEYED_EQUIVALENT **keyGroup = NULL;
118 long keyGroups = 0;
119 short columnMajorOrder = -1;
120 long useHashLookup = 0;
121
123 argc = scanargs(&s_arg, argc, argv);
124 if (argc < 3)
125 bomb(NULL, USAGE);
126
127 input1 = input2 = output = NULL;
128 match_column = equate_column = NULL;
129 match_columns = equate_columns = reuse = reusePage = 0;
130 tmpfile_used = invert = 0;
131 warnings = 1;
132 pipeFlags = 0;
133
134 for (i_arg = 1; i_arg < argc; i_arg++) {
135 if (s_arg[i_arg].arg_type == OPTION) {
136 delete_chars(s_arg[i_arg].list[0], "_");
137 switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
138 case SET_MAJOR_ORDER:
139 majorOrderFlag = 0;
140 s_arg[i_arg].n_items--;
141 if (s_arg[i_arg].n_items > 0 &&
142 (!scanItemList(&majorOrderFlag, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
143 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
144 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
145 SDDS_Bomb("invalid -majorOrder syntax/values");
146 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
147 columnMajorOrder = 1;
148 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
149 columnMajorOrder = 0;
150 break;
151 case SET_MATCH_COLUMN:
152 if (s_arg[i_arg].n_items != 2)
153 SDDS_Bomb("invalid -match syntax");
154 if (match_columns != 0)
155 SDDS_Bomb("only one -match option may be given");
156 match_column = tmalloc(sizeof(*match_column) * 2);
157 if ((ptr = strchr(s_arg[i_arg].list[1], '=')))
158 *ptr++ = 0;
159 else
160 ptr = s_arg[i_arg].list[1];
161 match_column[0] = s_arg[i_arg].list[1];
162 match_column[1] = ptr;
163 match_columns = 1;
164 break;
165 case SET_EQUATE_COLUMN:
166 if (s_arg[i_arg].n_items != 2)
167 SDDS_Bomb("invalid -equate syntax");
168 if (equate_columns != 0)
169 SDDS_Bomb("only one -equate option may be given");
170 equate_column = tmalloc(sizeof(*equate_column) * 2);
171 if ((ptr = strchr(s_arg[i_arg].list[1], '=')))
172 *ptr++ = 0;
173 else
174 ptr = s_arg[i_arg].list[1];
175 equate_column[0] = s_arg[i_arg].list[1];
176 equate_column[1] = ptr;
177 equate_columns = 1;
178 break;
179 case SET_REUSE:
180 if (s_arg[i_arg].n_items == 1)
181 reuse = 1;
182 else {
183 char *reuseOptions[2] = {"rows", "page"};
184 for (i = 1; i < s_arg[i_arg].n_items; i++) {
185 switch (match_string(s_arg[i_arg].list[i], reuseOptions, 2, 0)) {
186 case 0:
187 reuse = 1;
188 break;
189 case 1:
190 reusePage = 1;
191 break;
192 default:
193 SDDS_Bomb("unknown reuse keyword");
194 break;
195 }
196 }
197 }
198 break;
199 case SET_INVERT:
200 invert = 1;
201 break;
202 case SET_NOWARNINGS:
203 warnings = 0;
204 break;
205 case SET_PIPE:
206 if (!processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
207 SDDS_Bomb("invalid -pipe syntax");
208 break;
209 case SET_HASH_LOOKUP:
210 useHashLookup = 1;
211 break;
212 default:
213 fprintf(stderr, "error: unknown switch: %s\n", s_arg[i_arg].list[0]);
214 SDDS_Bomb(NULL);
215 break;
216 }
217 } else {
218 if (input1 == NULL)
219 input1 = s_arg[i_arg].list[0];
220 else if (input2 == NULL)
221 input2 = s_arg[i_arg].list[0];
222 else if (output == NULL)
223 output = s_arg[i_arg].list[0];
224 else
225 SDDS_Bomb("too many filenames");
226 }
227 }
228
229 if (pipeFlags & USE_STDIN && input1) {
230 if (output)
231 SDDS_Bomb("too many filenames (sddsxref)");
232 output = input2;
233 input2 = input1;
234 input1 = NULL;
235 }
236 processFilenames("sddsselect", &input1, &output, pipeFlags, !warnings, &tmpfile_used);
237 if (!input2)
238 SDDS_Bomb("second input file not specified (sddsxref)");
239
240 if (equate_columns && match_columns)
241 SDDS_Bomb("only one of -equate or -match may be given");
242 if (!equate_columns && !match_columns)
243 SDDS_Bomb("one of -equate or -match must be given");
244
245 if (!SDDS_InitializeInput(&SDDS_1, input1)) {
246 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
247 exit(EXIT_FAILURE);
248 }
249 if (!SDDS_InitializeInput(&SDDS_2, input2)) {
250 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
251 exit(EXIT_FAILURE);
252 }
253
254 if (match_columns) {
255 if ((j = SDDS_GetColumnIndex(&SDDS_1, match_column[0])) < 0 ||
256 SDDS_GetColumnType(&SDDS_1, j) != SDDS_STRING) {
257 sprintf(s, "error: column %s not found or not string type in file %s", match_column[0], input1 ? input1 : "stdin");
258 SDDS_SetError(s);
259 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
260 }
261 if ((j = SDDS_GetColumnIndex(&SDDS_2, match_column[1])) < 0 ||
262 SDDS_GetColumnType(&SDDS_2, j) != SDDS_STRING) {
263 sprintf(s, "error: column %s not found or not string type in file %s", match_column[1], input2);
264 SDDS_SetError(s);
265 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
266 }
267 }
268 if (equate_columns) {
269 if ((j = SDDS_GetColumnIndex(&SDDS_1, equate_column[0])) < 0 ||
271 sprintf(s, "error: column %s not found or not numeric type in file %s", equate_column[0], input1 ? input1 : "stdin");
272 SDDS_SetError(s);
273 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
274 }
275 if ((j = SDDS_GetColumnIndex(&SDDS_2, equate_column[1])) < 0 ||
277 sprintf(s, "error: column %s not found or not numeric type in file %s", equate_column[1], input2);
278 SDDS_SetError(s);
279 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
280 }
281 }
282
283 if (output && pipeFlags & USE_STDOUT)
284 SDDS_Bomb("too many filenames with -pipe option");
285 if (!output && !(pipeFlags & USE_STDOUT)) {
286 if (warnings)
287 fprintf(stderr, "warning: existing file %s will be replaced (sddsselect)\n", input1 ? input1 : "stdin");
288 tmpfile_used = 1;
289 cp_str(&output, tmpname(NULL));
290 }
291 if (!SDDS_InitializeCopy(&SDDS_output, &SDDS_1, output, "w")) {
292 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
293 exit(EXIT_FAILURE);
294 }
295 if (columnMajorOrder != -1)
296 SDDS_output.layout.data_mode.column_major = columnMajorOrder;
297 else
298 SDDS_output.layout.data_mode.column_major = SDDS_1.layout.data_mode.column_major;
299 if (!SDDS_WriteLayout(&SDDS_output))
300 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
301
302 while ((retval1 = SDDS_ReadPage(&SDDS_1)) > 0) {
303 if (!reusePage) {
304 if ((retval2 = SDDS_ReadPage(&SDDS_2)) <= 0) {
305 if (warnings)
306 fprintf(stderr, "warning: <input2> ends before <input1>\n");
307 if (invert) {
308 /* nothing to match, so everything would normally be thrown out */
309 if (!SDDS_CopyPage(&SDDS_output, &SDDS_1) ||
310 !SDDS_WritePage(&SDDS_output))
311 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
312 continue;
313 } else
314 /* nothing to match, so everything thrown out */
315 break;
316 }
317 } else {
318 if (retval1 == 1 && (retval2 = SDDS_ReadPage(&SDDS_2)) <= 0)
319 SDDS_Bomb("<input2> has no data");
320 SDDS_SetRowFlags(&SDDS_2, 1);
321 }
322 rows1 = SDDS_CountRowsOfInterest(&SDDS_1);
323 rows2 = SDDS_CountRowsOfInterest(&SDDS_2);
324
325 if (!SDDS_StartPage(&SDDS_output, rows1)) {
326 SDDS_SetError("Problem starting output page");
327 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
328 }
329 if (!SDDS_CopyParameters(&SDDS_output, &SDDS_2) ||
330 !SDDS_CopyArrays(&SDDS_output, &SDDS_2)) {
331 SDDS_SetError("Problem copying parameter or array data from second input file");
332 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
333 }
334 if (!SDDS_CopyParameters(&SDDS_output, &SDDS_1) ||
335 !SDDS_CopyArrays(&SDDS_output, &SDDS_1)) {
336 SDDS_SetError("Problem copying parameter or array data from first input file");
337 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
338 }
339 if (rows1) {
340 if (match_columns) {
341 char **string1, **string2;
342 long matched;
343 string2 = NULL;
344 if (!(string1 = SDDS_GetColumn(&SDDS_1, match_column[0]))) {
345 fprintf(stderr, "Error: problem getting column %s from file %s\n", match_column[0], input1 ? input1 : "stdin");
346 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
347 }
348 if (rows2 && !(string2 = SDDS_GetColumn(&SDDS_2, match_column[1]))) {
349 fprintf(stderr, "Error: problem getting column %s from file %s\n", match_column[1], input2);
350 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
351 }
352 StrHash *strHash = NULL;
353 if (rows2) {
354 if (useHashLookup)
355 strHash = SDDS_BuildStrHash(string2, rows2);
356 else
357 keyGroup = MakeSortedKeyGroups(&keyGroups, SDDS_STRING, string2, rows2);
358 }
359 for (i1 = 0; i1 < rows1; i1++) {
360 if (!SDDS_CopyRowDirect(&SDDS_output, i1, &SDDS_1, i1)) {
361 sprintf(s, "Problem copying row %" PRId64 " of first data set", i1);
362 SDDS_SetError(s);
363 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
364 }
365 matched = 0;
366 if (rows2) {
367 if (useHashLookup) {
368 if (SDDS_LookupStr(strHash, string1[i1], reuse) >= 0)
369 matched = 1;
370 } else {
371 if ((i2 = FindMatchingKeyGroup(keyGroup, keyGroups, SDDS_STRING, string1 + i1, reuse)) >= 0)
372 matched = 1;
373 }
374 }
375 if ((!matched && !invert) || (matched && invert)) {
376 if (!SDDS_AssertRowFlags(&SDDS_output, SDDS_INDEX_LIMITS, i1, i1, 0))
377 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
378 }
379 }
380 if (string1) {
381 for (i = 0; i < rows1; i++)
382 free(string1[i]);
383 free(string1);
384 string1 = NULL;
385 }
386 if (string2) {
387 for (i = 0; i < rows2; i++)
388 free(string2[i]);
389 free(string2);
390 string2 = NULL;
391 }
392 if (useHashLookup && strHash) {
393 SDDS_FreeStrHash(strHash);
394 strHash = NULL;
395 }
396 for (i = 0; i < keyGroups; i++) {
397 if (keyGroup[i]) {
398 if (keyGroup[i]->equivalent)
399 free(keyGroup[i]->equivalent);
400 free(keyGroup[i]);
401 keyGroup[i] = NULL;
402 }
403 }
404 if (keyGroups) {
405 free(keyGroup);
406 keyGroup = NULL;
407 keyGroups = 0;
408 }
409 } else if (equate_columns) {
410 double *value1, *value2;
411 long equated;
412 value2 = NULL;
413 if (!(value1 = SDDS_GetColumnInDoubles(&SDDS_1, equate_column[0]))) {
414 fprintf(stderr, "Error: problem getting column %s from file %s\n", equate_column[0], input1 ? input1 : "stdin");
415 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
416 }
417 if (rows2 && !(value2 = SDDS_GetColumnInDoubles(&SDDS_2, equate_column[1]))) {
418 fprintf(stderr, "Error: problem getting column %s from file %s\n", equate_column[1], input2);
419 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
420 }
421 NumHash *numHash = NULL;
422 if (rows2) {
423 if (useHashLookup)
424 numHash = SDDS_BuildNumHash(value2, rows2);
425 else
426 keyGroup = MakeSortedKeyGroups(&keyGroups, SDDS_DOUBLE, value2, rows2);
427 }
428 for (i1 = 0; i1 < rows1; i1++) {
429 if (!SDDS_CopyRowDirect(&SDDS_output, i1, &SDDS_1, i1)) {
430 sprintf(s, "Problem copying row %" PRId64 " of first data set", i1);
431 SDDS_SetError(s);
432 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
433 }
434 equated = 0;
435 if (rows2) {
436 if (useHashLookup) {
437 if (SDDS_LookupNum(numHash, value1[i1], reuse) >= 0)
438 equated = 1;
439 } else {
440 if ((i2 = FindMatchingKeyGroup(keyGroup, keyGroups, SDDS_DOUBLE, value1 + i1, reuse)) >= 0)
441 equated = 1;
442 }
443 }
444 if ((!equated && !invert) || (equated && invert)) {
445 if (!SDDS_AssertRowFlags(&SDDS_output, SDDS_INDEX_LIMITS, i1, i1, 0))
446 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
447 }
448 }
449 if (value1)
450 free(value1);
451 value1 = NULL;
452 if (rows2 && value2)
453 free(value2);
454 value2 = NULL;
455 if (useHashLookup && numHash) {
456 SDDS_FreeNumHash(numHash);
457 numHash = NULL;
458 }
459 for (i = 0; i < keyGroups; i++) {
460 if (keyGroup[i]) {
461 if (keyGroup[i]->equivalent)
462 free(keyGroup[i]->equivalent);
463 free(keyGroup[i]);
464 keyGroup[i] = NULL;
465 }
466 }
467 if (keyGroups) {
468 free(keyGroup);
469 keyGroup = NULL;
470 keyGroups = 0;
471 }
472 }
473 }
474 if (!SDDS_WritePage(&SDDS_output)) {
475 SDDS_SetError("Problem writing data to output file");
476 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
477 }
478 }
479
480 if (!SDDS_Terminate(&SDDS_1) || !SDDS_Terminate(&SDDS_2) || !SDDS_Terminate(&SDDS_output)) {
481 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
482 exit(EXIT_FAILURE);
483 }
484 if (tmpfile_used && !replaceFileAndBackUp(input1, output))
485 exit(EXIT_FAILURE);
486 free_scanargs(&s_arg, argc);
487 if (match_columns)
488 free(match_column);
489 return EXIT_SUCCESS;
490}
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_CopyParameters(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:286
int32_t SDDS_InitializeCopy(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, char *filename, char *filemode)
Definition SDDS_copy.c:40
int32_t SDDS_CopyRowDirect(SDDS_DATASET *SDDS_target, int64_t target_row, SDDS_DATASET *SDDS_source, int64_t source_row)
Definition SDDS_copy.c:834
int32_t SDDS_CopyPage(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:578
int32_t SDDS_CopyArrays(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:334
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
int32_t SDDS_AssertRowFlags(SDDS_DATASET *SDDS_dataset, uint32_t mode,...)
Sets acceptance flags for rows based on specified criteria.
void * SDDS_GetColumn(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves a copy of the data for a specified column, including only rows marked as "of interest".
int64_t SDDS_CountRowsOfInterest(SDDS_DATASET *SDDS_dataset)
Counts the number of rows marked as "of interest" in the current data table.
int32_t SDDS_SetRowFlags(SDDS_DATASET *SDDS_dataset, int32_t row_flag_value)
Sets the acceptance flags for all rows in the current data table of a data set.
double * SDDS_GetColumnInDoubles(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves the data of a specified numerical column as an array of doubles, considering only rows mark...
int32_t SDDS_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:50
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_ReadPage(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
Definition SDDS_utils.c:421
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:474
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:318
int32_t SDDS_GetColumnType(SDDS_DATASET *SDDS_dataset, int32_t index)
Retrieves the data type of a column in the SDDS dataset by its index.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:380
Header file for routines used by SDDS command-line applications.
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
#define SDDS_NUMERIC_TYPE(type)
Checks if the given type identifier corresponds to any numeric type.
Definition SDDStypes.h:138
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:65
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
char * cp_str(char **s, char *t)
Copies a string, allocating memory for storage.
Definition cp_str.c:28
char * delete_chars(char *s, char *t)
Removes all occurrences of characters found in string t from string s.
long match_string(char *string, char **option, long n_options, long mode)
Matches a given string against an array of option strings based on specified modes.
long replaceFileAndBackUp(char *file, char *replacement)
Replaces a file with a replacement file and creates a backup of the original.
Definition replacefile.c:78
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
Definition scanargs.c:36
long processPipeOption(char **item, long items, unsigned long *flags)
Definition scanargs.c:357
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
Definition scanargs.c:391
void free_scanargs(SCANNED_ARG **scanned, int argc)
Definition scanargs.c:588
long scanItemList(unsigned long *flags, char **item, long *items, unsigned long mode,...)
Scans a list of items and assigns values based on provided keywords and types.
KEYED_EQUIVALENT ** MakeSortedKeyGroups(long *keyGroups, long keyType, void *data, long points)
Create sorted key groups from data.
long FindMatchingKeyGroup(KEYED_EQUIVALENT **keyGroup, long keyGroups, long keyType, void *searchKeyData, long reuse)
Find a matching key group for a search key.
char * tmpname(char *s)
Supplies a unique temporary filename.
Definition tmpname.c:37