SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
sddsmxref.c File Reference

Detailed Description

Merges two SDDS data sets by adding data from the second set to the first based on matching or filtering column data.

This program merges data from two SDDS files. It transfers parameters, columns, and arrays from the second input file to the first based on user-specified criteria for matching, filtering, and name transformations. The resulting data set can be output to a new file or overwrite the first input file.

Usage

sddsmxref [<input1>] <input2> [<output>]
[-pipe[=input][,output]]
[-ifis={column|parameter|array},<name>[,...]]
[-ifnot={column|parameter|array},<name>[,...]]
[-transfer={parameter|array},<name>[,...]]
[-take=<column-name>[,...]]
[-leave=<column-name>[,...]]
[-fillIn]
[-match=<column-name>[=<column-name>][,...]]
[-equate=<column-name>[=<column-name>][,<tol>][,...]]
[-reuse[=[rows][,page]]]
[-rename={column|parameter|array},<old>=<new>[,...]]
[-editnames={column|parameter|array},<wild>,<edit>]
[-majorOrder=row|column]

Options

Option Description
-pipe Use standard input and/or output instead of files.
-ifis Specifies items that must exist in <input1>.
-ifnot Specifies items that must not exist in <input1>.
-transfer Specifies parameters or arrays to transfer from <input2>.
-take Specifies columns to take from <input2>.
-leave Specifies columns to exclude from <input2> (overrides -take for overlapping columns).
-fillIn Fills in NULL or 0 for unmatched rows.
-match Matches rows between <input1> and <input2> based on column values.
-equate Equates rows with specified tolerances.
-reuse Allows reuse of rows or pages from <input2>.
-rename Renames items in the output data set.
-editnames Edits names matching the wildcard string.
-majorOrder Specifies the output's major order.

Incompatibilities

  • -take is incompatible with -leave for overlapping column names.
  • -reuse=page cannot be used if -match or -equate is not specified.

Specific Requirements

  • For -match, the matching column(s) must exist in both <input1> and <input2>.
  • For -equate, equated columns must be numeric in both inputs.
  • For -transfer, specified parameters or arrays must exist in <input2>.
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
M. Borland, C. Saunders, R. Soliday, H. Shang

Definition in file sddsmxref.c.

#include "mdb.h"
#include "SDDS.h"
#include "SDDSaps.h"
#include "scan.h"

Go to the source code of this file.

Typedefs

typedef char * STRING_PAIR[2]
 

Functions

long expandTransferRequests (char ***match, long *matches, long type, TRANSFER_DEFINITION *transfer, long transfers, SDDS_DATASET *inSet)
 
void process_newnames (SDDS_DATASET *SDDS_dataset, REFDATA *take_RefData, REFDATA rename_data, EDIT_NAME_REQUEST *edit_column_request, long edit_column_requests, EDIT_NAME_REQUEST *edit_parameter_request, long edit_parameter_requests, EDIT_NAME_REQUEST *edit_array_request, long edit_array_requests)
 
char ** process_editnames (char **orig_name, long **orig_flags, long orig_names, EDIT_NAME_REQUEST *edit_request, long edit_requests)
 
long CopyRowToNewColumn (SDDS_DATASET *target, int64_t target_row, SDDS_DATASET *source, int64_t source_row, REFDATA new_data, long columns, char *input2)
 
long CopyArraysFromSecondInput (SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, REFDATA new_data)
 
long CopyParametersFromSecondInput (SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, REFDATA new_data)
 
void free_refdata (REFDATA *refData, long rename)
 
void free_edit_request (EDIT_NAME_REQUEST *edit_request, long edit_requests)
 
long rows_equate (SDDS_DATASET *SDDS1, int64_t row1, SDDS_DATASET *SDDS2, int64_t row2, long equate_columns, STRING_PAIR *equate_column, double *equate_tolerance)
 
int main (int argc, char **argv)
 

Typedef Documentation

◆ STRING_PAIR

typedef char* STRING_PAIR[2]

Definition at line 161 of file sddsmxref.c.

Function Documentation

◆ CopyArraysFromSecondInput()

long CopyArraysFromSecondInput ( SDDS_DATASET * SDDS_target,
SDDS_DATASET * SDDS_source,
REFDATA new_data )

Definition at line 1092 of file sddsmxref.c.

1092 {
1093 long i, j, k, m;
1094 char s[1024];
1095
1096 if (new_data.arrays == 0)
1097 return 1;
1098 for (i = 0; i < new_data.arrays; i++) {
1099 if ((j = SDDS_GetArrayIndex(SDDS_source, new_data.orig_array[i])) < 0)
1100 continue;
1101 if ((k = SDDS_GetArrayIndex(SDDS_target, new_data.new_array[i])) < 0) {
1102 sprintf(s, "Warning: Array '%s' not defined in output.\n", new_data.new_array[i]);
1103 SDDS_SetError(s);
1104 continue;
1105 }
1106 if (SDDS_source->layout.array_definition[j].type != SDDS_target->layout.array_definition[k].type) {
1107 SDDS_SetError("Error: Cannot copy arrays of different types.");
1108 return 0;
1109 }
1110 SDDS_target->array[k].definition = SDDS_target->layout.array_definition + k;
1111 SDDS_target->array[k].elements = SDDS_source->array[j].elements;
1112 if (!(SDDS_target->array[k].dimension = (int32_t *)SDDS_Malloc(sizeof(*SDDS_target->array[k].dimension) * SDDS_target->array[k].definition->dimensions)) ||
1113 !(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))) {
1114 SDDS_SetError("Error: Unable to copy arrays due to memory allocation failure.");
1115 return 0;
1116 }
1117 for (m = 0; m < SDDS_target->array[k].definition->dimensions; m++)
1118 SDDS_target->array[k].dimension[m] = SDDS_source->array[j].dimension[m];
1119
1120 if (SDDS_target->array[k].definition->type != SDDS_STRING)
1121 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);
1122 else if (!SDDS_CopyStringArray(SDDS_target->array[k].data, SDDS_source->array[j].data, SDDS_target->array[k].elements)) {
1123 SDDS_SetError("Error: Unable to copy string arrays.");
1124 return 0;
1125 }
1126 }
1127 return 1;
1128}
int32_t SDDS_type_size[SDDS_NUM_TYPES]
Array of sizes for each supported data type.
Definition SDDS_data.c:62
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
Definition SDDS_utils.c:379
int32_t SDDS_GetArrayIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named array in the SDDS dataset.
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_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
Definition SDDS_utils.c:677
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85

◆ CopyParametersFromSecondInput()

long CopyParametersFromSecondInput ( SDDS_DATASET * SDDS_target,
SDDS_DATASET * SDDS_source,
REFDATA new_data )

Definition at line 1068 of file sddsmxref.c.

