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