SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
sddsxref.c
Go to the documentation of this file.
1/**
2 * @file sddsxref.c
3 * @brief Cross-references and merges SDDS data sets based on column matching and filtering.
4 *
5 * @details
6 * This program merges data from multiple SDDS (Self Describing Data Set) files into a single output file.
7 * It performs cross-referencing based on column matching, and supports selective transfer of columns,
8 * parameters, and arrays. The program also includes options for renaming and editing names to customize
9 * the output dataset.
10 *
11 * @section Usage
12 * ```
13 * sddsxref [<input1>] <input2> [<input3>...] [<output>]
14 * [-pipe[=input][,output]]
15 * [-ifis={column|parameter|array},<name>[,...]]
16 * [-ifnot={parameter|column|array},<name>[,...]]
17 * [-transfer={parameter|array},<name>[,...]]
18 * [-take=<column-name>[,...]]
19 * [-leave=<column-name>[,...]]
20 * [-replace=column|parameter|array,<name list>]
21 * [-fillIn]
22 * [-reuse[=[rows][,page]]]
23 * [-match=<column-name>[=<column-name>]]
24 * [-wildMatch=<column-name>[=<column-name>]]
25 * [-rename={column|parameter|array},<oldname>=<newname>[,...]]
26 * [-editnames={column|parameter|array},<wildcard-string>,<edit-string>]
27 * [-equate=<column-name>[=<column-name>]]
28 * [-majorOrder=row|column]
29 * ```
30 *
31 * @section Options
32 * | Required | Description |
33 * |---------------------------------------|---------------------------------------------------------------------------------------|
34 * | `<input2>` | The second input file for cross-referencing. |
35 *
36 * | Optional | Description |
37 * |---------------------------------------|---------------------------------------------------------------------------------------|
38 * | `-pipe` | Use standard input/output streams. |
39 * | `-ifis` | Filters data that must exist in the input files. |
40 * | `-ifnot` | Filters data that must not exist in the input files. |
41 * | `-transfer` | Specifies parameters or arrays to transfer from reference files into the output. |
42 * | `-take` | Specifies columns to be taken from reference files and added to the output dataset. |
43 * | `-leave` | Specifies columns not to be taken from reference files. Overrides the `-take` option for these columns. |
44 * | `-replace` | Replaces data in the output based on the specified types and names. |
45 * | `-fillIn` | Fills in NULL or zero values for unmatched rows in the output. |
46 * | `-reuse` | Allows reusing rows or pages from the reference file during cross-referencing. |
47 * | `-match` | Matches columns between input files for data integration. |
48 * | `-wildMatch` | Matches columns using wildcard patterns. |
49 * | `-rename` | Renames specified columns, parameters, or arrays in the output. |
50 * | `-editnames` | Edits names of specified entities. |
51 * | `-equate` | Matches columns based on equality conditions. |
52 * | `-majorOrder` | Specifies the major order of data in the output. Defaults to the input's order. |
53 *
54 * @subsection Incompatibilities
55 * - `-equate` is incompatible with:
56 * - `-match`
57 * - Only one of the following may be specified:
58 * - `-wildMatch`
59 * - `-match`
60 * - For `-reuse`:
61 * - Requires specifying rows, pages, or both.
62 *
63 * @copyright
64 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
65 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
66 *
67 * @license
68 * This file is distributed under the terms of the Software License Agreement
69 * found in the file LICENSE included with this distribution.
70 *
71 * @author
72 * M. Borland, C. Saunders, R. Soliday, L. Emery, H. Shang
73 */
74
75#include "mdb.h"
76#include "SDDS.h"
77#include "SDDSaps.h"
78#include "scan.h"
79#include <ctype.h>
80
81/* Enumeration for option types */
82enum option_type {
83 SET_TAKE_COLUMNS,
84 SET_LEAVE_COLUMNS,
85 SET_MATCH_COLUMN,
86 SET_EQUATE_COLUMN,
87 SET_TRANSFER,
88 SET_REUSE,
89 SET_IFNOT,
90 SET_NOWARNINGS,
91 SET_IFIS,
92 SET_PIPE,
93 SET_FILLIN,
94 SET_RENAME,
95 SET_EDIT_NAMES,
96 SET_WILD_MATCH,
97 SET_MAJOR_ORDER,
98 SET_REPLACE,
99 N_OPTIONS
100};
101
102#define COLUMN_MODE 0
103#define PARAMETER_MODE 1
104#define ARRAY_MODE 2
105#define MODES 3
106static char *mode_name[MODES] = {
107 "column",
108 "parameter",
109 "array",
110};
111
112#define COLUMN_REPLACE 0
113#define PARAMETER_REPLACE 1
114#define ARRAY_REPLACE 2
115#define REPLACE_TYPES 3
116static char *replace_type[REPLACE_TYPES] = {
117 "column", "parameter", "array"};
118
119#define PARAMETER_TRANSFER 0
120#define ARRAY_TRANSFER 1
121#define TRANSFER_TYPES 2
122static char *transfer_type[TRANSFER_TYPES] = {
123 "parameter", "array"};
124
125typedef struct
126{
127 char *name;
128 long type;
130
131typedef struct
132{
133 char **new_column;
134 char **new_parameter;
135 char **new_array;
136 char **orig_column;
137 char **orig_parameter;
138 char **orig_array;
139 int32_t columns;
140 int32_t parameters;
141 int32_t arrays;
142} REFDATA;
143
144/* Structure for getting edit names */
145typedef struct
146{
147 char *match_string;
148 char *edit_string;
150
151long expandTransferRequests(char ***match, int32_t *matches, long type, TRANSFER_DEFINITION *transfer,
152 long transfers, SDDS_DATASET *inSet);
153
154void add_newnames(SDDS_DATASET *SDDS_dataset, REFDATA *new_data, REFDATA rename_data,
155 EDIT_NAME_REQUEST *edit_column_request, long edit_column_requests,
156 EDIT_NAME_REQUEST *edit_parameter_request, long edit_parameter_requests,
157 EDIT_NAME_REQUEST *edit_array_request, long edit_array_requests, long filenumber);
158
159char **process_editnames(char **orig_name, long **orig_flags, long orig_names, EDIT_NAME_REQUEST *edit_request,
160 long edit_requests, long filenumber);
161long CopyRowToNewColumn(SDDS_DATASET *target, int64_t target_row, SDDS_DATASET *source, int64_t source_row,
162 REFDATA new_data, long columns, char *input2);
163long CopyParametersFromSecondInput(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, REFDATA new_data);
164long CopyArraysFromSecondInput(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, REFDATA new_data);
165
166typedef char *STRING_PAIR[2];
167
168char *option[N_OPTIONS] = {
169 "take", "leave", "match", "equate", "transfer", "reuse", "ifnot",
170 "nowarnings", "ifis", "pipe", "fillin", "rename", "editnames", "wildmatch", "majorOrder", "replace"};
171
172char *USAGE =
173 "Usage:\n"
174 " sddsxref [<input1>] <input2> [<input3>...] [<output>]\n\n"
175 "Options:\n"
176 " -pipe[=input][,output]\n"
177 " Enable piping. Optionally specify input and/or output streams.\n"
178 " -ifis={column|parameter|array},<name>[,...]\n"
179 " Specify names of parameters, arrays, or columns that must exist in <input1>.\n"
180 " -ifnot={parameter|column|array},<name>[,...]\n"
181 " Specify names of parameters, arrays, or columns that must not exist in <input1>.\n"
182 " -transfer={parameter|array},<name>[,...]\n"
183 " Specify parameters or arrays to transfer from <input2>.\n"
184 " -take=<column-name>[,...]\n"
185 " Specify columns to take from <input2>.\n"
186 " -leave=<column-name>[,...]\n"
187 " Specify columns not to take from <input2>. Overrides -take for specified columns.\n"
188 " Use -leave=* to exclude all columns.\n"
189 " -replace=column|parameter|array,<name list>\n"
190 " Replace specified columns, parameters, or arrays in <input1> with those from subsequent input files.\n"
191 " -fillIn\n"
192 " Fill in NULL and 0 values in rows where no match is found. By default, such rows are omitted.\n"
193 " -reuse[=[rows][,page]]\n"
194 " Allow reuse of rows from <input2>. Use -reuse=page to restrict to the first page of <input2>.\n"
195 " -match=<column-name>[=<column-name>]\n"
196 " Specify columns to match between <input1> and <input2> for data selection and placement.\n"
197 " -wildMatch=<column-name>[=<column-name>]\n"
198 " Similar to -match, but allows wildcards in the matching data from <input2>.\n"
199 " -rename={column|parameter|array},<oldname>=<newname>[,...]\n"
200 " Rename specified columns, parameters, or arrays in the output data set.\n"
201 " -editnames={column|parameter|array},<wildcard-string>,<edit-string>\n"
202 " Edit names of specified entities using wildcard patterns and edit commands.\n"
203 " -equate=<column-name>[=<column-name>]\n"
204 " Equate columns between <input1> and <input2> for data matching based on equality.\n"
205 " -majorOrder=row|column\n"
206 " Specify the major order of data in the output (row or column). Defaults to the order of <input1>.\n"
207 "Program by Michael Borland. (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")\n";
208
209int main(int argc, char **argv) {
210 SDDS_DATASET SDDS_1, SDDS_output;
211 SDDS_DATASET *SDDS_ref;
212 REFDATA *new_data, rename_data, *take_RefData, *replace_RefData;
213 long j, i_arg, reuse, reusePage, endWarning, k;
214 int64_t i, i1, i2, i3, rows1, rows2, rows2Max;
215 SCANNED_ARG *s_arg;
216 char s[200], *ptr;
217
218 char **take_column, **leave_column, **replace_column, **replace_parameter, **replace_array, **output_column = NULL;
219 char **inputfile, **referfile;
220 char **match_column, **equate_column;
221 long take_columns, replace_columns, leave_columns, match_columns, equate_columns, leave_all_columns, replace_parameters, replace_arrays;
222 int32_t output_columns = 0;
223 char *input1, *input2, *output;
224 long tmpfile_used, retval1, retval2, inputfiles, referfiles;
225 long wildMatch;
226 TRANSFER_DEFINITION *transfer;
227 long transfers;
228 long warnings;
229 IFITEM_LIST ifnot_item, ifis_item;
230 unsigned long pipeFlags, majorOrderFlag;
231 long fillIn, keyGroups = 0;
232 KEYED_EQUIVALENT **keyGroup = NULL;
233 long outputInitialized;
234 int z, it, itm, datatype1, datatype2;
235 long col;
236 int firstRun, copyInput1Only;
237 char **string1, **string2;
238 double *value1, *value2;
239 long matched;
240 short columnMajorOrder = -1;
241
242 EDIT_NAME_REQUEST *edit_column_request, *edit_parameter_request, *edit_array_request;
243 long edit_column_requests, edit_parameter_requests, edit_array_requests;
244
246 argc = scanargs(&s_arg, argc, argv);
247 if (argc < 3) {
248 fprintf(stderr, "%s", USAGE);
249 exit(EXIT_FAILURE);
250 }
251
252 SDDS_ref = NULL;
253 take_RefData = replace_RefData = NULL;
254 new_data = NULL;
255
256 rename_data.columns = rename_data.parameters = rename_data.arrays = 0;
257 rename_data.new_column = rename_data.orig_column = rename_data.new_parameter = rename_data.orig_parameter = rename_data.new_array = rename_data.orig_array = NULL;
258 edit_column_request = edit_parameter_request = edit_array_request = NULL;
259 edit_column_requests = edit_parameter_requests = edit_array_requests = 0;
260
261 input1 = input2 = output = NULL;
262 take_column = leave_column = replace_column = replace_parameter = replace_array = NULL;
263 match_column = equate_column = NULL;
264 inputfile = referfile = NULL;
265 take_columns = leave_columns = replace_columns = match_columns = equate_columns = reuse = reusePage = replace_parameters = replace_arrays = 0;
266 tmpfile_used = inputfiles = referfiles = 0;
267 transfer = NULL;
268 transfers = 0;
269 ifnot_item.items = ifis_item.items = 0;
270 warnings = 1;
271 pipeFlags = 0;
272 fillIn = 0;
273 outputInitialized = 0;
274 rows1 = rows2 = output_columns = 0;
275 string1 = string2 = NULL;
276 wildMatch = 0;
277
278 for (i_arg = 1; i_arg < argc; i_arg++) {
279 if (s_arg[i_arg].arg_type == OPTION) {
280 delete_chars(s_arg[i_arg].list[0], "_");
281 switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
282 case SET_MAJOR_ORDER:
283 majorOrderFlag = 0;
284 s_arg[i_arg].n_items--;
285 if (s_arg[i_arg].n_items > 0 &&
286 (!scanItemList(&majorOrderFlag, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
287 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
288 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
289 SDDS_Bomb("invalid -majorOrder syntax/values");
290 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
291 columnMajorOrder = 1;
292 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
293 columnMajorOrder = 0;
294 break;
295 case SET_LEAVE_COLUMNS:
296 if (s_arg[i_arg].n_items < 2)
297 SDDS_Bomb("invalid -leave syntax");
298 leave_column = trealloc(leave_column, sizeof(*leave_column) * (leave_columns + s_arg[i_arg].n_items - 1));
299 for (i = 1; i < s_arg[i_arg].n_items; i++)
300 leave_column[i - 1 + leave_columns] = s_arg[i_arg].list[i];
301 leave_columns += s_arg[i_arg].n_items - 1;
302 break;
303 case SET_TAKE_COLUMNS:
304 if (s_arg[i_arg].n_items < 2)
305 SDDS_Bomb("invalid -take syntax");
306 take_column = trealloc(take_column, sizeof(*take_column) * (take_columns + s_arg[i_arg].n_items - 1));
307 for (i = 1; i < s_arg[i_arg].n_items; i++)
308 take_column[i - 1 + take_columns] = s_arg[i_arg].list[i];
309 take_columns += s_arg[i_arg].n_items - 1;
310 break;
311 case SET_WILD_MATCH:
312 wildMatch = 1;
313 /* fall-through to SET_MATCH_COLUMN */
314 case SET_MATCH_COLUMN:
315 if (s_arg[i_arg].n_items != 2)
316 SDDS_Bomb("invalid -match or -wildMatch syntax");
317 if (match_columns != 0)
318 SDDS_Bomb("only one -match or -wildMatch option may be given");
319 match_column = tmalloc(sizeof(*match_column) * 2);
320 if ((ptr = strchr(s_arg[i_arg].list[1], '=')))
321 *ptr++ = 0;
322 else
323 ptr = s_arg[i_arg].list[1];
324 match_column[0] = s_arg[i_arg].list[1];
325 match_column[1] = ptr;
326 match_columns = 1;
327 break;
328 case SET_EQUATE_COLUMN:
329 if (s_arg[i_arg].n_items != 2)
330 SDDS_Bomb("invalid -equate syntax");
331 if (equate_columns != 0)
332 SDDS_Bomb("only one -equate option may be given");
333 equate_column = tmalloc(sizeof(*equate_column) * 2);
334 if ((ptr = strchr(s_arg[i_arg].list[1], '=')))
335 *ptr++ = 0;
336 else
337 ptr = s_arg[i_arg].list[1];
338 equate_column[0] = s_arg[i_arg].list[1];
339 equate_column[1] = ptr;
340 equate_columns = 1;
341 break;
342 case SET_REPLACE:
343 if (s_arg[i_arg].n_items < 3)
344 SDDS_Bomb("invalid -replace syntax");
345 switch (match_string(s_arg[i_arg].list[1], replace_type, REPLACE_TYPES, 0)) {
346 case COLUMN_REPLACE:
347 replace_column = trealloc(replace_column, sizeof(*replace_column) * (replace_columns + s_arg[i_arg].n_items - 2));
348 for (i = 2; i < s_arg[i_arg].n_items; i++)
349 replace_column[i - 2 + replace_columns] = s_arg[i_arg].list[i];
350 replace_columns += s_arg[i_arg].n_items - 2;
351 break;
352 case PARAMETER_REPLACE:
353 replace_parameter = trealloc(replace_parameter, sizeof(*replace_parameter) * (replace_parameters + s_arg[i_arg].n_items - 2));
354 for (i = 2; i < s_arg[i_arg].n_items; i++)
355 replace_parameter[i - 2 + replace_parameters] = s_arg[i_arg].list[i];
356 replace_parameters += s_arg[i_arg].n_items - 2;
357 break;
358 case ARRAY_REPLACE:
359 replace_array = trealloc(replace_array, sizeof(*replace_array) * (replace_arrays + s_arg[i_arg].n_items - 2));
360 for (i = 2; i < s_arg[i_arg].n_items; i++)
361 replace_array[i - 2 + replace_arrays] = s_arg[i_arg].list[i];
362 replace_arrays += s_arg[i_arg].n_items - 2;
363 break;
364 default:
365 SDDS_Bomb("unknown type of transfer");
366 break;
367 }
368 break;
369 case SET_TRANSFER:
370 if (s_arg[i_arg].n_items < 3)
371 SDDS_Bomb("invalid -transfer syntax");
372 transfer = trealloc(transfer, sizeof(*transfer) * (transfers + s_arg[i_arg].n_items - 2));
373 switch (match_string(s_arg[i_arg].list[1], transfer_type, TRANSFER_TYPES, 0)) {
374 case PARAMETER_TRANSFER:
375 for (i = 2; i < s_arg[i_arg].n_items; i++) {
376 transfer[i - 2 + transfers].type = PARAMETER_TRANSFER;
377 transfer[i - 2 + transfers].name = s_arg[i_arg].list[i];
378 }
379 break;
380 case ARRAY_TRANSFER:
381 for (i = 2; i < s_arg[i_arg].n_items; i++) {
382 transfer[i - 2 + transfers].type = ARRAY_TRANSFER;
383 transfer[i - 2 + transfers].name = s_arg[i_arg].list[i];
384 }
385 break;
386 default:
387 SDDS_Bomb("unknown type of transfer");
388 break;
389 }
390 transfers += s_arg[i_arg].n_items - 2;
391 break;
392 case SET_REUSE:
393 if (s_arg[i_arg].n_items == 1)
394 reuse = 1;
395 else {
396 char *reuseOptions[2] = {"rows", "page"};
397 for (i = 1; i < s_arg[i_arg].n_items; i++) {
398 switch (match_string(s_arg[i_arg].list[i], reuseOptions, 2, 0)) {
399 case 0:
400 reuse = 1;
401 break;
402 case 1:
403 reusePage = 1;
404 break;
405 default:
406 SDDS_Bomb("unknown reuse keyword");
407 break;
408 }
409 }
410 }
411 break;
412 case SET_IFNOT:
413 if (s_arg[i_arg].n_items < 3)
414 SDDS_Bomb("invalid -ifnot usage");
415 add_ifitem(&ifnot_item, s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1);
416 break;
417 case SET_NOWARNINGS:
418 warnings = 0;
419 break;
420 case SET_IFIS:
421 if (s_arg[i_arg].n_items < 3)
422 SDDS_Bomb("invalid -ifis usage");
423 add_ifitem(&ifis_item, s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1);
424 break;
425 case SET_PIPE:
426 if (!processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
427 SDDS_Bomb("invalid -pipe syntax");
428 break;
429 case SET_FILLIN:
430 fillIn = 1;
431 break;
432 case SET_RENAME:
433 if (s_arg[i_arg].n_items < 3)
434 SDDS_Bomb("invalid -rename syntax");
435 switch (match_string(s_arg[i_arg].list[1], mode_name, MODES, 0)) {
436 case COLUMN_MODE:
437 k = rename_data.columns;
438 rename_data.new_column = trealloc(rename_data.new_column, sizeof(char *) * (k + s_arg[i_arg].n_items - 2));
439 rename_data.orig_column = trealloc(rename_data.orig_column, sizeof(char *) * (k + s_arg[i_arg].n_items - 2));
440 for (i = 2; i < s_arg[i_arg].n_items; i++) {
441 if (!(ptr = strchr(s_arg[i_arg].list[i], '=')))
442 SDDS_Bomb("invalid -rename syntax");
443 *ptr++ = 0;
444 rename_data.orig_column[k + i - 2] = s_arg[i_arg].list[i];
445 rename_data.new_column[k + i - 2] = ptr;
446 }
447 rename_data.columns += s_arg[i_arg].n_items - 2;
448 break;
449 case PARAMETER_MODE:
450 k = rename_data.parameters;
451 rename_data.new_parameter = trealloc(rename_data.new_parameter, sizeof(char *) * (k + s_arg[i_arg].n_items - 2));
452 rename_data.orig_parameter = trealloc(rename_data.orig_parameter, sizeof(char *) * (k + s_arg[i_arg].n_items - 2));
453 for (i = 2; i < s_arg[i_arg].n_items; i++) {
454 if (!(ptr = strchr(s_arg[i_arg].list[i], '=')))
455 SDDS_Bomb("invalid -rename syntax");
456 *ptr++ = 0;
457 rename_data.orig_parameter[k + i - 2] = s_arg[i_arg].list[i];
458 rename_data.new_parameter[k + i - 2] = ptr;
459 }
460 rename_data.parameters += s_arg[i_arg].n_items - 2;
461 break;
462 case ARRAY_MODE:
463 k = rename_data.arrays;
464 rename_data.new_array = trealloc(rename_data.new_array, sizeof(char *) * (k + s_arg[i_arg].n_items - 2));
465 rename_data.orig_array = trealloc(rename_data.orig_array, sizeof(char *) * (k + s_arg[i_arg].n_items - 2));
466 for (i = 2; i < s_arg[i_arg].n_items; i++) {
467 if (!(ptr = strchr(s_arg[i_arg].list[i], '=')))
468 SDDS_Bomb("invalid -rename syntax");
469 *ptr++ = 0;
470 rename_data.orig_array[k + i - 2] = s_arg[i_arg].list[i];
471 rename_data.new_array[k + i - 2] = ptr;
472 }
473 rename_data.arrays += s_arg[i_arg].n_items - 2;
474 break;
475 default:
476 SDDS_Bomb("invalid -rename syntax: specify column, parameter, or array keyword");
477 break;
478 }
479 break;
480 case SET_EDIT_NAMES:
481 if (s_arg[i_arg].n_items != 4)
482 SDDS_Bomb("invalid -editnames syntax");
483 switch (match_string(s_arg[i_arg].list[1], mode_name, MODES, 0)) {
484 case COLUMN_MODE:
485 edit_column_request = trealloc(edit_column_request, sizeof(*edit_column_request) * (edit_column_requests + 1));
486 edit_column_request[edit_column_requests].match_string = s_arg[i_arg].list[2];
487 edit_column_request[edit_column_requests].edit_string = s_arg[i_arg].list[3];
488 edit_column_requests++;
489 break;
490 case PARAMETER_MODE:
491 edit_parameter_request = trealloc(edit_parameter_request, sizeof(*edit_parameter_request) * (edit_parameter_requests + 1));
492 edit_parameter_request[edit_parameter_requests].match_string = s_arg[i_arg].list[2];
493 edit_parameter_request[edit_parameter_requests].edit_string = s_arg[i_arg].list[3];
494 edit_parameter_requests++;
495 break;
496 case ARRAY_MODE:
497 edit_array_request = trealloc(edit_array_request, sizeof(*edit_array_request) * (edit_array_requests + 1));
498 edit_array_request[edit_array_requests].match_string = s_arg[i_arg].list[2];
499 edit_array_request[edit_array_requests].edit_string = s_arg[i_arg].list[3];
500 edit_array_requests++;
501 break;
502 default:
503 SDDS_Bomb("invalid -editnames syntax: specify column, parameter, or array keyword");
504 break;
505 }
506 break;
507 default:
508 fprintf(stderr, "error: unknown switch: %s\n", s_arg[i_arg].list[0]);
509 SDDS_Bomb(NULL);
510 break;
511 }
512 } else {
513 inputfile = trealloc(inputfile, sizeof(*inputfile) * (inputfiles + 1));
514 inputfile[inputfiles++] = s_arg[i_arg].list[0];
515 }
516 }
517
518 if (inputfiles == 0) {
519 SDDS_Bomb("too few reference files given");
520 } else {
521 if (!(pipeFlags & USE_STDIN) && !(pipeFlags & USE_STDOUT)) {
522 if (inputfiles < 2) {
523 SDDS_Bomb("too few reference files given");
524 } else if (inputfiles == 2) {
525 input1 = output = inputfile[0];
526 referfile = trealloc(referfile, sizeof(*referfile) * (referfiles + 1));
527 referfile[0] = inputfile[1];
528 referfiles++;
529 } else {
530 input1 = inputfile[0];
531 output = inputfile[--inputfiles];
532 for (z = 1; z < inputfiles; z++) {
533 referfile = trealloc(referfile, sizeof(*referfile) * (referfiles + 1));
534 referfile[z - 1] = inputfile[z];
535 referfiles++;
536 }
537 }
538 } else if (!(pipeFlags & USE_STDIN) && (pipeFlags & USE_STDOUT)) {
539 if (inputfiles < 2) {
540 SDDS_Bomb("too few reference files given");
541 } else {
542 input1 = inputfile[0];
543 for (z = 1; z < inputfiles; z++) {
544 referfile = trealloc(referfile, sizeof(*referfile) * (referfiles + 1));
545 referfile[z - 1] = inputfile[z];
546 referfiles++;
547 }
548 }
549 } else if ((pipeFlags & USE_STDIN) && !(pipeFlags & USE_STDOUT)) {
550 if (inputfiles < 2) {
551 SDDS_Bomb("too few reference files given");
552 } else {
553 output = inputfile[--inputfiles];
554 for (z = 0; z < inputfiles; z++) {
555 referfile = trealloc(referfile, sizeof(*referfile) * (referfiles + 1));
556 referfile[z] = inputfile[z];
557 referfiles++;
558 }
559 }
560 } else {
561 for (z = 0; z < inputfiles; z++) {
562 referfile = trealloc(referfile, sizeof(*referfile) * (referfiles + 1));
563 referfile[z] = inputfile[z];
564 referfiles++;
565 }
566 }
567 }
568
569 processFilenames("sddsxref", &input1, &output, pipeFlags, !warnings, &tmpfile_used);
570
571 if (equate_columns && match_columns)
572 SDDS_Bomb("only one of -equate or -match may be given");
573
574 if (!SDDS_InitializeInput(&SDDS_1, input1)) {
575 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
576 exit(EXIT_FAILURE);
577 }
578
579 if (!check_ifitems(&SDDS_1, &ifnot_item, 0, warnings) || !check_ifitems(&SDDS_1, &ifis_item, 1, warnings))
580 exit(EXIT_SUCCESS);
581
582 for (it = 0; it < ifnot_item.items; it++) {
583 switch (ifnot_item.type[it]) {
584 case COLUMN_BASED:
585 leave_column = trealloc(leave_column, sizeof(*leave_column) * (leave_columns + 1));
586 leave_column[leave_columns] = ifnot_item.name[it];
587 leave_columns++;
588 break;
589 case PARAMETER_BASED:
590 for (itm = 0; itm < transfers; itm++) {
591 if (strcmp(transfer[itm].name, ifnot_item.name[it]) == 0) {
592 SDDS_Bomb("Excluded item is a part of -transfer list.");
593 exit(EXIT_FAILURE);
594 }
595 }
596 break;
597 case ARRAY_BASED:
598 for (itm = 0; itm < transfers; itm++) {
599 if (strcmp(transfer[itm].name, ifnot_item.name[it]) == 0) {
600 SDDS_Bomb("Excluded item is a part of -transfer list.");
601 exit(EXIT_FAILURE);
602 }
603 }
604 break;
605 default:
606 SDDS_Bomb("internal error---unknown ifitem type");
607 exit(EXIT_FAILURE);
608 break;
609 }
610 }
611
612 /* Allocate memory for new_data */
613 new_data = malloc(sizeof(*new_data) * referfiles);
614 for (z = 0; z < referfiles; z++) {
615 SDDS_ref = trealloc(SDDS_ref, sizeof(*SDDS_ref) * (z + 1));
616 input2 = referfile[z];
617 if (!SDDS_InitializeInput(&SDDS_ref[z], input2)) {
618 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
619 exit(EXIT_FAILURE);
620 }
621
622 take_RefData = trealloc(take_RefData, sizeof(*take_RefData) * (z + 1));
623 take_RefData[z].columns = 0;
624 replace_RefData = trealloc(replace_RefData, sizeof(*replace_RefData) * (z + 1));
625 replace_RefData[z].columns = replace_RefData[z].parameters = replace_RefData[z].arrays = 0;
626
627 add_newnames(&SDDS_ref[z], &new_data[z], rename_data, edit_column_request, edit_column_requests,
628 edit_parameter_request, edit_parameter_requests, edit_array_request, edit_array_requests, z + 1);
629
630 if (SDDS_ColumnCount(&SDDS_ref[z])) {
631 SDDS_SetColumnFlags(&SDDS_ref[z], 1);
632 if (take_columns) {
633 SDDS_SetColumnFlags(&SDDS_ref[z], 0);
634 for (i = 0; i < take_columns; i++) {
635 if (!has_wildcards(take_column[i]) && SDDS_GetColumnIndex(&SDDS_ref[z], take_column[i]) < 0) {
636 sprintf(s, "error: column %s not found in file %s take_columns %ld SDDS_ref[z] %" PRId64 "\n", take_column[i], input2, take_columns, SDDS_ref[z].n_rows);
637 SDDS_SetError(s);
638 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
639 }
640 if (!SDDS_SetColumnsOfInterest(&SDDS_ref[z], SDDS_MATCH_STRING, take_column[i], SDDS_OR))
641 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
642 }
643 }
644
645 leave_all_columns = 0;
646 if (leave_columns == 1 && strcmp(leave_column[0], "*") == 0)
647 leave_all_columns = 1;
648 else {
649 if (!take_columns)
650 SDDS_SetColumnFlags(&SDDS_ref[z], 1);
651 for (i = 0; i < leave_columns; i++) {
652 if (!has_wildcards(leave_column[i]) &&
653 SDDS_GetColumnIndex(&SDDS_ref[z], leave_column[i]) < 0)
654 continue;
655 if (!SDDS_SetColumnsOfInterest(&SDDS_ref[z], SDDS_MATCH_STRING, leave_column[i], SDDS_AND | SDDS_NEGATE_MATCH))
656 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
657 }
658
659 if (!(take_RefData[z].orig_column = (char **)SDDS_GetColumnNames(&SDDS_ref[z], &take_RefData[z].columns))) {
660 SDDS_SetError("error: no columns selected to take from input file");
661 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
662 }
663 }
664 if (replace_columns) {
665 SDDS_SetColumnFlags(&SDDS_ref[z], 0);
666 for (i = 0; i < replace_columns; i++) {
667 if (!has_wildcards(replace_column[i]) && SDDS_GetColumnIndex(&SDDS_ref[z], replace_column[i]) < 0) {
668 sprintf(s, "error: column %s not found in file %s replace_columns %ld SDDS_ref[z] %" PRId64 "\n", replace_column[i], input2, replace_columns, SDDS_ref[z].n_rows);
669 SDDS_SetError(s);
670 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
671 }
672 if (!SDDS_SetColumnsOfInterest(&SDDS_ref[z], SDDS_MATCH_STRING, replace_column[i], SDDS_OR))
673 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
674 }
675 if (!(replace_RefData[z].orig_column = (char **)SDDS_GetColumnNames(&SDDS_ref[z], &replace_RefData[z].columns))) {
676 SDDS_SetError("error: no columns selected to replace from input file");
677 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
678 }
679 }
680 if (match_columns) {
681 if ((j = SDDS_GetColumnIndex(&SDDS_1, match_column[0])) < 0 ||
682 SDDS_GetColumnType(&SDDS_1, j) != SDDS_STRING) {
683 sprintf(s, "error: column %s not found or not string type in file %s", match_column[0], input1 ? input1 : "stdin");
684 SDDS_SetError(s);
685 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
686 }
687 if ((j = SDDS_GetColumnIndex(&SDDS_ref[z], match_column[1])) < 0 ||
688 SDDS_GetColumnType(&SDDS_ref[z], j) != SDDS_STRING) {
689 sprintf(s, "error: column %s not found or not string type in file %s", match_column[1], input2);
690 SDDS_SetError(s);
691 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
692 }
693 }
694 if (equate_columns) {
695 if ((j = SDDS_GetColumnIndex(&SDDS_1, equate_column[0])) < 0 ||
697 sprintf(s, "error: column %s not found or not numeric type in file %s", equate_column[0], input1 ? input1 : "stdin");
698 SDDS_SetError(s);
699 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
700 }
701 if ((j = SDDS_GetColumnIndex(&SDDS_ref[z], equate_column[1])) < 0 ||
702 !SDDS_NUMERIC_TYPE(SDDS_GetColumnType(&SDDS_ref[z], j))) {
703 sprintf(s, "error: column %s not found or not numeric type in file %s", equate_column[1], input2);
704 SDDS_SetError(s);
705 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
706 }
707 }
708 } else {
709 take_RefData[z].columns = 0;
710 leave_all_columns = 1;
711 }
712 if (!take_RefData[z].columns && !leave_all_columns && warnings)
713 fprintf(stderr, "warning: there are no columns being taken from %s that are not already in %s\n", input2, input1 ? input1 : "stdin");
714
715 if (leave_all_columns)
716 take_RefData[z].columns = 0;
717
718 if (!outputInitialized) {
719 if (!SDDS_InitializeCopy(&SDDS_output, &SDDS_1, output, "w")) {
720 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
721 exit(EXIT_FAILURE);
722 }
723 outputInitialized = 1;
724 if (columnMajorOrder != -1)
725 SDDS_output.layout.data_mode.column_major = columnMajorOrder;
726 else
727 SDDS_output.layout.data_mode.column_major = SDDS_1.layout.data_mode.column_major;
728 }
729
730 /* Get the new name for new_data if there is a match of original name */
731 if (take_RefData[z].columns)
732 take_RefData[z].new_column = (char **)malloc(sizeof(char *) * take_RefData[z].columns);
733
734 for (i = 0; i < take_RefData[z].columns; i++) {
735 k = 0;
736 /* If there are new names (renamed or edited), find the corresponding original name index,
737 and assign the new name to take_RefData */
738 if (new_data[z].columns) {
739 k = match_string(take_RefData[z].orig_column[i], new_data[z].orig_column, new_data[z].columns, EXACT_MATCH);
740 if (k == -1)
741 SDDS_CopyString(&take_RefData[z].new_column[i], take_RefData[z].orig_column[i]);
742 else
743 SDDS_CopyString(&take_RefData[z].new_column[i], new_data[z].new_column[k]);
744 } else
745 SDDS_CopyString(&take_RefData[z].new_column[i], take_RefData[z].orig_column[i]);
746 if (SDDS_GetColumnIndex(&SDDS_output, take_RefData[z].new_column[i]) >= 0) {
747 free(take_RefData[z].new_column[i]);
748 free(take_RefData[z].orig_column[i]);
749 for (j = i; j < take_RefData[z].columns - 1; j++)
750 take_RefData[z].orig_column[j] = take_RefData[z].orig_column[j + 1];
751 take_RefData[z].columns -= 1;
752 i--;
753 if (take_RefData[z].columns == 0)
754 break;
755 } else {
756 /* Transfer column definition */
757 if (!SDDS_TransferColumnDefinition(&SDDS_output, &SDDS_ref[z], take_RefData[z].orig_column[i], take_RefData[z].new_column[i]))
758 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
759 }
760 }
761
762 if (!take_RefData[z].columns && !leave_all_columns && warnings)
763 fprintf(stderr, "warning: there are no columns being taken from %s that are not already in %s\n", input2, input1 ? input1 : "stdin");
764 output_columns = 0;
765 if (take_RefData[z].columns &&
766 (!(output_column = (char **)SDDS_GetColumnNames(&SDDS_output, &output_columns)) || output_columns == 0)) {
767 SDDS_SetError("Problem getting output column names");
768 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
769 }
770 if (output_columns) {
771 for (i = 0; i < output_columns; i++)
772 free(output_column[i]);
773 free(output_column);
774 }
775 /* Check if the column in replace_column exists in the output file */
776 for (i = 0; i < replace_RefData[z].columns; i++) {
777 if (SDDS_GetColumnIndex(&SDDS_1, replace_RefData[z].orig_column[i]) < 0) {
778 if (warnings) {
779 fprintf(stderr, "Warning, %s replace column does not exist in the input1, ignore.\n", replace_RefData[z].orig_column[i]);
780 }
781 } else {
782 /* Check if column types are the same */
783 j = SDDS_GetColumnIndex(&SDDS_ref[z], replace_RefData[z].orig_column[i]);
784 k = SDDS_GetColumnIndex(&SDDS_output, replace_RefData[z].orig_column[i]);
785 datatype1 = SDDS_GetColumnType(&SDDS_ref[z], j);
786 datatype2 = SDDS_GetColumnType(&SDDS_output, k);
787 if (datatype1 != datatype2 && (datatype1 == SDDS_STRING || datatype2 == SDDS_STRING)) {
788 if (warnings) {
789 if (datatype1 == SDDS_STRING)
790 fprintf(stderr, "Warning: cannot replace a numeric column with a string column, replace %s ignored.\n", replace_RefData[z].orig_column[i]);
791 if (datatype2 == SDDS_STRING)
792 fprintf(stderr, "Warning: cannot replace a string column with a numeric column, replace %s ignored.\n", replace_RefData[z].orig_column[i]);
793 }
794 } else {
795 if (datatype1 != datatype2) {
796 if (warnings)
797 fprintf(stderr, "Warning, replace column %s has different data type as the column in input1; redefining the column type\n", replace_RefData[z].orig_column[i]);
798 if (!SDDS_ChangeColumnInformation(&SDDS_output, "type", SDDS_type_name[datatype1 - 1], SDDS_PASS_BY_STRING | SDDS_SET_BY_NAME, replace_RefData[z].orig_column[i])) {
799 fprintf(stderr, "Problem redefining column type for %s\n", replace_RefData[z].orig_column[i]);
800 exit(EXIT_FAILURE);
801 }
802 }
803 /* Add replace_column to take_column, while the orig_name and new_name are the same */
804 take_RefData[z].orig_column = trealloc(take_RefData[z].orig_column, sizeof(*(take_RefData[z].orig_column)) * (take_RefData[z].columns + 1));
805 take_RefData[z].new_column = trealloc(take_RefData[z].new_column, sizeof(*(take_RefData[z].new_column)) * (take_RefData[z].columns + 1));
806 SDDS_CopyString(&take_RefData[z].orig_column[take_RefData[z].columns], replace_RefData[z].orig_column[i]);
807 SDDS_CopyString(&take_RefData[z].new_column[take_RefData[z].columns], replace_RefData[z].orig_column[i]);
808 take_RefData[z].columns++;
809 }
810 }
811 free(replace_RefData[z].orig_column[i]);
812 }
813
814 take_RefData[z].parameters = take_RefData[z].arrays = 0;
815 if (transfers) {
816 if (!expandTransferRequests(&take_RefData[z].orig_parameter, &take_RefData[z].parameters, PARAMETER_TRANSFER, transfer, transfers, &SDDS_ref[z]) ||
817 !expandTransferRequests(&take_RefData[z].orig_array, &take_RefData[z].arrays, ARRAY_TRANSFER, transfer, transfers, &SDDS_ref[z]))
818 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
819 }
820
821 /* Get the new name for parameters, define parameters for output */
822 if (take_RefData[z].parameters)
823 take_RefData[z].new_parameter = (char **)malloc(sizeof(char *) * take_RefData[z].parameters);
824 if (take_RefData[z].arrays)
825 take_RefData[z].new_array = (char **)malloc(sizeof(char *) * take_RefData[z].arrays);
826
827 for (i = 0; i < take_RefData[z].parameters; i++) {
828 k = 0;
829 if (new_data[z].parameters) {
830 k = match_string(take_RefData[z].orig_parameter[i], new_data[z].orig_parameter, new_data[z].parameters, EXACT_MATCH);
831 if (k != -1)
832 SDDS_CopyString(&take_RefData[z].new_parameter[i], new_data[z].new_parameter[k]);
833 else
834 SDDS_CopyString(&take_RefData[z].new_parameter[i], take_RefData[z].orig_parameter[i]);
835 } else
836 SDDS_CopyString(&take_RefData[z].new_parameter[i], take_RefData[z].orig_parameter[i]);
837 if (SDDS_GetParameterIndex(&SDDS_output, take_RefData[z].new_parameter[i]) >= 0) {
838 free(take_RefData[z].orig_parameter[i]);
839 free(take_RefData[z].new_parameter[i]);
840 for (col = i; col < take_RefData[z].parameters - 1; col++)
841 take_RefData[z].orig_parameter[col] = take_RefData[z].orig_parameter[col + 1];
842 take_RefData[z].parameters -= 1;
843 i--;
844 if (take_RefData[z].parameters == 0)
845 break;
846 } else {
847 if (!SDDS_TransferParameterDefinition(&SDDS_output, &SDDS_ref[z], take_RefData[z].orig_parameter[i], take_RefData[z].new_parameter[i]))
848 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
849 }
850 }
851 /* Get the new name for arrays, and define arrays for output */
852 for (i = 0; i < take_RefData[z].arrays; i++) {
853 k = 0;
854 if (new_data[z].arrays) {
855 k = match_string(take_RefData[z].orig_array[i], new_data[z].orig_array, new_data[z].arrays, EXACT_MATCH);
856 if (k == -1)
857 SDDS_CopyString(&take_RefData[z].new_array[i], take_RefData[z].orig_array[i]);
858 else
859 SDDS_CopyString(&take_RefData[z].new_array[i], new_data[z].new_array[k]);
860 } else
861 SDDS_CopyString(&take_RefData[z].new_array[i], take_RefData[z].orig_array[i]);
862 if (SDDS_GetArrayIndex(&SDDS_output, take_RefData[z].new_array[i]) >= 0) {
863 free(take_RefData[z].orig_array[i]);
864 free(take_RefData[z].new_array[i]);
865 for (col = i; col < take_RefData[z].arrays - 1; col++)
866 take_RefData[z].orig_array[col] = take_RefData[z].orig_array[col + 1];
867 take_RefData[z].arrays -= 1;
868 i--;
869 if (take_RefData[z].arrays == 0)
870 break;
871 } else {
872 if (!SDDS_TransferArrayDefinition(&SDDS_output, &SDDS_ref[z], take_RefData[z].orig_array[i], take_RefData[z].new_array[i]))
873 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
874 }
875 }
876
877 /* Check replace parameters and arrays, adding them to take_refData */
878 if (replace_parameters) {
879 for (i = 0; i < replace_parameters; i++) {
880 replace_RefData[z].parameters += SDDS_MatchParameters(&SDDS_ref[z], &replace_RefData[z].orig_parameter, SDDS_MATCH_STRING, FIND_ANY_TYPE, replace_parameter[i], SDDS_OR | SDDS_1_PREVIOUS);
881 }
882
883 /* Check if replace parameters exist in input1 */
884 for (i = 0; i < replace_RefData[z].parameters; i++) {
885 if (SDDS_GetParameterIndex(&SDDS_1, replace_RefData[z].orig_parameter[i]) < 0) {
886 if (warnings) {
887 fprintf(stderr, "Warning, parameter %s replace parameter does not exist in the input1, ignore.\n", replace_RefData[z].orig_parameter[i]);
888 }
889 } else {
890 /* Check if parameter types are the same */
891 j = SDDS_GetParameterIndex(&SDDS_ref[z], replace_RefData[z].orig_parameter[i]);
892 k = SDDS_GetParameterIndex(&SDDS_output, replace_RefData[z].orig_parameter[i]);
893 datatype1 = SDDS_GetParameterType(&SDDS_ref[z], j);
894 datatype2 = SDDS_GetParameterType(&SDDS_output, k);
895 if (datatype1 != datatype2 && (datatype1 == SDDS_STRING || datatype2 == SDDS_STRING)) {
896 if (warnings) {
897 if (datatype1 == SDDS_STRING)
898 fprintf(stderr, "Warning: cannot replace a numeric parameter with a string parameter, replace %s ignored.\n", replace_RefData[z].orig_parameter[i]);
899 if (datatype2 == SDDS_STRING)
900 fprintf(stderr, "Warning: cannot replace a string parameter with a numeric parameter, replace %s ignored.\n", replace_RefData[z].orig_parameter[i]);
901 }
902 } else {
903 if (datatype1 != datatype2) {
904 if (warnings)
905 fprintf(stderr, "Warning, replace parameter %s type is different from input1, redefining parameter type.\n", replace_RefData[z].orig_parameter[i]);
906
907 if (!SDDS_ChangeParameterInformation(&SDDS_output, "type", SDDS_type_name[datatype1 - 1], SDDS_PASS_BY_STRING | SDDS_SET_BY_NAME, replace_RefData[z].orig_parameter[i])) {
908 fprintf(stderr, "Problem redefining parameter type for %s\n", replace_RefData[z].orig_parameter[i]);
909 exit(EXIT_FAILURE);
910 }
911 }
912 /* Add replace_parameter to take_parameter, while the orig_name and new_name are the same */
913 take_RefData[z].orig_parameter = trealloc(take_RefData[z].orig_parameter, sizeof(*(take_RefData[z].orig_parameter)) * (take_RefData[z].parameters + 1));
914 take_RefData[z].new_parameter = trealloc(take_RefData[z].new_parameter, sizeof(*(take_RefData[z].new_parameter)) * (take_RefData[z].parameters + 1));
915 SDDS_CopyString(&take_RefData[z].orig_parameter[take_RefData[z].parameters], replace_RefData[z].orig_parameter[i]);
916 SDDS_CopyString(&take_RefData[z].new_parameter[take_RefData[z].parameters], replace_RefData[z].orig_parameter[i]);
917 take_RefData[z].parameters++;
918 }
919 }
920 free(replace_RefData[z].orig_parameter[i]);
921 }
922
923 if (replace_arrays) {
924 for (i = 0; i < replace_arrays; i++) {
925 replace_RefData[z].arrays += SDDS_MatchArrays(&SDDS_ref[z], &replace_RefData[z].orig_array, SDDS_MATCH_STRING, FIND_ANY_TYPE, replace_array[i], SDDS_OR | SDDS_1_PREVIOUS);
926 }
927 /* Check if replace arrays exist in input1 */
928 for (i = 0; i < replace_RefData[z].arrays; i++) {
929 if (SDDS_GetArrayIndex(&SDDS_1, replace_RefData[z].orig_array[i]) < 0) {
930 if (warnings) {
931 fprintf(stderr, "Warning, array %s replace array does not exist in the input, ignore.\n", replace_RefData[z].orig_array[i]);
932 }
933 } else {
934 /* Check if array types are the same */
935 j = SDDS_GetArrayIndex(&SDDS_ref[z], replace_RefData[z].orig_array[i]);
936 k = SDDS_GetArrayIndex(&SDDS_output, replace_RefData[z].orig_array[i]);
937 datatype1 = SDDS_GetArrayType(&SDDS_ref[z], j);
938 datatype2 = SDDS_GetArrayType(&SDDS_output, k);
939 if (datatype1 != datatype2 && (datatype1 == SDDS_STRING || datatype2 == SDDS_STRING)) {
940 if (warnings) {
941 if (datatype1 == SDDS_STRING)
942 fprintf(stderr, "Warning: cannot replace a numeric array with a string array, replace %s ignored.\n", replace_RefData[z].orig_array[i]);
943 if (datatype2 == SDDS_STRING)
944 fprintf(stderr, "Warning: cannot replace a string array with a numeric array, replace %s ignored.\n", replace_RefData[z].orig_array[i]);
945 }
946 } else {
947 if (datatype1 != datatype2) {
948 if (warnings)
949 fprintf(stderr, "Warning, replace array %s has different data type as the array in input1; redefining\n", replace_RefData[z].orig_array[i]);
950 if (!SDDS_ChangeArrayInformation(&SDDS_output, "type", SDDS_type_name[datatype1 - 1], SDDS_PASS_BY_STRING | SDDS_SET_BY_NAME, replace_RefData[z].orig_array[i])) {
951 fprintf(stderr, "Problem redefining array type for %s\n", replace_RefData[z].orig_array[i]);
952 exit(EXIT_FAILURE);
953 }
954 }
955 /* Add replace_array to take_array, while the orig_name and new_name are the same */
956 take_RefData[z].orig_array = trealloc(take_RefData[z].orig_array, sizeof(*(take_RefData[z].orig_array)) * (take_RefData[z].arrays + 1));
957 SDDS_CopyString(&take_RefData[z].orig_array[take_RefData[z].arrays], replace_RefData[z].orig_array[i]);
958 SDDS_CopyString(&take_RefData[z].new_array[take_RefData[z].arrays], replace_RefData[z].orig_array[i]);
959 take_RefData[z].arrays++;
960 }
961 }
962 free(replace_RefData[z].orig_array[i]);
963 }
964 }
965 }
966 }
967
968 if (!SDDS_WriteLayout(&SDDS_output))
969 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
970
971 free(leave_column);
972 if (take_columns) {
973 SDDS_FreeStringArray(take_column, take_columns);
974 free(take_column);
975 }
976
977 endWarning = 0;
978
979 while ((retval1 = SDDS_ReadPage(&SDDS_1)) > 0) {
980 copyInput1Only = 0;
981 rows1 = SDDS_CountRowsOfInterest(&SDDS_1);
982 if (!SDDS_StartPage(&SDDS_output, rows1)) {
983 SDDS_SetError("Problem starting output page");
984 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
985 }
986 if (fillIn && !SDDS_ClearPage(&SDDS_output)) {
987 SDDS_SetError("Problem clearing output page");
988 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
989 }
990 if (!SDDS_CopyParameters(&SDDS_output, &SDDS_1) ||
991 !SDDS_CopyArrays(&SDDS_output, &SDDS_1)) {
992 SDDS_SetError("Problem copying parameter or array data from first input file");
993 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
994 }
995
996 for (z = 0; z < referfiles; z++) {
997 input2 = referfile[z];
998 if (!reusePage) {
999 if ((retval2 = SDDS_ReadPage(&SDDS_ref[z])) <= 0 && !endWarning) {
1000 if (warnings)
1001 fprintf(stderr, "warning: %s ends prematurely\n", input2 ? input2 : "stdin");
1002 endWarning = 1;
1003 }
1004 } else {
1005 if (retval1 == 1 && (retval2 = SDDS_ReadPage(&SDDS_ref[z])) <= 0) {
1006 if (!endWarning && warnings)
1007 fprintf(stderr, "warning: %s has no data\n", input2 ? input2 : "stdin");
1008 endWarning = 1;
1009 } else
1010 SDDS_SetRowFlags(&SDDS_ref[z], 1);
1011 }
1012
1013 if (take_RefData[z].columns &&
1014 (!SDDS_SetColumnFlags(&SDDS_ref[z], 0) ||
1015 !SDDS_SetColumnsOfInterest(&SDDS_ref[z], SDDS_NAME_ARRAY, take_RefData[z].columns, take_RefData[z].orig_column)))
1016 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1017
1018 /* Copy parameters and arrays */
1019 if (!CopyParametersFromSecondInput(&SDDS_output, &SDDS_ref[z], take_RefData[z])) {
1020 SDDS_SetError("Problem copying parameter from second input file");
1021 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1022 }
1023 if (!CopyArraysFromSecondInput(&SDDS_output, &SDDS_ref[z], take_RefData[z])) {
1024 SDDS_SetError("Problem copying parameter from second input file");
1025 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1026 }
1027 }
1028
1029 firstRun = 1;
1030 for (z = rows2Max = 0; z < referfiles; z++) {
1031 input2 = referfile[z];
1032 rows2 = SDDS_CountRowsOfInterest(&SDDS_ref[z]);
1033 rows2Max = rows2 > rows2Max ? rows2 : rows2Max;
1034
1035 if (!firstRun) {
1036 /* DO NOT USE SDDS_CountRowsOfInterest because
1037 CopyRowToNewColumn and SDDS_AssertRowFlags expect
1038 the real row index and not the index of rows of interest */
1039 rows1 = SDDS_RowCount(&SDDS_output);
1040 }
1041 if (take_RefData[z].columns) {
1042 if (!rows2) {
1043 if (!SDDS_SetRowFlags(&SDDS_output, fillIn)) {
1044 SDDS_SetError("Problem setting row flags for output file.");
1045 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1046 }
1047 } else if (rows1) {
1048 if (match_columns) {
1049 if (firstRun) {
1050 if (!(string1 = (char **)SDDS_GetColumn(&SDDS_1, match_column[0]))) {
1051 fprintf(stderr, "Error: problem getting column %s from file %s\n", match_column[0], input1 ? input1 : "stdin");
1052 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1053 }
1054 } else {
1055 if (!(string1 = (char **)SDDS_GetColumn(&SDDS_output, match_column[0]))) {
1056 fprintf(stderr, "Error: problem getting column %s from file %s\n", match_column[0], input1 ? input1 : "stdin");
1057 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1058 }
1059 }
1060 if (!(string2 = (char **)SDDS_GetColumn(&SDDS_ref[z], match_column[1]))) {
1061 fprintf(stderr, "Error: problem getting column %s from file %s\n", match_column[1], input2);
1062 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1063 }
1064 if (!wildMatch)
1065 keyGroup = MakeSortedKeyGroups(&keyGroups, SDDS_STRING, string2, rows2);
1066 i3 = 0;
1067 for (i1 = 0; i1 < rows1; i1++) {
1068 if (firstRun) {
1069 if (!SDDS_CopyRowDirect(&SDDS_output, i1, &SDDS_1, i1)) {
1070 sprintf(s, "Problem copying row %" PRId64 " of first data set", i1);
1071 SDDS_SetError(s);
1072 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1073 }
1074 }
1075 matched = 0;
1076 if ((&SDDS_output)->row_flag[i1]) {
1077 if (!wildMatch) {
1078 if ((i2 = FindMatchingKeyGroup(keyGroup, keyGroups, SDDS_STRING, string1 + i3, reuse)) >= 0)
1079 matched = 1;
1080 } else {
1081 if ((i2 = match_string(string1[i3], string2, rows2, WILDCARD_MATCH)) >= 0)
1082 matched = 1;
1083 }
1084 if (matched) {
1085 if (!CopyRowToNewColumn(&SDDS_output, i1, &SDDS_ref[z], i2, take_RefData[z], take_RefData[z].columns, input2)) {
1086 fprintf(stderr, "error in copying data to output!\n");
1087 exit(EXIT_FAILURE);
1088 }
1089 } else {
1090 if (!fillIn && !SDDS_AssertRowFlags(&SDDS_output, SDDS_INDEX_LIMITS, i1, i1, (int32_t)0))
1091 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1092 if (warnings)
1093 fprintf(stderr, "warning: no match for row %" PRId64 " (%s = \"%s\")\n", i3, match_column[0], string1[i3]);
1094 }
1095 i3++;
1096 }
1097 }
1098 firstRun = 0;
1099 if (string1) {
1100 for (i = 0; i < i3; i++)
1101 free(string1[i]);
1102 free(string1);
1103 }
1104 if (string2) {
1105 for (i = 0; i < rows2; i++)
1106 free(string2[i]);
1107 free(string2);
1108 }
1109
1110 for (i = 0; i < keyGroups; i++) {
1111 free(keyGroup[i]->equivalent);
1112 free(keyGroup[i]);
1113 }
1114 free(keyGroup);
1115 } else if (equate_columns) {
1116 if (firstRun) {
1117 if (!(value1 = SDDS_GetColumnInDoubles(&SDDS_1, equate_column[0]))) {
1118 fprintf(stderr, "Error: problem getting column %s from file %s\n", equate_column[0], input1 ? input1 : "stdin");
1119 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1120 }
1121 } else {
1122 if (!(value1 = SDDS_GetColumnInDoubles(&SDDS_output, equate_column[0]))) {
1123 fprintf(stderr, "Error: problem getting column %s from file %s\n", equate_column[0], input1 ? input1 : "stdin");
1124 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1125 }
1126 }
1127 if (!(value2 = SDDS_GetColumnInDoubles(&SDDS_ref[z], equate_column[1]))) {
1128 fprintf(stderr, "Error: problem getting column %s from file %s\n", equate_column[1], input2);
1129 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1130 }
1131
1132 i3 = 0;
1133 keyGroup = MakeSortedKeyGroups(&keyGroups, SDDS_DOUBLE, value2, rows2);
1134 for (i1 = 0; i1 < rows1; i1++) {
1135 if (firstRun) {
1136 if (!SDDS_CopyRowDirect(&SDDS_output, i1, &SDDS_1, i1)) {
1137 sprintf(s, "Problem copying row %" PRId64 " of first data set", i1);
1138 SDDS_SetError(s);
1139 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1140 }
1141 }
1142 if ((&SDDS_output)->row_flag[i1]) {
1143 if ((i2 = FindMatchingKeyGroup(keyGroup, keyGroups, SDDS_DOUBLE, value1 + i3, reuse)) >= 0) {
1144 if (!CopyRowToNewColumn(&SDDS_output, i1, &SDDS_ref[z], i2, take_RefData[z], take_RefData[z].columns, input2)) {
1145 fprintf(stderr, "error in copying data to output!\n");
1146 exit(EXIT_FAILURE);
1147 }
1148 } else {
1149 if (!fillIn && !SDDS_AssertRowFlags(&SDDS_output, SDDS_INDEX_LIMITS, i1, i1, (int32_t)0))
1150 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1151 if (warnings)
1152 fprintf(stderr, "warning: no equal for row %" PRId64 " (%s = %g)\n", i3, equate_column[0], value1[i3]);
1153 }
1154 i3++;
1155 }
1156 }
1157 firstRun = 0;
1158 if (i3 && equate_columns)
1159 free(value1);
1160 if (rows2 && equate_columns)
1161 free(value2);
1162 for (i = 0; i < keyGroups; i++) {
1163 free(keyGroup[i]->equivalent);
1164 free(keyGroup[i]);
1165 }
1166 free(keyGroup);
1167 } else {
1168 for (i1 = 0; i1 < rows1; i1++) {
1169 i2 = i1;
1170 if (i2 >= rows2) {
1171 if (!reuse) {
1172 if (fillIn) {
1173 if (!SDDS_CopyRowDirect(&SDDS_output, i1, &SDDS_1, i1)) {
1174 sprintf(s, "Problem copying row %" PRId64 " of first data set", i1);
1175 SDDS_SetError(s);
1176 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1177 }
1178 }
1179 if (warnings)
1180 fprintf(stderr, "warning: no row in file 2 for row %" PRId64 " in file 1\n", i1);
1181 continue;
1182 } else
1183 i2 = rows2 - 1;
1184 }
1185 if (firstRun) {
1186 if (!SDDS_CopyRowDirect(&SDDS_output, i1, &SDDS_1, i1)) {
1187 sprintf(s, "Problem copying row %" PRId64 " of first data set", i1);
1188 SDDS_SetError(s);
1189 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1190 }
1191 }
1192 if (take_RefData[z].columns &&
1193 !CopyRowToNewColumn(&SDDS_output, i1, &SDDS_ref[z], i2, take_RefData[z], take_RefData[z].columns, input2)) {
1194 fprintf(stderr, "error in copying data to output!\n");
1195 exit(EXIT_FAILURE);
1196 }
1197 }
1198 firstRun = 0;
1199 }
1200 }
1201 } else {
1202 if (rows2) {
1203 if (rows1) {
1204 if (match_columns) {
1205 if (firstRun) {
1206 if (!(string1 = (char **)SDDS_GetColumn(&SDDS_1, match_column[0]))) {
1207 fprintf(stderr, "Error: problem getting column %s from file %s\n", match_column[0], input1 ? input1 : "stdin");
1208 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1209 }
1210 } else {
1211 if (!(string1 = (char **)SDDS_GetColumn(&SDDS_output, match_column[0]))) {
1212 fprintf(stderr, "Error: problem getting column %s from file %s\n", match_column[0], input1 ? input1 : "stdin");
1213 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1214 }
1215 }
1216 if (!(string2 = (char **)SDDS_GetColumn(&SDDS_ref[z], match_column[1]))) {
1217 fprintf(stderr, "Error: problem getting column %s from file %s\n", match_column[1], input2);
1218 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1219 }
1220 keyGroup = MakeSortedKeyGroups(&keyGroups, SDDS_STRING, string2, rows2);
1221 i3 = 0;
1222 for (i1 = 0; i1 < rows1; i1++) {
1223 if (firstRun) {
1224 if (!SDDS_CopyRowDirect(&SDDS_output, i1, &SDDS_1, i1)) {
1225 sprintf(s, "Problem copying row %" PRId64 " of first data set", i1);
1226 SDDS_SetError(s);
1227 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1228 }
1229 }
1230 if ((&SDDS_output)->row_flag[i1]) {
1231 if ((FindMatchingKeyGroup(keyGroup, keyGroups, SDDS_STRING, string1 + i3, reuse)) < 0) {
1232 if (!fillIn && !SDDS_AssertRowFlags(&SDDS_output, SDDS_INDEX_LIMITS, i1, i1, (int32_t)0))
1233 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1234 if (warnings)
1235 fprintf(stderr, "warning: no match for row %" PRId64 " (%s = \"%s\")\n", i3, match_column[0], string1[i3]);
1236 }
1237 i3++;
1238 }
1239 }
1240 firstRun = 0;
1241 if (string1) {
1242 for (i = 0; i < i3; i++)
1243 free(string1[i]);
1244 free(string1);
1245 }
1246 if (string2) {
1247 for (i = 0; i < rows2; i++)
1248 free(string2[i]);
1249 free(string2);
1250 }
1251
1252 for (i = 0; i < keyGroups; i++) {
1253 free(keyGroup[i]->equivalent);
1254 free(keyGroup[i]);
1255 }
1256 free(keyGroup);
1257 } else if (equate_columns) {
1258 if (firstRun) {
1259 if (!(value1 = SDDS_GetColumnInDoubles(&SDDS_1, equate_column[0]))) {
1260 fprintf(stderr, "Error: problem getting column %s from file %s\n", equate_column[0], input1 ? input1 : "stdin");
1261 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1262 }
1263 } else {
1264 if (!(value1 = SDDS_GetColumnInDoubles(&SDDS_output, equate_column[0]))) {
1265 fprintf(stderr, "Error: problem getting column %s from file %s\n", equate_column[0], input1 ? input1 : "stdin");
1266 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1267 }
1268 }
1269 if (!(value2 = SDDS_GetColumnInDoubles(&SDDS_ref[z], equate_column[1]))) {
1270 fprintf(stderr, "Error: problem getting column %s from file %s\n", equate_column[1], input2);
1271 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1272 }
1273 keyGroup = MakeSortedKeyGroups(&keyGroups, SDDS_DOUBLE, value2, rows2);
1274 i3 = 0;
1275 for (i1 = 0; i1 < rows1; i1++) {
1276 if (firstRun) {
1277 if (!SDDS_CopyRowDirect(&SDDS_output, i1, &SDDS_1, i1)) {
1278 sprintf(s, "Problem copying row %" PRId64 " of first data set", i1);
1279 SDDS_SetError(s);
1280 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1281 }
1282 }
1283 if ((&SDDS_output)->row_flag[i1]) {
1284 if ((FindMatchingKeyGroup(keyGroup, keyGroups, SDDS_DOUBLE, value1 + i3, reuse)) < 0) {
1285 if (!fillIn && !SDDS_AssertRowFlags(&SDDS_output, SDDS_INDEX_LIMITS, i1, i1, (int32_t)0))
1286 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1287 if (warnings)
1288 fprintf(stderr, "warning: no equal for row %" PRId64 " (%s = %g)\n", i3, equate_column[0], value1[i3]);
1289 }
1290 i3++;
1291 }
1292 }
1293 firstRun = 0;
1294 if (i3 && equate_columns)
1295 free(value1);
1296 if (rows2 && equate_columns)
1297 free(value2);
1298 for (i = 0; i < keyGroups; i++) {
1299 free(keyGroup[i]->equivalent);
1300 free(keyGroup[i]);
1301 }
1302 free(keyGroup);
1303 }
1304 }
1305 }
1306 copyInput1Only++;
1307 }
1308 }
1309 if ((rows2Max == 0 && fillIn) || (copyInput1Only == referfiles && !match_columns && !equate_columns)) {
1310 if (!SDDS_CopyColumns(&SDDS_output, &SDDS_1)) {
1311 SDDS_SetError("Problem copying tabular data for output file.");
1312 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1313 }
1314 }
1315
1316 if (!SDDS_WritePage(&SDDS_output)) {
1317 SDDS_SetError("Problem writing data to output file");
1318 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1319 }
1320 }
1321
1322 for (z = 0; z < referfiles; z++) {
1323 free(referfile[z]);
1324
1325 if (take_RefData[z].columns) {
1326 for (i = 0; i < take_RefData[z].columns; i++) {
1327 free(take_RefData[z].new_column[i]);
1328 free(take_RefData[z].orig_column[i]);
1329 }
1330 free(take_RefData[z].new_column);
1331 free(take_RefData[z].orig_column);
1332 }
1333
1334 if (take_RefData[z].parameters) {
1335 for (i = 0; i < take_RefData[z].parameters; i++) {
1336 free(take_RefData[z].new_parameter[i]);
1337 free(take_RefData[z].orig_parameter[i]);
1338 }
1339 free(take_RefData[z].new_parameter);
1340 free(take_RefData[z].orig_parameter);
1341 }
1342
1343 if (take_RefData[z].arrays) {
1344 for (i = 0; i < take_RefData[z].arrays; i++) {
1345 free(take_RefData[z].new_array[i]);
1346 free(take_RefData[z].orig_array[i]);
1347 }
1348 free(take_RefData[z].new_array);
1349 free(take_RefData[z].orig_array);
1350 }
1351
1352 if (new_data[z].columns) {
1353 for (i = 0; i < new_data[z].columns; i++) {
1354 free(new_data[z].new_column[i]);
1355 free(new_data[z].orig_column[i]);
1356 }
1357 free(new_data[z].new_column);
1358 free(new_data[z].orig_column);
1359 }
1360
1361 if (new_data[z].parameters) {
1362 for (i = 0; i < new_data[z].parameters; i++) {
1363 free(new_data[z].new_parameter[i]);
1364 free(new_data[z].orig_parameter[i]);
1365 }
1366 free(new_data[z].new_parameter);
1367 free(new_data[z].orig_parameter);
1368 }
1369 if (new_data[z].arrays) {
1370 for (i = 0; i < new_data[z].arrays; i++) {
1371 free(new_data[z].new_array[i]);
1372 free(new_data[z].orig_array[i]);
1373 }
1374 free(new_data[z].new_array);
1375 free(new_data[z].orig_array);
1376 }
1377 }
1378 if (new_data)
1379 free(new_data);
1380
1381 if (edit_column_requests) {
1382 for (i = 0; i < edit_column_requests; i++) {
1383 free(edit_column_request[i].match_string);
1384 free(edit_column_request[i].edit_string);
1385 }
1386 free(edit_column_request);
1387 }
1388 if (edit_parameter_requests) {
1389 for (i = 0; i < edit_parameter_requests; i++) {
1390 free(edit_parameter_request[i].match_string);
1391 free(edit_parameter_request[i].edit_string);
1392 }
1393 free(edit_parameter_request);
1394 }
1395
1396 if (edit_array_requests) {
1397 for (i = 0; i < edit_array_requests; i++) {
1398 free(edit_array_request[i].match_string);
1399 free(edit_array_request[i].edit_string);
1400 }
1401 free(edit_array_request);
1402 }
1403
1404 free(take_RefData);
1405 if (replace_RefData)
1406 free(replace_RefData);
1407 free(referfile);
1408 free(inputfile);
1409
1410 if (match_columns)
1411 free(match_column);
1412 if (equate_columns)
1413 free(equate_column);
1414
1415 /*#ifdef SOLARIS */
1416 if (!SDDS_Terminate(&SDDS_output) || !SDDS_Terminate(&SDDS_1)) {
1417 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
1418 exit(EXIT_FAILURE);
1419 }
1420 for (z = 0; z < referfiles; z++) {
1421 if (!SDDS_Terminate(&SDDS_ref[z])) {
1422 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
1423 exit(EXIT_FAILURE);
1424 }
1425 }
1426 free(SDDS_ref);
1427 /*#endif */
1428 if (tmpfile_used && !replaceFileAndBackUp(input1, output))
1429 exit(EXIT_FAILURE);
1430 free(input1);
1431 free(output);
1432 return EXIT_SUCCESS;
1433}
1434
1435long expandTransferRequests(char ***match, int32_t *matches, long type,
1436 TRANSFER_DEFINITION *transfer, long transfers, SDDS_DATASET *inSet) {
1437 long i, first;
1438 int32_t (*matchRoutine)(SDDS_DATASET *SDDS_dataset, char ***nameReturn, int32_t matchMode, int32_t typeMode, ...);
1439
1440 *matches = 0;
1441 *match = NULL;
1442 if (!transfers)
1443 return 1;
1444 switch (type) {
1445 case PARAMETER_TRANSFER:
1446 matchRoutine = SDDS_MatchParameters;
1447 break;
1448 case ARRAY_TRANSFER:
1449 matchRoutine = SDDS_MatchArrays;
1450 break;
1451 default:
1452 SDDS_Bomb("invalid transfer type--this shouldn't happen");
1453 exit(EXIT_FAILURE);
1454 break;
1455 }
1456 first = 0;
1457 for (i = 0; i < transfers; i++) {
1458 if (transfer[i].type == type) {
1459 if ((*matches = (*matchRoutine)(inSet, match, SDDS_MATCH_STRING, FIND_ANY_TYPE, transfer[i].name, SDDS_OR | (first ? SDDS_0_PREVIOUS : 0))) == -1) {
1460 return 0;
1461 }
1462 first = 0;
1463 }
1464 }
1465 return 1;
1466}
1467
1468void add_newnames(SDDS_DATASET *SDDS_dataset, REFDATA *new_data, REFDATA rename_data,
1469 EDIT_NAME_REQUEST *edit_column_request, long edit_column_requests,
1470 EDIT_NAME_REQUEST *edit_parameter_request, long edit_parameter_requests,
1471 EDIT_NAME_REQUEST *edit_array_request, long edit_array_requests, long filenumber) {
1472 long i, k = 0, *orig_columnflags;
1473 int32_t columns, parameters, arrays;
1474 long *orig_parameterflags, *orig_arrayflags;
1475 char **column_names, **parameter_names, **array_names, **new_names;
1476
1477 columns = parameters = arrays = 0;
1478 column_names = parameter_names = array_names = new_names = NULL;
1479 orig_columnflags = orig_parameterflags = orig_arrayflags = NULL;
1480 new_data->columns = new_data->parameters = new_data->arrays = 0;
1481 new_data->new_column = new_data->orig_column = NULL;
1482 new_data->new_parameter = new_data->orig_parameter = NULL;
1483 new_data->new_array = new_data->orig_array = NULL;
1484
1485 /* No edit requests at all */
1486 if (!edit_column_requests && !edit_parameter_requests && !edit_array_requests &&
1487 !rename_data.columns && !rename_data.parameters && !rename_data.arrays)
1488 return;
1489
1490 /* Transfer renames to new_data */
1491 (*new_data).columns = rename_data.columns;
1492 (*new_data).parameters = rename_data.parameters;
1493 (*new_data).arrays = rename_data.arrays;
1494 if (rename_data.columns) {
1495 (*new_data).new_column = (char **)malloc(sizeof(char *) * rename_data.columns);
1496 (*new_data).orig_column = (char **)malloc(sizeof(char *) * rename_data.columns);
1497 for (i = 0; i < rename_data.columns; i++) {
1498 SDDS_CopyString(&(*new_data).new_column[i], rename_data.new_column[i]);
1499 SDDS_CopyString(&(*new_data).orig_column[i], rename_data.orig_column[i]);
1500 }
1501 }
1502 if (rename_data.parameters) {
1503 (*new_data).new_parameter = (char **)malloc(sizeof(char *) * rename_data.parameters);
1504 (*new_data).orig_parameter = (char **)malloc(sizeof(char *) * rename_data.parameters);
1505 for (i = 0; i < rename_data.parameters; i++) {
1506 SDDS_CopyString(&(*new_data).new_parameter[i], rename_data.new_parameter[i]);
1507 SDDS_CopyString(&(*new_data).orig_parameter[i], rename_data.orig_parameter[i]);
1508 }
1509 }
1510 if (rename_data.arrays) {
1511 (*new_data).new_array = (char **)malloc(sizeof(char *) * rename_data.arrays);
1512 (*new_data).orig_array = (char **)malloc(sizeof(char *) * rename_data.arrays);
1513 for (i = 0; i < rename_data.arrays; i++) {
1514 SDDS_CopyString(&(*new_data).new_array[i], rename_data.new_array[i]);
1515 SDDS_CopyString(&(*new_data).orig_array[i], rename_data.orig_array[i]);
1516 }
1517 }
1518
1519 if (!(column_names = SDDS_GetColumnNames(SDDS_dataset, &columns))) {
1520 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
1521 exit(EXIT_FAILURE);
1522 }
1523 if (!(parameter_names = SDDS_GetParameterNames(SDDS_dataset, &parameters))) {
1524 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
1525 exit(EXIT_FAILURE);
1526 }
1527
1528 if (!(array_names = SDDS_GetArrayNames(SDDS_dataset, &arrays))) {
1529 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
1530 exit(EXIT_FAILURE);
1531 }
1532
1533 /* Process edit names */
1534 if (edit_column_requests) {
1535 if ((new_names = process_editnames(column_names, &orig_columnflags, columns, edit_column_request, edit_column_requests, filenumber))) {
1536 for (i = 0; i < columns; i++) {
1537 if (orig_columnflags[i]) {
1538 k = (*new_data).columns;
1539 (*new_data).new_column = trealloc((*new_data).new_column, sizeof(char *) * (k + 1));
1540 (*new_data).orig_column = trealloc((*new_data).orig_column, sizeof(char *) * (k + 1));
1541 SDDS_CopyString(&(*new_data).new_column[k], new_names[i]);
1542 SDDS_CopyString(&(*new_data).orig_column[k], column_names[i]);
1543 (*new_data).columns++;
1544 }
1545 free(new_names[i]);
1546 }
1547 free(new_names);
1548 }
1549 }
1550
1551 if (edit_parameter_requests) {
1552 if ((new_names = process_editnames(parameter_names, &orig_parameterflags, parameters, edit_parameter_request, edit_parameter_requests, filenumber))) {
1553 for (i = 0; i < parameters; i++) {
1554 if (orig_parameterflags[i]) {
1555 k = (*new_data).parameters;
1556 (*new_data).new_parameter = trealloc((*new_data).new_parameter, sizeof(char *) * (k + 1));
1557 (*new_data).orig_parameter = trealloc((*new_data).orig_parameter, sizeof(char *) * (k + 1));
1558 SDDS_CopyString(&(*new_data).new_parameter[k], new_names[i]);
1559 SDDS_CopyString(&(*new_data).orig_parameter[k], parameter_names[i]);
1560 (*new_data).parameters++;
1561 }
1562 free(new_names[i]);
1563 }
1564 free(new_names);
1565 }
1566 }
1567
1568 if (edit_array_requests) {
1569 if ((new_names = process_editnames(array_names, &orig_arrayflags, arrays, edit_array_request, edit_array_requests, filenumber))) {
1570 for (i = 0; i < arrays; i++) {
1571 if (orig_arrayflags[i]) {
1572 k = (*new_data).arrays;
1573 (*new_data).new_array = trealloc((*new_data).new_array, sizeof(char *) * (k + 1));
1574 (*new_data).orig_array = trealloc((*new_data).orig_array, sizeof(char *) * (k + 1));
1575 SDDS_CopyString(&(*new_data).new_array[k], new_names[i]);
1576 SDDS_CopyString(&(*new_data).orig_array[k], array_names[i]);
1577 (*new_data).arrays++;
1578 }
1579 free(new_names[i]);
1580 }
1581 free(new_names);
1582 }
1583 }
1584
1585 if (orig_columnflags)
1586 free(orig_columnflags);
1587 if (orig_parameterflags)
1588 free(orig_parameterflags);
1589 if (orig_arrayflags)
1590 free(orig_arrayflags);
1591 for (i = 0; i < columns; i++)
1592 free(column_names[i]);
1593 free(column_names);
1594 for (i = 0; i < parameters; i++)
1595 free(parameter_names[i]);
1596 free(parameter_names);
1597 for (i = 0; i < arrays; i++)
1598 free(array_names[i]);
1599 free(array_names);
1600}
1601
1602char **process_editnames(char **orig_name, long **orig_flags, long orig_names, EDIT_NAME_REQUEST *edit_request,
1603 long edit_requests, long filenumber) {
1604 long i, j, i1, i2 = 0, k;
1605 char **new_name, s[1024], tmpstr[1024];
1606 char *ptr, **editstr, *pch;
1607 char edit_buffer[1024];
1608
1609 *orig_flags = NULL;
1610
1611 *orig_flags = tmalloc(sizeof(**orig_flags) * orig_names);
1612 new_name = tmalloc(sizeof(*new_name) * orig_names);
1613
1614 editstr = (char **)malloc(sizeof(*editstr) * edit_requests);
1615 ptr = malloc(sizeof(char) * 256);
1616 sprintf(s, "%ld", filenumber);
1617
1618 for (i = 0; i < edit_requests; i++) {
1619 SDDS_CopyString(&editstr[i], edit_request[i].edit_string);
1620 if (strstr(editstr[i], "%%ld"))
1621 replace_string(ptr, editstr[i], "%%ld", "%ld");
1622 else if (strstr(editstr[i], "%ld")) {
1623 sprintf(s, "%ld", filenumber);
1624 replace_string(ptr, editstr[i], "%ld", s);
1625 } else if (wild_match(editstr[i], "*%*ld*")) {
1626 /* Find the format of %*ld */
1627 /* Find position of '%' */
1628 pch = strchr(editstr[i], '%');
1629 i1 = pch - editstr[i];
1630 /* Find the position of 'd' after '%' */
1631 for (k = 0; k < strlen(editstr[i]); k++) {
1632 if (editstr[i][k] == 'd') {
1633 i2 = k;
1634 if (i2 > i1)
1635 break;
1636 }
1637 }
1638 strncpy(tmpstr, pch, i2 - i1 + 1);
1639 tmpstr[i2 - i1 + 1] = '\0';
1640 sprintf(s, tmpstr, filenumber);
1641 replace_string(ptr, editstr[i], tmpstr, s);
1642 } else
1643 continue;
1644 free(editstr[i]);
1645 SDDS_CopyString(&editstr[i], ptr);
1646 }
1647 free(ptr);
1648 ptr = NULL;
1649 for (j = 0; j < orig_names; j++) {
1650 (*orig_flags)[j] = 0;
1651 SDDS_CopyString(new_name + j, orig_name[j]);
1652 for (i = 0; i < edit_requests; i++) {
1653 ptr = expand_ranges(edit_request[i].match_string);
1654 free(edit_request[i].match_string);
1655 edit_request[i].match_string = ptr;
1656 if (wild_match(new_name[j], edit_request[i].match_string)) {
1657 strcpy(edit_buffer, new_name[j]);
1658 if (!edit_string(edit_buffer, editstr[i]))
1659 SDDS_Bomb("error editing name");
1660 free(new_name[j]);
1661 SDDS_CopyString(&new_name[j], edit_buffer);
1662 (*orig_flags)[j] = 1;
1663 }
1664 }
1665 }
1666
1667 for (i = 0; i < edit_requests; i++)
1668 free(editstr[i]);
1669 free(editstr);
1670 return new_name;
1671}
1672
1673long CopyRowToNewColumn(SDDS_DATASET *target, int64_t target_row, SDDS_DATASET *source, int64_t source_row,
1674 REFDATA new_data, long columns, char *input2) {
1675 long i, j, k, type, size;
1676 char s[1024];
1677
1678 if (!columns)
1679 return 1;
1680
1681 for (i = 0; i < columns; i++) {
1682 if ((j = SDDS_GetColumnIndex(source, new_data.orig_column[i])) < 0) {
1683 sprintf(s, "error: column %s not found in file %s\n", new_data.orig_column[i], input2);
1684 SDDS_SetError(s);
1685 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1686 continue;
1687 }
1688 if ((k = SDDS_GetColumnIndex(target, new_data.new_column[i])) < 0) {
1689 sprintf(s, "error: column %s not defined in output\n", new_data.new_column[i]);
1690 SDDS_SetError(s);
1691 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1692 continue;
1693 }
1694
1695 if ((type = SDDS_GetColumnType(target, k)) == SDDS_STRING) {
1696 if (!SDDS_CopyString(((char ***)target->data)[k] + target_row, ((char ***)source->data)[j][source_row])) {
1697 SDDS_SetError("Unable to copy row--string copy failed (SDDS_CopyRow)");
1698 return (0);
1699 }
1700 } else {
1701 size = SDDS_type_size[type - 1];
1702 memcpy((char *)target->data[k] + size * target_row, (char *)source->data[j] + size * source_row, size);
1703 }
1704 }
1705 return (1);
1706}
1707
1708long CopyParametersFromSecondInput(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, REFDATA new_data) {
1709 long i, j, k;
1710 char s[1024];
1711
1712 if (new_data.parameters == 0)
1713 return 1;
1714 if (new_data.parameters) {
1715 for (i = 0; i < new_data.parameters; i++) {
1716 if ((j = SDDS_GetParameterIndex(SDDS_source, new_data.orig_parameter[i])) < 0) {
1717 continue;
1718 }
1719
1720 if ((k = SDDS_GetParameterIndex(SDDS_target, new_data.new_parameter[i])) < 0) {
1721 fprintf(stderr, "Warning, parameter %s not defined in output.\n", new_data.new_parameter[i]);
1722 continue;
1723 }
1724 if (!SDDS_SetParameters(SDDS_target, SDDS_SET_BY_INDEX | SDDS_PASS_BY_REFERENCE, k, SDDS_source->parameter[j], -1)) {
1725 sprintf(s, "Unable to copy parameters for parameter %s", new_data.new_parameter[i]);
1726 SDDS_SetError(s);
1727 return (0);
1728 }
1729 }
1730 }
1731 return 1;
1732}
1733
1734long CopyArraysFromSecondInput(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, REFDATA new_data) {
1735 long i, j, k, m;
1736 char s[1024];
1737
1738 if (new_data.arrays == 0)
1739 return 1;
1740 for (i = 0; i < new_data.arrays; i++) {
1741 if ((j = SDDS_GetArrayIndex(SDDS_source, new_data.orig_array[i])) < 0)
1742 continue;
1743 if ((k = SDDS_GetArrayIndex(SDDS_target, new_data.new_array[i])) < 0) {
1744 sprintf(s, "Warning, array %s not defined in output.\n", new_data.new_array[i]);
1745 SDDS_SetError(s);
1746 continue;
1747 }
1748 if (SDDS_source->layout.array_definition[j].type != SDDS_target->layout.array_definition[k].type) {
1749 SDDS_SetError("Can't copy arrays between different types (SDDS_CopyArrays)");
1750 return 0;
1751 }
1752 SDDS_target->array[k].definition = SDDS_target->layout.array_definition + k;
1753 SDDS_target->array[k].elements = SDDS_source->array[j].elements;
1754 if (!(SDDS_target->array[k].dimension = (int32_t *)SDDS_Malloc(sizeof(*SDDS_target->array[k].dimension) * SDDS_target->array[k].definition->dimensions)) ||
1755 !(SDDS_target->array[k].data = SDDS_Realloc(SDDS_target->array[k].data, SDDS_type_size[SDDS_target->array[k].definition->type - 1] * SDDS_target->array[k].elements))) {
1756 SDDS_SetError("Unable to copy arrays--allocation failure (SDDS_CopyArrays)");
1757 return (0);
1758 }
1759 for (m = 0; m < SDDS_target->array[k].definition->dimensions; m++)
1760 SDDS_target->array[k].dimension[m] = SDDS_source->array[j].dimension[m];
1761
1762 if (SDDS_target->array[k].definition->type != SDDS_STRING)
1763 memcpy(SDDS_target->array[k].data, SDDS_source->array[j].data, SDDS_type_size[SDDS_target->array[k].definition->type - 1] * SDDS_target->array[k].elements);
1764 else if (!SDDS_CopyStringArray(SDDS_target->array[k].data, SDDS_source->array[j].data, SDDS_target->array[k].elements)) {
1765 SDDS_SetError("Unable to copy arrays (SDDS_CopyArrays)");
1766 return (0);
1767 }
1768 }
1769 return 1;
1770}
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_CopyColumns(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:387
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_CopyArrays(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:334
int32_t SDDS_type_size[SDDS_NUM_TYPES]
Array of sizes for each supported data type.
Definition SDDS_data.c:62
char * SDDS_type_name[SDDS_NUM_TYPES]
Array of supported data type names.
Definition SDDS_data.c:43
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
int32_t SDDS_ClearPage(SDDS_DATASET *SDDS_dataset)
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.
int32_t SDDS_SetColumnsOfInterest(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
Sets the acceptance flags for columns based on specified naming criteria.
int32_t SDDS_SetColumnFlags(SDDS_DATASET *SDDS_dataset, int32_t column_flag_value)
Sets the acceptance flags for all columns 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_ChangeParameterInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode,...)
Modifies a specific field in a parameter definition within the SDDS dataset.
Definition SDDS_info.c:485
int32_t SDDS_ChangeArrayInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode,...)
Modifies a specific field in an array definition within the SDDS dataset.
Definition SDDS_info.c:597
int32_t SDDS_ChangeColumnInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode,...)
Modifies a specific field in a column definition within the SDDS dataset.
Definition SDDS_info.c:364
int32_t SDDS_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:49
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.
int32_t SDDS_TransferColumnDefinition(SDDS_DATASET *target, SDDS_DATASET *source, char *name, char *newName)
Transfers a column definition from a source dataset to a target dataset.
int32_t SDDS_TransferArrayDefinition(SDDS_DATASET *target, SDDS_DATASET *source, char *name, char *newName)
Transfers an array definition from a source dataset to a target dataset.
int32_t SDDS_TransferParameterDefinition(SDDS_DATASET *target, SDDS_DATASET *source, char *name, char *newName)
Transfers a parameter definition from a source dataset to a target dataset.
int32_t SDDS_FreeStringArray(char **string, int64_t strings)
Frees an array of strings by deallocating each individual string.
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
Definition SDDS_utils.c:379
int32_t SDDS_GetParameterType(SDDS_DATASET *SDDS_dataset, int32_t index)
Retrieves the data type of a parameter in the SDDS dataset by its index.
int32_t SDDS_GetArrayIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named array in the SDDS dataset.
char ** SDDS_GetParameterNames(SDDS_DATASET *SDDS_dataset, int32_t *number)
Retrieves the names of all parameters in the SDDS dataset.
int32_t SDDS_GetParameterIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named parameter in the SDDS dataset.
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
int32_t SDDS_MatchParameters(SDDS_DATASET *SDDS_dataset, char ***nameReturn, int32_t matchMode, int32_t typeMode,...)
Matches and retrieves parameter names from an SDDS dataset based on specified criteria.
int32_t SDDS_ColumnCount(SDDS_DATASET *page)
Retrieves the number of columns in the SDDS dataset.
char ** SDDS_GetColumnNames(SDDS_DATASET *SDDS_dataset, int32_t *number)
Retrieves the names of all columns in the SDDS dataset.
int32_t SDDS_GetArrayType(SDDS_DATASET *SDDS_dataset, int32_t index)
Retrieves the data type of an array in the SDDS dataset by its index.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:432
int32_t SDDS_CopyStringArray(char **target, char **source, int64_t n_strings)
Copies an array of strings from source to target.
void * SDDS_Malloc(size_t size)
Allocates memory of a specified size.
Definition SDDS_utils.c:639
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
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:342
char ** SDDS_GetArrayNames(SDDS_DATASET *SDDS_dataset, int32_t *number)
Retrieves the names of all arrays in the SDDS dataset.
int32_t SDDS_CopyString(char **target, const char *source)
Copies a source string to a target string with memory allocation.
Definition SDDS_utils.c:856
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
Definition SDDS_utils.c:677
int32_t SDDS_MatchArrays(SDDS_DATASET *SDDS_dataset, char ***nameReturn, int32_t matchMode, int32_t typeMode,...)
Matches and retrieves array names from an SDDS dataset based on specified criteria.
Header file for routines used by SDDS command-line applications.
long edit_string(char *text, char *edit)
Edits the provided text based on the specified edit commands.
Definition edit_string.c:75
#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 * trealloc(void *old_ptr, uint64_t size_of_block)
Reallocates a memory block to a new size.
Definition array.c:181
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:59
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.
int replace_string(char *t, char *s, char *orig, char *repl)
Replace all occurrences of one string with another string.
long replaceFileAndBackUp(char *file, char *replacement)
Replaces a file with a replacement file and creates a backup of the original.
Definition replacefile.c:75
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:356
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
Definition scanargs.c:390
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.
int has_wildcards(char *template)
Check if a template string contains any wildcard characters.
Definition wild_match.c:498
char * expand_ranges(char *template)
Expand range specifiers in a wildcard template into explicit character lists.
Definition wild_match.c:429
int wild_match(char *string, char *template)
Determine whether one string is a wildcard match for another.
Definition wild_match.c:49