1068 {
1069 long i, j, k;
1070 char s[1024];
1071
1072 if (new_data.parameters == 0)
1073 return 1;
1074 for (i = 0; i < new_data.parameters; i++) {
1075 if ((j = SDDS_GetParameterIndex(SDDS_source, new_data.orig_parameter[i])) < 0) {
1076 continue;
1077 }
1078
1079 if ((k = SDDS_GetParameterIndex(SDDS_target, new_data.new_parameter[i])) < 0) {
1080 fprintf(stderr, "Warning: Parameter '%s' not defined in output.\n", new_data.new_parameter[i]);
1081 continue;
1082 }
1083 if (!SDDS_SetParameters(SDDS_target, SDDS_SET_BY_INDEX | SDDS_PASS_BY_REFERENCE, k, SDDS_source->parameter[j], -1)) {
1084 sprintf(s, "Unable to copy parameters for parameter '%s'", new_data.new_parameter[i]);
1085 SDDS_SetError(s);
1086 return 0;
1087 }
1088 }
1089 return 1;
1090}
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
int32_t SDDS_GetParameterIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named parameter in the SDDS dataset.

◆ CopyRowToNewColumn()

long CopyRowToNewColumn ( SDDS_DATASET * target,
int64_t target_row,
SDDS_DATASET * source,
int64_t source_row,
REFDATA new_data,
long columns,
char * input2 )

Definition at line 1130 of file sddsmxref.c.

1130 {
1131 long i, j, k, type, size;
1132 char s[1024];
1133
1134 if (!columns)
1135 return 1;
1136
1137 for (i = 0; i < columns; i++) {
1138 if ((j = SDDS_GetColumnIndex(source, new_data.orig_column[i])) < 0) {
1139 sprintf(s, "Error: Column '%s' not found in file '%s'.\n", new_data.orig_column[i], input2);
1140 SDDS_SetError(s);
1141 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1142 continue;
1143 }
1144 if ((k = SDDS_GetColumnIndex(target, new_data.new_column[i])) < 0) {
1145 sprintf(s, "Error: Column '%s' not defined in output.\n", new_data.new_column[i]);
1146 SDDS_SetError(s);
1147 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1148 continue;
1149 }
1150
1151 if ((type = SDDS_GetColumnType(target, k)) == SDDS_STRING) {
1152 if (!SDDS_CopyString(((char ***)target->data)[k] + target_row, ((char ***)source->data)[j][source_row])) {
1153 SDDS_SetError("Error: Unable to copy string data.");
1154 return 0;
1155 }
1156 } else {
1157 size = SDDS_type_size[type - 1];
1158 memcpy((char *)target->data[k] + size * target_row, (char *)source->data[j] + size * source_row, size);
1159 }
1160 }
1161 return 1;
1162}
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:432
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.
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

◆ expandTransferRequests()

long expandTransferRequests ( char *** match,
long * matches,
long type,
TRANSFER_DEFINITION * transfer,
long transfers,
SDDS_DATASET * inSet )

Definition at line 879 of file sddsmxref.c.

879 {
880 long i, first;
881 int32_t (*matchRoutine)(SDDS_DATASET *SDDS_dataset, char ***nameReturn, int32_t matchMode, int32_t typeMode, ...);
882
883 *matches = 0;
884 *match = NULL;
885 switch (type) {
886 case PARAMETER_TRANSFER:
887 matchRoutine = SDDS_MatchParameters;
888 break;
889 case ARRAY_TRANSFER:
890 matchRoutine = SDDS_MatchArrays;
891 break;
892 default:
893 SDDS_Bomb("Invalid transfer type--this shouldn't happen");
894 exit(EXIT_FAILURE);
895 break;
896 }
897 first = 0;
898 for (i = 0; i < transfers; i++) {
899 if (transfer[i].type == type) {
900 if ((*matches = (*matchRoutine)(inSet, match, SDDS_MATCH_STRING, FIND_ANY_TYPE, transfer[i].name, SDDS_OR | (first ? SDDS_0_PREVIOUS : 0))) == -1) {
901 return 0;
902 }
903 first = 0;
904 }
905 }
906 return 1;
907}
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.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
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.

◆ free_edit_request()

void free_edit_request ( EDIT_NAME_REQUEST * edit_request,
long edit_requests )

Definition at line 1164 of file sddsmxref.c.

1164 {
1165 long i;
1166 if (edit_requests) {
1167 for (i = 0; i < edit_requests; i++) {
1168 free(edit_request[i].match_string);
1169 free(edit_request[i].edit_string);
1170 }
1171 free(edit_request);
1172 }
1173}
long edit_string(char *text, char *edit)
Edits the provided text based on the specified edit commands.
Definition edit_string.c:75
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.

◆ free_refdata()

void free_refdata ( REFDATA * refData,
long rename )

Definition at line 814 of file sddsmxref.c.

814 {
815 long i;
816 if (!rename) {
817 for (i = 0; i < refData->columns; i++) {
818 free(refData->orig_column[i]);
819 free(refData->new_column[i]);
820 }
821 for (i = 0; i < refData->parameters; i++) {
822 free(refData->orig_parameter[i]);
823 free(refData->new_parameter[i]);
824 }
825 for (i = 0; i < refData->arrays; i++) {
826 free(refData->orig_array[i]);
827 free(refData->new_array[i]);
828 }
829 }
830 if (refData->columns) {
831 free(refData->orig_column);
832 free(refData->new_column);
833 }
834 if (refData->parameters) {
835 free(refData->orig_parameter);
836 free(refData->new_parameter);
837 }
838 if (refData->arrays) {
839 free(refData->orig_array);
840 free(refData->new_array);
841 }
842}

◆ main()

int main ( int argc,
char ** argv )

Definition at line 199 of file sddsmxref.c.

199 {
200 SDDS_DATASET SDDS_1, SDDS_2, SDDS_output;
201 long i_arg, reuse, reusePage;
202 int64_t i, j, k, rows1, rows2, n;
203 SCANNED_ARG *s_arg;
204 char s[200], *ptr;
205 char **take_column, **leave_column, **output_column;
206 STRING_PAIR *match_column, *equate_column;
207 double *equate_tolerance;
208 long take_columns, leave_columns, match_columns, equate_columns, leave_all_columns;
209 int32_t output_columns;
210 char *input1, *input2, *output, *match_value;
211 long tmpfile_used, retval1, retval2;
212 long *row_used;
213 TRANSFER_DEFINITION *transfer;
214 long transfers;
215 long warnings, fillIn;
216 IFITEM_LIST ifnot_item, ifis_item;
217 unsigned long pipeFlags, majorOrderFlag;
218 REFDATA rename_data, take_RefData;
219 EDIT_NAME_REQUEST *edit_column_request, *edit_parameter_request, *edit_array_request;
220 long edit_column_requests, edit_parameter_requests, edit_array_requests;
221 short columnMajorOrder = -1;
222
224 argc = scanargs(&s_arg, argc, argv);
225 if (argc < 3) {
226 fprintf(stderr, "%s\n", USAGE);
227 exit(EXIT_FAILURE);
228 }
229
230 input1 = input2 = output = NULL;
231 take_column = leave_column = NULL;
232 match_column = equate_column = NULL;
233 equate_tolerance = NULL;
234 take_columns = leave_columns = match_columns = equate_columns = reuse = reusePage = 0;
235 tmpfile_used = 0;
236 transfer = NULL;
237 transfers = 0;
238 ifnot_item.items = ifis_item.items = 0;
239 warnings = 1;
240 pipeFlags = 0;
241 fillIn = 0;
242 leave_all_columns = 0;
243
244 rename_data.columns = rename_data.parameters = rename_data.arrays = 0;
245 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;
246 edit_column_request = edit_parameter_request = edit_array_request = NULL;
247 edit_column_requests = edit_parameter_requests = edit_array_requests = 0;
248 take_RefData.columns = take_RefData.parameters = take_RefData.arrays = 0;
249 take_RefData.orig_column = take_RefData.new_column = take_RefData.orig_parameter = take_RefData.new_parameter = take_RefData.orig_array = take_RefData.new_array = NULL;
250
251 for (i_arg = 1; i_arg < argc; i_arg++) {
252 if (s_arg[i_arg].arg_type == OPTION) {
253 delete_chars(s_arg[i_arg].list[0], "_");
254 switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
255 case SET_MAJOR_ORDER:
256 majorOrderFlag = 0;
257 s_arg[i_arg].n_items--;
258 if (s_arg[i_arg].n_items > 0 && (!scanItemList(&majorOrderFlag, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0, "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER, "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
259 SDDS_Bomb("invalid -majorOrder syntax/values");
260 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
261 columnMajorOrder = 1;
262 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
263 columnMajorOrder = 0;
264 break;
265 case SET_LEAVE_COLUMNS:
266 if (s_arg[i_arg].n_items < 2) {
267 fprintf(stderr, "%s\n", USAGE);
268 exit(EXIT_FAILURE);
269 }
270 leave_column = trealloc(leave_column, sizeof(*leave_column) * (leave_columns + s_arg[i_arg].n_items - 1));
271 for (i = 1; i < s_arg[i_arg].n_items; i++)
272 leave_column[i - 1 + leave_columns] = s_arg[i_arg].list[i];
273 leave_columns += s_arg[i_arg].n_items - 1;
274 break;
275 case SET_TAKE_COLUMNS:
276 if (s_arg[i_arg].n_items < 2) {
277 fprintf(stderr, "%s\n", USAGE);
278 exit(EXIT_FAILURE);
279 }
280 take_column = trealloc(take_column, sizeof(*take_column) * (take_columns + s_arg[i_arg].n_items - 1));
281 for (i = 1; i < s_arg[i_arg].n_items; i++)
282 take_column[i - 1 + take_columns] = s_arg[i_arg].list[i];
283 take_columns += s_arg[i_arg].n_items - 1;
284 break;
285 case SET_MATCH_COLUMNS:
286 if (s_arg[i_arg].n_items < 2) {
287 fprintf(stderr, "%s\n", USAGE);
288 exit(EXIT_FAILURE);
289 }
290 match_column = trealloc(match_column, sizeof(*match_column) * (match_columns + s_arg[i_arg].n_items - 1));
291 for (i = 1; i < s_arg[i_arg].n_items; i++) {
292 if ((ptr = strchr(s_arg[i_arg].list[i], '=')))
293 *ptr++ = 0;
294 else
295 ptr = s_arg[i_arg].list[i];
296 match_column[i - 1 + match_columns][0] = s_arg[i_arg].list[i];
297 match_column[i - 1 + match_columns][1] = ptr;
298 }
299 match_columns += s_arg[i_arg].n_items - 1;
300 break;
301 case SET_EQUATE_COLUMNS:
302 if (s_arg[i_arg].n_items < 2)
303 SDDS_Bomb("invalid -equate syntax");
304 equate_column = trealloc(equate_column, sizeof(*equate_column) * (equate_columns + s_arg[i_arg].n_items - 1));
305 equate_tolerance = trealloc(equate_tolerance, sizeof(*equate_tolerance) * (equate_columns + s_arg[i_arg].n_items - 1));
306 for (i = 1; i < s_arg[i_arg].n_items; i++) {
307 if (!tokenIsNumber(s_arg[i_arg].list[i])) {
308 if ((ptr = strchr(s_arg[i_arg].list[i], '=')))
309 *ptr++ = 0;
310 else
311 ptr = s_arg[i_arg].list[i];
312 equate_column[equate_columns][0] = s_arg[i_arg].list[i];
313 equate_column[equate_columns][1] = ptr;
314 equate_tolerance[equate_columns] = 0;
315 equate_columns += 1;
316 } else {
317 sscanf(s_arg[i_arg].list[i], "%le", &equate_tolerance[equate_columns - 1]);
318 }
319 }
320 break;
321 case SET_TRANSFER:
322 if (s_arg[i_arg].n_items < 3)
323 SDDS_Bomb("invalid -transfer syntax");
324 transfer = trealloc(transfer, sizeof(*transfer) * (transfers + s_arg[i_arg].n_items - 2));
325 switch (match_string(s_arg[i_arg].list[1], transfer_type, TRANSFER_TYPES, 0)) {
326 case PARAMETER_TRANSFER:
327 for (i = 2; i < s_arg[i_arg].n_items; i++) {
328 transfer[i - 2 + transfers].type = PARAMETER_TRANSFER;
329 transfer[i - 2 + transfers].name = s_arg[i_arg].list[i];
330 }
331 break;
332 case ARRAY_TRANSFER:
333 for (i = 2; i < s_arg[i_arg].n_items; i++) {
334 transfer[i - 2 + transfers].type = ARRAY_TRANSFER;
335 transfer[i - 2 + transfers].name = s_arg[i_arg].list[i];
336 }
337 break;
338 default:
339 SDDS_Bomb("unknown type of transfer");
340 break;
341 }
342 transfers += s_arg[i_arg].n_items - 2;
343 break;
344 case SET_REUSE:
345 if (s_arg[i_arg].n_items == 1)
346 reuse = 1;
347 else {
348 char *reuseOptions[2] = {"rows", "page"};
349 for (i = 1; i < s_arg[i_arg].n_items; i++) {
350 switch (match_string(s_arg[i_arg].list[i], reuseOptions, 2, 0)) {
351 case 0:
352 reuse = 1;
353 break;
354 case 1:
355 reusePage = 1;
356 break;
357 default:
358 SDDS_Bomb("unknown reuse keyword");
359 break;
360 }
361 }
362 }
363 break;
364 case SET_IFNOT:
365 if (s_arg[i_arg].n_items < 3)
366 SDDS_Bomb("invalid -ifnot usage");
367 add_ifitem(&ifnot_item, s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1);
368 break;
369 case SET_NOWARNINGS:
370 warnings = 0;
371 break;
372 case SET_IFIS:
373 if (s_arg[i_arg].n_items < 3)
374 SDDS_Bomb("invalid -ifis usage");
375 add_ifitem(&ifis_item, s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1);
376 break;
377 case SET_PIPE:
378 if (!processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
379 SDDS_Bomb("invalid -pipe syntax");
380 break;
381 case SET_FILLIN:
382 fillIn = 1;
383 break;
384 case SET_RENAME:
385 if (s_arg[i_arg].n_items < 3)
386 SDDS_Bomb("invalid -rename syntax");
387 switch (match_string(s_arg[i_arg].list[1], mode_name, MODES, 0)) {
388 case COLUMN_MODE:
389 k = rename_data.columns;
390 rename_data.new_column = trealloc(rename_data.new_column, sizeof(char *) * (k + s_arg[i_arg].n_items - 2));
391 rename_data.orig_column = trealloc(rename_data.orig_column, sizeof(char *) * (k + s_arg[i_arg].n_items - 2));
392 for (i = 2; i < s_arg[i_arg].n_items; i++) {
393 if (!(ptr = strchr(s_arg[i_arg].list[i], '=')))
394 SDDS_Bomb("invalid -rename syntax");
395 *ptr++ = 0;
396 rename_data.orig_column[k + i - 2] = s_arg[i_arg].list[i];
397 rename_data.new_column[k + i - 2] = ptr;
398 }
399 rename_data.columns += s_arg[i_arg].n_items - 2;
400 break;
401 case PARAMETER_MODE:
402 k = rename_data.parameters;
403 rename_data.new_parameter = trealloc(rename_data.new_parameter, sizeof(char *) * (k + s_arg[i_arg].n_items - 2));
404 rename_data.orig_parameter = trealloc(rename_data.orig_parameter, sizeof(char *) * (k + s_arg[i_arg].n_items - 2));
405 for (i = 2; i < s_arg[i_arg].n_items; i++) {
406 if (!(ptr = strchr(s_arg[i_arg].list[i], '=')))
407 SDDS_Bomb("invalid -rename syntax");
408 *ptr++ = 0;
409 rename_data.orig_parameter[k + i - 2] = s_arg[i_arg].list[i];
410 rename_data.new_parameter[k + i - 2] = ptr;
411 }
412 rename_data.parameters += s_arg[i_arg].n_items - 2;
413 break;
414 case ARRAY_MODE:
415 k = rename_data.arrays;
416 rename_data.new_array = trealloc(rename_data.new_array, sizeof(char *) * (k + s_arg[i_arg].n_items - 2));
417 rename_data.orig_array = trealloc(rename_data.orig_array, sizeof(char *) * (k + s_arg[i_arg].n_items - 2));
418 for (i = 2; i < s_arg[i_arg].n_items; i++) {
419 if (!(ptr = strchr(s_arg[i_arg].list[i], '=')))
420 SDDS_Bomb("invalid -rename syntax");
421 *ptr++ = 0;
422 rename_data.orig_array[k + i - 2] = s_arg[i_arg].list[i];
423 rename_data.new_array[k + i - 2] = ptr;
424 }
425 rename_data.arrays += s_arg[i_arg].n_items - 2;
426 break;
427 default:
428 SDDS_Bomb("invalid -rename syntax: specify column, parameter, or array keyword");
429 break;
430 }
431 break;
432 case SET_EDIT:
433 if (s_arg[i_arg].n_items != 4)
434 SDDS_Bomb("invalid -editnames syntax");
435 switch (match_string(s_arg[i_arg].list[1], mode_name, MODES, 0)) {
436 case COLUMN_MODE:
437 edit_column_request = trealloc(edit_column_request, sizeof(*edit_column_request) * (edit_column_requests + 1));
438 SDDS_CopyString(&edit_column_request[edit_column_requests].match_string, s_arg[i_arg].list[2]);
439 SDDS_CopyString(&edit_column_request[edit_column_requests].edit_string, s_arg[i_arg].list[3]);
440 edit_column_requests++;
441 break;
442 case PARAMETER_MODE:
443 edit_parameter_request = trealloc(edit_parameter_request, sizeof(*edit_parameter_request) * (edit_parameter_requests + 1));
444 SDDS_CopyString(&edit_parameter_request[edit_parameter_requests].match_string, s_arg[i_arg].list[2]);
445 SDDS_CopyString(&edit_parameter_request[edit_parameter_requests].edit_string, s_arg[i_arg].list[3]);
446 edit_parameter_requests++;
447 break;
448 case ARRAY_MODE:
449 edit_array_request = trealloc(edit_array_request, sizeof(*edit_array_request) * (edit_array_requests + 1));
450 SDDS_CopyString(&edit_array_request[edit_array_requests].match_string, s_arg[i_arg].list[2]);
451 SDDS_CopyString(&edit_array_request[edit_array_requests].edit_string, s_arg[i_arg].list[3]);
452 edit_array_requests++;
453 break;
454 default:
455 SDDS_Bomb("invalid -editnames syntax: specify column, parameter, or array keyword");
456 break;
457 }
458 break;
459 default:
460 fprintf(stderr, "Error: Unknown switch: %s\n%s\n", s_arg[i_arg].list[0], USAGE);
461 SDDS_Bomb(NULL);
462 break;
463 }
464 } else {
465 if (input1 == NULL)
466 input1 = s_arg[i_arg].list[0];
467 else if (input2 == NULL)
468 input2 = s_arg[i_arg].list[0];
469 else if (output == NULL)
470 output = s_arg[i_arg].list[0];
471 else {
472 fprintf(stderr, "Error: Too many filenames specified.\n%s\n", USAGE);
473 SDDS_Bomb("too many filenames");
474 }
475 }
476 }
477
478 if (pipeFlags & USE_STDIN && input1) {
479 if (output) {
480 fprintf(stderr, "Error: Too many filenames specified with -pipe option.\n%s\n", USAGE);
481 SDDS_Bomb("too many filenames (sddsmxref)");
482 }
483 output = input2;
484 input2 = input1;
485 input1 = NULL;
486 }
487 processFilenames("sddsmxref", &input1, &output, pipeFlags, !warnings, &tmpfile_used);
488 if (!input2) {
489 SDDS_Bomb("Second input file not specified");
490 exit(EXIT_FAILURE);
491 }
492
493 if (!SDDS_InitializeInput(&SDDS_1, input1)) {
494 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
495 exit(EXIT_FAILURE);
496 }
497 if (!check_ifitems(&SDDS_1, &ifnot_item, 0, warnings) || !check_ifitems(&SDDS_1, &ifis_item, 1, warnings))
498 exit(EXIT_SUCCESS);
499 if (!SDDS_InitializeInput(&SDDS_2, input2)) {
500 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
501 exit(EXIT_FAILURE);
502 }
503 /* Get parameter and array names from transfer */
504 if (transfers) {
505 if (!expandTransferRequests(&take_RefData.orig_parameter, &take_RefData.parameters, PARAMETER_TRANSFER, transfer, transfers, &SDDS_2) ||
506 !expandTransferRequests(&take_RefData.orig_array, &take_RefData.arrays, ARRAY_TRANSFER, transfer, transfers, &SDDS_2))
507 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
508 }
509 if (SDDS_ColumnCount(&SDDS_2)) {
510 SDDS_SetColumnFlags(&SDDS_2, 1);
511 if (take_columns) {
512 SDDS_SetColumnFlags(&SDDS_2, 0);
513 for (i = 0; i < take_columns; i++) {
514 if (!has_wildcards(take_column[i]) && SDDS_GetColumnIndex(&SDDS_2, take_column[i]) < 0) {
515 sprintf(s, "Error: Column '%s' not found in file '%s'", take_column[i], input2);
516 SDDS_SetError(s);
517 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
518 }
519 if (!SDDS_SetColumnsOfInterest(&SDDS_2, SDDS_MATCH_STRING, take_column[i], SDDS_OR))
520 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
521 }
522 }
523
524 leave_all_columns = 0;
525 if (leave_columns == 1 && strcmp(leave_column[0], "*") == 0)
526 leave_all_columns = 1;
527 else {
528 if (!take_columns)
529 SDDS_SetColumnFlags(&SDDS_2, 1);
530 for (i = 0; i < leave_columns; i++) {
531 if (!has_wildcards(leave_column[i]) &&
532 SDDS_GetColumnIndex(&SDDS_2, leave_column[i]) < 0)
533 continue;
534 if (!SDDS_SetColumnsOfInterest(&SDDS_2, SDDS_MATCH_STRING, leave_column[i], SDDS_AND | SDDS_NEGATE_MATCH))
535 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
536 }
537 if (leave_columns)
538 free(leave_column);
539 if (take_columns)
540 free(take_column);
541
542 if (!(take_RefData.orig_column = SDDS_GetColumnNames(&SDDS_2, &take_RefData.columns))) {
543 SDDS_SetError("Error: No columns selected to take from input file.");
544 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
545 }
546 }
547
548 for (i = 0; i < match_columns; i++) {
549 if ((j = SDDS_GetColumnIndex(&SDDS_1, match_column[i][0])) < 0 ||
550 SDDS_GetColumnType(&SDDS_1, j) != SDDS_STRING) {
551 sprintf(s, "Error: Column '%s' not found or not of string type in file '%s'.", match_column[i][0], input1 ? input1 : "stdin");
552 SDDS_SetError(s);
553 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
554 }
555 if ((j = SDDS_GetColumnIndex(&SDDS_2, match_column[i][1])) < 0 ||
556 SDDS_GetColumnType(&SDDS_2, j) != SDDS_STRING) {
557 sprintf(s, "Error: Column '%s' not found or not of string type in file '%s'.", match_column[i][1], input2);
558 SDDS_SetError(s);
559 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
560 }
561 }
562 for (i = 0; i < equate_columns; i++) {
563 if ((j = SDDS_GetColumnIndex(&SDDS_1, equate_column[i][0])) < 0 ||
565 sprintf(s, "Error: Column '%s' not found or not of numeric type in file '%s'.", equate_column[i][0], input1 ? input1 : "stdin");
566 SDDS_SetError(s);
567 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
568 }
569 if ((j = SDDS_GetColumnIndex(&SDDS_2, equate_column[i][1])) < 0 ||
571 sprintf(s, "Error: Column '%s' not found or not of numeric type in file '%s'.", equate_column[i][1], input2);
572 SDDS_SetError(s);
573 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
574 }
575 }
576
577 } else {
578 take_columns = 0;
579 take_RefData.columns = 0;
580 leave_all_columns = 1;
581 }
582 if (!take_RefData.columns && !leave_all_columns && warnings)
583 fprintf(stderr, "Warning: No columns being taken from '%s' that are not already in '%s'.\n",
584 input1 ? input1 : "stdin", input2);
585 if (leave_all_columns) {
586 take_RefData.columns = 0;
587 take_columns = 0;
588 }
589
590 if (output && (pipeFlags & USE_STDOUT))
591 SDDS_Bomb("Too many filenames specified with -pipe option.");
592 if (!output && !(pipeFlags & USE_STDOUT)) {
593 if (warnings)
594 fprintf(stderr, "Warning: Existing file '%s' will be replaced.\n", input1 ? input1 : "stdin");
595 tmpfile_used = 1;
596 cp_str(&output, tmpname(NULL));
597 }
598 if (!SDDS_InitializeCopy(&SDDS_output, &SDDS_1, output, "w")) {
599 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
600 exit(EXIT_FAILURE);
601 }
602 if (columnMajorOrder != -1)
603 SDDS_output.layout.data_mode.column_major = columnMajorOrder;
604 else
605 SDDS_output.layout.data_mode.column_major = SDDS_1.layout.data_mode.column_major;
606
607 /* Process new names for take RefData */
608 process_newnames(&SDDS_2, &take_RefData, rename_data, edit_column_request, edit_column_requests,
609 edit_parameter_request, edit_parameter_requests, edit_array_request, edit_array_requests);
610
611 for (i = 0; i < take_RefData.columns; i++) {
612 if (SDDS_GetColumnIndex(&SDDS_output, take_RefData.new_column[i]) >= 0) {
613 if (warnings)
614 fprintf(stderr, "Warning: Column '%s' already exists in the first input file. No data will be taken from column '%s' of the second input file.\n",
615 take_RefData.new_column[i], take_RefData.orig_column[i]);
616 free(take_RefData.new_column[i]);
617 free(take_RefData.orig_column[i]);
618 for (j = i; j < take_RefData.columns - 1; j++) {
619 take_RefData.new_column[j] = take_RefData.new_column[j + 1];
620 take_RefData.orig_column[j] = take_RefData.orig_column[j + 1];
621 }
622
623 take_RefData.columns -= 1;
624 i--;
625 if (take_RefData.columns == 0)
626 break;
627 } else {
628 if (!SDDS_TransferColumnDefinition(&SDDS_output, &SDDS_2, take_RefData.orig_column[i], take_RefData.new_column[i]))
629 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
630 }
631 }
632 if (!(output_column = (char **)SDDS_GetColumnNames(&SDDS_output, &output_columns)) || output_columns == 0) {
633 SDDS_SetError("Error: Problem getting output column names.");
634 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
635 }
636
637 for (i = 0; i < take_RefData.parameters; i++) {
638 if (SDDS_GetParameterIndex(&SDDS_output, take_RefData.new_parameter[i]) >= 0) {
639 free(take_RefData.orig_parameter[i]);
640 free(take_RefData.new_parameter[i]);
641 for (j = i; j < take_RefData.parameters - 1; j++)
642 take_RefData.orig_parameter[j] = take_RefData.orig_parameter[j + 1];
643 take_RefData.parameters -= 1;
644 i--;
645 if (take_RefData.parameters == 0)
646 break;
647 } else {
648 if (!SDDS_TransferParameterDefinition(&SDDS_output, &SDDS_2, take_RefData.orig_parameter[i], take_RefData.new_parameter[i]))
649 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
650 }
651 }
652
653 for (i = 0; i < take_RefData.arrays; i++) {
654 if (SDDS_GetArrayIndex(&SDDS_output, take_RefData.new_array[i]) < 0) {
655 free(take_RefData.orig_array[i]);
656 free(take_RefData.new_array[i]);
657 for (j = i; j < take_RefData.arrays - 1; j++)
658 take_RefData.orig_array[j] = take_RefData.orig_array[j + 1];
659 take_RefData.arrays -= 1;
660 i--;
661 if (take_RefData.arrays == 0)
662 break;
663 } else {
664 if (!SDDS_TransferArrayDefinition(&SDDS_output, &SDDS_2, take_RefData.orig_array[i], take_RefData.new_array[i]))
665 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
666 }
667 }
668 if (!SDDS_WriteLayout(&SDDS_output))
669 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
670 if (!take_RefData.columns && !leave_all_columns && warnings)
671 fprintf(stderr, "Warning: No columns being taken from '%s' that are not already in '%s'.\n", input2, input1 ? input1 : "stdin");
672 if (output_columns) {
673 for (i = 0; i < output_columns; i++)
674 free(output_column[i]);
675 free(output_column);
676 }
677 row_used = NULL;
678 while ((retval1 = SDDS_ReadPage(&SDDS_1)) > 0) {
679 if (!reusePage) {
680 if ((retval2 = SDDS_ReadPage(&SDDS_2)) <= 0) {
681 fprintf(stderr, "Warning: <input2> ends before <input1>.\n");
682 break;
683 }
684 } else {
685 if (retval1 == 1 && (retval2 = SDDS_ReadPage(&SDDS_2)) <= 0)
686 SDDS_Bomb("<input2> has no data");
687 SDDS_SetRowFlags(&SDDS_2, 1);
688 }
689 if (take_RefData.columns &&
690 (!SDDS_SetColumnFlags(&SDDS_2, 0) ||
691 !SDDS_SetColumnsOfInterest(&SDDS_2, SDDS_NAME_ARRAY, take_RefData.columns, take_RefData.orig_column)))
692 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
693 rows1 = SDDS_CountRowsOfInterest(&SDDS_1);
694 if ((rows2 = SDDS_CountRowsOfInterest(&SDDS_2))) {
695 row_used = SDDS_Realloc(row_used, sizeof(*row_used) * rows2);
696 SDDS_ZeroMemory(row_used, rows2 * sizeof(*row_used));
697 }
698 if (!SDDS_StartPage(&SDDS_output, rows1)) {
699 SDDS_SetError("Error: Problem starting output table.");
700 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
701 }
702 if (fillIn && !SDDS_ClearPage(&SDDS_output)) {
703 SDDS_SetError("Error: Problem clearing output table.");
704 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
705 }
706 /* Copy parameters and arrays */
707 if (!CopyParametersFromSecondInput(&SDDS_output, &SDDS_2, take_RefData)) {
708 SDDS_SetError("Error: Problem copying parameters from second input file.");
709 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
710 }
711 if (!CopyArraysFromSecondInput(&SDDS_output, &SDDS_2, take_RefData)) {
712 SDDS_SetError("Error: Problem copying arrays from second input file.");
713 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
714 }
715 if (!SDDS_CopyParameters(&SDDS_output, &SDDS_1) ||
716 !SDDS_CopyArrays(&SDDS_output, &SDDS_1)) {
717 SDDS_SetError("Error: Problem copying parameters or arrays from first input file.");
718 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
719 }
720 for (j = 0; j < rows1; j++) {
721 if (!SDDS_CopyRowDirect(&SDDS_output, j, &SDDS_1, j)) {
722 sprintf(s, "Error: Problem copying row %" PRId64 " of first data set.", j);
723 SDDS_SetError(s);
724 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
725 }
726 SDDS_output.row_flag[j] = 1;
727 if (!match_columns && !equate_columns && !leave_all_columns) {
728 if (j >= rows2) {
729 if (warnings)
730 fprintf(stderr, "Warning: No match for row %" PRId64 " (value %s)\n", j, match_value);
731 SDDS_output.row_flag[j] = 0;
732 continue;
733 }
734 if (!CopyRowToNewColumn(&SDDS_output, j, &SDDS_2, j, take_RefData, take_RefData.columns, input2)) {
735 fprintf(stderr, "Error: Failed to copy data to output.\n");
736 exit(EXIT_FAILURE);
737 }
738 continue;
739 }
740 if (!leave_all_columns) {
741 SDDS_SetRowFlags(&SDDS_2, 1);
742 for (i = 0; i < match_columns; i++) {
743 if (!SDDS_GetValue(&SDDS_1, match_column[i][0], j, &match_value)) {
744 sprintf(s, "Error: Problem getting column '%s' from file '%s'.", match_column[i][0], input1 ? input1 : "stdin");
745 SDDS_SetError(s);
746 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
747 }
748 if (SDDS_MatchRowsOfInterest(&SDDS_2, match_column[i][1], match_value, SDDS_AND) < 0) {
749 sprintf(s, "Error: Problem setting rows of interest for column '%s'.", match_column[i][1]);
750 SDDS_SetError(s);
751 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
752 }
753 free(match_value);
754 }
755 if (!(n = SDDS_CountRowsOfInterest(&SDDS_2))) {
756 if (warnings)
757 fprintf(stderr, "Warning: No match for row %" PRId64 "\n", j);
758 SDDS_output.row_flag[j] = 0;
759 continue;
760 }
761 i = -1; /* Counter for rows-of-interest in file 2 */
762 for (k = 0; k < rows2; k++) {
763 if (!SDDS_2.row_flag[k])
764 continue;
765 i++;
766 if (!row_used[k] && rows_equate(&SDDS_1, j, &SDDS_2, k, equate_columns, equate_column, equate_tolerance)) {
767 row_used[k] = reuse ? 0 : 1;
768 if (!CopyRowToNewColumn(&SDDS_output, j, &SDDS_2, k, take_RefData, take_RefData.columns, input2)) {
769 fprintf(stderr, "Error: Failed to copy data to output.\n");
770 exit(EXIT_FAILURE);
771 }
772 break;
773 }
774 }
775 if (k == rows2) {
776 if (warnings)
777 fprintf(stderr, "Warning: No match for row %" PRId64 "\n", j);
778 if (!fillIn)
779 SDDS_output.row_flag[j] = 0;
780 continue;
781 }
782 }
783 }
784 if (!SDDS_WritePage(&SDDS_output)) {
785 SDDS_SetError("Error: Problem writing data to output file.");
786 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
787 }
788 }
789
790 if (!SDDS_Terminate(&SDDS_1) || !SDDS_Terminate(&SDDS_2) || !SDDS_Terminate(&SDDS_output)) {
791 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
792 exit(EXIT_FAILURE);
793 }
794 if (tmpfile_used && !replaceFileAndBackUp(input1, output))
795 exit(EXIT_FAILURE);
796 free_scanargs(&s_arg, argc);
797 if (row_used)
798 free(row_used);
799
800 free_refdata(&take_RefData, 0);
801 free_refdata(&rename_data, 1);
802
803 free_edit_request(edit_column_request, edit_column_requests);
804 free_edit_request(edit_parameter_request, edit_parameter_requests);
805 free_edit_request(edit_array_request, edit_array_requests);
806 if (match_columns)
807 free(match_column);
808 if (equate_columns)
809 free(equate_column);
810
811 return EXIT_SUCCESS;
812}
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_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
int32_t SDDS_ClearPage(SDDS_DATASET *SDDS_dataset)
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.
int64_t SDDS_MatchRowsOfInterest(SDDS_DATASET *SDDS_dataset, char *selection_column, char *label_to_match, int32_t logic)
Matches and marks rows of interest in an SDDS dataset based on label matching.
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.
void * SDDS_GetValue(SDDS_DATASET *SDDS_dataset, char *column_name, int64_t srow_index, void *memory)
Retrieves the value from a specified column and selected row, optionally storing it in provided memor...
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_ZeroMemory(void *mem, int64_t n_bytes)
Sets a block of memory to zero.
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.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
#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
char * cp_str(char **s, char *t)
Copies a string, allocating memory for storage.
Definition cp_str.c:28
long tokenIsNumber(char *token)
Checks if the given token represents a valid number.
Definition data_scan.c:530
char * delete_chars(char *s, char *t)
Removes all occurrences of characters found in string t from string s.
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
void free_scanargs(SCANNED_ARG **scanned, int argc)
Definition scanargs.c:584
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.
char * tmpname(char *s)
Supplies a unique temporary filename.
Definition tmpname.c:34
int has_wildcards(char *template)
Check if a template string contains any wildcard characters.
Definition wild_match.c:498

◆ process_editnames()

char ** process_editnames ( char ** orig_name,
long ** orig_flags,
long orig_names,
EDIT_NAME_REQUEST * edit_request,
long edit_requests )

Definition at line 1016 of file sddsmxref.c.

1016 {
1017 long i, j;
1018 char **new_name, s[1024];
1019 char *ptr, **editstr;
1020 char edit_buffer[1024];
1021
1022 *orig_flags = NULL;
1023
1024 *orig_flags = tmalloc(sizeof(**orig_flags) * orig_names);
1025 new_name = tmalloc(sizeof(*new_name) * orig_names);
1026
1027 editstr = (char **)malloc(sizeof(*editstr) * edit_requests);
1028 ptr = malloc(sizeof(char) * 256);
1029 sprintf(s, "%" PRId32, 2);
1030
1031 for (i = 0; i < edit_requests; i++) {
1032 SDDS_CopyString(&editstr[i], edit_request[i].edit_string);
1033 if (strstr(editstr[i], "%%ld"))
1034 replace_string(ptr, editstr[i], "%%ld", "%ld");
1035 else if (strstr(editstr[i], "%ld"))
1036 replace_string(ptr, editstr[i], "%ld", s);
1037 else
1038 continue;
1039 free(editstr[i]);
1040 SDDS_CopyString(&editstr[i], ptr);
1041 }
1042 free(ptr);
1043 ptr = NULL;
1044 for (j = 0; j < orig_names; j++) {
1045 (*orig_flags)[j] = 0;
1046 SDDS_CopyString(&new_name[j], orig_name[j]);
1047 for (i = 0; i < edit_requests; i++) {
1048 ptr = expand_ranges(edit_request[i].match_string);
1049 free(edit_request[i].match_string);
1050 edit_request[i].match_string = ptr;
1051 if (wild_match(new_name[j], edit_request[i].match_string)) {
1052 strcpy(edit_buffer, new_name[j]);
1053 if (!edit_string(edit_buffer, editstr[i]))
1054 SDDS_Bomb("Error editing name");
1055 free(new_name[j]);
1056 SDDS_CopyString(&new_name[j], edit_buffer);
1057 (*orig_flags)[j] = 1;
1058 }
1059 }
1060 }
1061
1062 for (i = 0; i < edit_requests; i++)
1063 free(editstr[i]);
1064 free(editstr);
1065 return new_name;
1066}
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:59
int replace_string(char *t, char *s, char *orig, char *repl)
Replace all occurrences of one string with another string.
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

◆ process_newnames()

void process_newnames ( SDDS_DATASET * SDDS_dataset,
REFDATA * take_RefData,
REFDATA rename_data,
EDIT_NAME_REQUEST * edit_column_request,
long edit_column_requests,
EDIT_NAME_REQUEST * edit_parameter_request,
long edit_parameter_requests,
EDIT_NAME_REQUEST * edit_array_request,
long edit_array_requests )

Definition at line 909 of file sddsmxref.c.

912 {
913 long i, k = 0, *orig_columnflags;
914 long *orig_parameterflags, *orig_arrayflags;
915 char **column_names, **parameter_names, **array_names, **new_names;
916 int32_t columns, parameters, arrays;
917
918 columns = parameters = arrays = 0;
919 column_names = parameter_names = array_names = new_names = NULL;
920 orig_columnflags = orig_parameterflags = orig_arrayflags = NULL;
921
922 if (take_RefData->columns)
923 take_RefData->new_column = (char **)malloc(sizeof(*(take_RefData->new_column)) * take_RefData->columns);
924 if (take_RefData->parameters)
925 take_RefData->new_parameter = (char **)malloc(sizeof(*(take_RefData->new_parameter)) * take_RefData->parameters);
926 if (take_RefData->arrays)
927 take_RefData->new_array = (char **)malloc(sizeof(*(take_RefData->new_array)) * take_RefData->arrays);
928
929 /* Transfer renames to take_RefData */
930 for (i = 0; i < take_RefData->columns; i++)
931 if ((k = match_string(take_RefData->orig_column[i], rename_data.orig_column, rename_data.columns, EXACT_MATCH)) >= 0)
932 SDDS_CopyString(&take_RefData->new_column[i], rename_data.new_column[k]);
933 else
934 SDDS_CopyString(&take_RefData->new_column[i], take_RefData->orig_column[i]);
935
936 for (i = 0; i < take_RefData->parameters; i++)
937 if ((k = match_string(take_RefData->orig_parameter[i], rename_data.orig_parameter, rename_data.parameters, EXACT_MATCH)) >= 0)
938 SDDS_CopyString(&take_RefData->new_parameter[i], rename_data.new_parameter[k]);
939 else
940 SDDS_CopyString(&take_RefData->new_parameter[i], take_RefData->orig_parameter[i]);
941 for (i = 0; i < take_RefData->arrays; i++)
942 if ((k = match_string(take_RefData->orig_array[i], rename_data.orig_array, rename_data.arrays, EXACT_MATCH)) >= 0)
943 SDDS_CopyString(&take_RefData->new_array[i], rename_data.new_array[k]);
944 else
945 SDDS_CopyString(&take_RefData->new_array[i], take_RefData->orig_array[i]);
946
947 if (!(column_names = SDDS_GetColumnNames(SDDS_dataset, &columns))) {
948 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
949 exit(EXIT_FAILURE);
950 }
951 if (!(parameter_names = SDDS_GetParameterNames(SDDS_dataset, &parameters))) {
952 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
953 exit(EXIT_FAILURE);
954 }
955
956 if (!(array_names = SDDS_GetArrayNames(SDDS_dataset, &arrays))) {
957 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
958 exit(EXIT_FAILURE);
959 }
960
961 /* Process edit names */
962 if (edit_column_requests) {
963 if ((new_names = process_editnames(column_names, &orig_columnflags, columns, edit_column_request, edit_column_requests))) {
964 for (i = 0; i < columns; i++) {
965 if (orig_columnflags[i]) {
966 if ((k = match_string(column_names[i], take_RefData->orig_column, take_RefData->columns, EXACT_MATCH)) >= 0)
967 SDDS_CopyString(&take_RefData->new_column[k], new_names[i]);
968 }
969 free(new_names[i]);
970 }
971 free(new_names);
972 }
973 }
974 if (edit_parameter_requests) {
975 if ((new_names = process_editnames(parameter_names, &orig_parameterflags, parameters, edit_parameter_request, edit_parameter_requests))) {
976 for (i = 0; i < parameters; i++) {
977 if (orig_parameterflags[i]) {
978 if ((k = match_string(parameter_names[i], take_RefData->orig_parameter, take_RefData->parameters, EXACT_MATCH)) >= 0)
979 SDDS_CopyString(&take_RefData->new_parameter[k], new_names[i]);
980 }
981 free(new_names[i]);
982 }
983 free(new_names);
984 }
985 }
986
987 if (edit_array_requests) {
988 if ((new_names = process_editnames(array_names, &orig_arrayflags, arrays, edit_array_request, edit_array_requests))) {
989 for (i = 0; i < arrays; i++) {
990 if (orig_arrayflags[i]) {
991 if ((k = match_string(array_names[i], take_RefData->orig_array, take_RefData->arrays, EXACT_MATCH)) >= 0)
992 SDDS_CopyString(&take_RefData->new_array[k], new_names[i]);
993 }
994 free(new_names[i]);
995 }
996 free(new_names);
997 }
998 }
999 if (orig_columnflags)
1000 free(orig_columnflags);
1001 if (orig_parameterflags)
1002 free(orig_parameterflags);
1003 if (orig_arrayflags)
1004 free(orig_arrayflags);
1005 for (i = 0; i < columns; i++)
1006 free(column_names[i]);
1007 free(column_names);
1008 for (i = 0; i < parameters; i++)
1009 free(parameter_names[i]);
1010 free(parameter_names);
1011 for (i = 0; i < arrays; i++)
1012 free(array_names[i]);
1013 free(array_names);
1014}
char ** SDDS_GetParameterNames(SDDS_DATASET *SDDS_dataset, int32_t *number)
Retrieves the names of all parameters in the SDDS dataset.
char ** SDDS_GetArrayNames(SDDS_DATASET *SDDS_dataset, int32_t *number)
Retrieves the names of all arrays in the SDDS dataset.

◆ rows_equate()

long rows_equate ( SDDS_DATASET * SDDS1,
int64_t row1,
SDDS_DATASET * SDDS2,
int64_t row2,
long equate_columns,
STRING_PAIR * equate_column,
double * equate_tolerance )

Definition at line 844 of file sddsmxref.c.

844 {
845 char *data1, *data2;
846 long index1, index2, size, type1, type2, i;
847 char s[SDDS_MAXLINE];
848 index2 = 0;
849 for (i = 0; i < equate_columns; i++) {
850 if ((index1 = SDDS_GetColumnIndex(SDDS1, equate_column[i][0])) < 0 ||
851 (index2 = SDDS_GetColumnIndex(SDDS2, equate_column[i][1])) < 0) {
852 SDDS_SetError("Problem equating rows");
853 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
854 }
855 type1 = SDDS1->layout.column_definition[index1].type;
856 type2 = SDDS2->layout.column_definition[index2].type;
857 if (equate_tolerance[i] == 0) {
858 if (type1 != type2) {
859 sprintf(s, "Problem equating rows--types don't match for column '%s'='%s'", equate_column[i][0], equate_column[i][1]);
860 SDDS_SetError(s);
861 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
862 }
863 size = SDDS_GetTypeSize(type1);
864 data1 = (char *)SDDS1->data[index1] + size * row1;
865 data2 = (char *)SDDS2->data[index2] + size * row2;
866 if (memcmp(data1, data2, size) != 0)
867 return 0;
868 } else {
869 double d1, d2;
870 SDDS_CastValue(SDDS1->data, index1, type1, SDDS_DOUBLE, &d1);
871 SDDS_CastValue(SDDS2->data, index2, type2, SDDS_DOUBLE, &d2);
872 if (fabs(d1 - d2) > equate_tolerance[i])
873 return 0;
874 }
875 }
876 return 1;
877}
void * SDDS_CastValue(void *data, int64_t index, int32_t data_type, int32_t desired_type, void *memory)
Casts a value from one SDDS data type to another.
int32_t SDDS_GetTypeSize(int32_t type)
Retrieves the size in bytes of a specified SDDS data type.
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37