SDDSlib
Loading...
Searching...
No Matches
sddsmxref.c File Reference

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

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

Go to the source code of this file.

Classes

struct  TRANSFER_DEFINITION
 
struct  REFDATA
 
struct  EDIT_NAME_REQUEST
 

Macros

#define PARAMETER_TRANSFER   0
 
#define ARRAY_TRANSFER   1
 
#define TRANSFER_TYPES   2
 
#define COLUMN_MODE   0
 
#define PARAMETER_MODE   1
 
#define ARRAY_MODE   2
 
#define MODES   3
 

Typedefs

typedef char * STRING_PAIR[2]
 

Enumerations

enum  option_type {
  SET_TAKE_COLUMNS , SET_LEAVE_COLUMNS , SET_MATCH_COLUMNS , SET_EQUATE_COLUMNS ,
  SET_TRANSFER , SET_REUSE , SET_IFNOT , SET_NOWARNINGS ,
  SET_IFIS , SET_PIPE , SET_FILLIN , SET_RENAME ,
  SET_EDIT , SET_MAJOR_ORDER , N_OPTIONS
}
 

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)
 

Variables

char * option [N_OPTIONS]
 
static char * transfer_type [TRANSFER_TYPES]
 
static char * mode_name [MODES]
 
char * USAGE
 

Detailed Description

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

The program sddsmxref takes columns, parameters, and arrays from successive tables in an input file and adds them to corresponding tables in another input file. The matching is based on specified column criteria. The output can be directed to a new file or replace the first input file.

Usage:

sddsmxref [<input1>] <input2> [<output>] [options]

Options: -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>][,<tolerance>][,...] -reuse[=[rows][,page]] -rename={column|parameter|array},<oldname>=<newname>[,...] -editnames={column|parameter|array},<wildcard-string>,<edit-string> -majorOrder=row|column

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.

Macro Definition Documentation

◆ ARRAY_MODE

#define ARRAY_MODE   2

Definition at line 115 of file sddsmxref.c.

◆ ARRAY_TRANSFER

#define ARRAY_TRANSFER   1

Definition at line 83 of file sddsmxref.c.

◆ COLUMN_MODE

#define COLUMN_MODE   0

Definition at line 113 of file sddsmxref.c.

◆ MODES

#define MODES   3

Definition at line 116 of file sddsmxref.c.

◆ PARAMETER_MODE

#define PARAMETER_MODE   1

Definition at line 114 of file sddsmxref.c.

◆ PARAMETER_TRANSFER

#define PARAMETER_TRANSFER   0

Definition at line 82 of file sddsmxref.c.

◆ TRANSFER_TYPES

#define TRANSFER_TYPES   2

Definition at line 84 of file sddsmxref.c.

Typedef Documentation

◆ STRING_PAIR

typedef char* STRING_PAIR[2]

Definition at line 136 of file sddsmxref.c.

Enumeration Type Documentation

◆ option_type

enum option_type

Definition at line 47 of file sddsmxref.c.

47 {
48 SET_TAKE_COLUMNS,
49 SET_LEAVE_COLUMNS,
50 SET_MATCH_COLUMNS,
51 SET_EQUATE_COLUMNS,
52 SET_TRANSFER,
53 SET_REUSE,
54 SET_IFNOT,
55 SET_NOWARNINGS,
56 SET_IFIS,
57 SET_PIPE,
58 SET_FILLIN,
59 SET_RENAME,
60 SET_EDIT,
61 SET_MAJOR_ORDER,
62 N_OPTIONS
63};

Function Documentation

◆ CopyArraysFromSecondInput()

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

Definition at line 1054 of file sddsmxref.c.

1054 {
1055 long i, j, k, m;
1056 char s[1024];
1057
1058 if (new_data.arrays == 0)
1059 return 1;
1060 for (i = 0; i < new_data.arrays; i++) {
1061 if ((j = SDDS_GetArrayIndex(SDDS_source, new_data.orig_array[i])) < 0)
1062 continue;
1063 if ((k = SDDS_GetArrayIndex(SDDS_target, new_data.new_array[i])) < 0) {
1064 sprintf(s, "Warning: Array '%s' not defined in output.\n", new_data.new_array[i]);
1065 SDDS_SetError(s);
1066 continue;
1067 }
1068 if (SDDS_source->layout.array_definition[j].type != SDDS_target->layout.array_definition[k].type) {
1069 SDDS_SetError("Error: Cannot copy arrays of different types.");
1070 return 0;
1071 }
1072 SDDS_target->array[k].definition = SDDS_target->layout.array_definition + k;
1073 SDDS_target->array[k].elements = SDDS_source->array[j].elements;
1074 if (!(SDDS_target->array[k].dimension = (int32_t *)SDDS_Malloc(sizeof(*SDDS_target->array[k].dimension) * SDDS_target->array[k].definition->dimensions)) ||
1075 !(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))) {
1076 SDDS_SetError("Error: Unable to copy arrays due to memory allocation failure.");
1077 return 0;
1078 }
1079 for (m = 0; m < SDDS_target->array[k].definition->dimensions; m++)
1080 SDDS_target->array[k].dimension[m] = SDDS_source->array[j].dimension[m];
1081
1082 if (SDDS_target->array[k].definition->type != SDDS_STRING)
1083 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);
1084 else if (!SDDS_CopyStringArray(SDDS_target->array[k].data, SDDS_source->array[j].data, SDDS_target->array[k].elements)) {
1085 SDDS_SetError("Error: Unable to copy string arrays.");
1086 return 0;
1087 }
1088 }
1089 return 1;
1090}
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 1030 of file sddsmxref.c.

1030 {
1031 long i, j, k;
1032 char s[1024];
1033
1034 if (new_data.parameters == 0)
1035 return 1;
1036 for (i = 0; i < new_data.parameters; i++) {
1037 if ((j = SDDS_GetParameterIndex(SDDS_source, new_data.orig_parameter[i])) < 0) {
1038 continue;
1039 }
1040
1041 if ((k = SDDS_GetParameterIndex(SDDS_target, new_data.new_parameter[i])) < 0) {
1042 fprintf(stderr, "Warning: Parameter '%s' not defined in output.\n", new_data.new_parameter[i]);
1043 continue;
1044 }
1045 if (!SDDS_SetParameters(SDDS_target, SDDS_SET_BY_INDEX | SDDS_PASS_BY_REFERENCE, k, SDDS_source->parameter[j], -1)) {
1046 sprintf(s, "Unable to copy parameters for parameter '%s'", new_data.new_parameter[i]);
1047 SDDS_SetError(s);
1048 return 0;
1049 }
1050 }
1051 return 1;
1052}
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 1092 of file sddsmxref.c.

1092 {
1093 long i, j, k, type, size;
1094 char s[1024];
1095
1096 if (!columns)
1097 return 1;
1098
1099 for (i = 0; i < columns; i++) {
1100 if ((j = SDDS_GetColumnIndex(source, new_data.orig_column[i])) < 0) {
1101 sprintf(s, "Error: Column '%s' not found in file '%s'.\n", new_data.orig_column[i], input2);
1102 SDDS_SetError(s);
1103 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1104 continue;
1105 }
1106 if ((k = SDDS_GetColumnIndex(target, new_data.new_column[i])) < 0) {
1107 sprintf(s, "Error: Column '%s' not defined in output.\n", new_data.new_column[i]);
1108 SDDS_SetError(s);
1109 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1110 continue;
1111 }
1112
1113 if ((type = SDDS_GetColumnType(target, k)) == SDDS_STRING) {
1114 if (!SDDS_CopyString(((char ***)target->data)[k] + target_row, ((char ***)source->data)[j][source_row])) {
1115 SDDS_SetError("Error: Unable to copy string data.");
1116 return 0;
1117 }
1118 } else {
1119 size = SDDS_type_size[type - 1];
1120 memcpy((char *)target->data[k] + size * target_row, (char *)source->data[j] + size * source_row, size);
1121 }
1122 }
1123 return 1;
1124}
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 841 of file sddsmxref.c.

841 {
842 long i, first;
843 int32_t (*matchRoutine)(SDDS_DATASET *SDDS_dataset, char ***nameReturn, int32_t matchMode, int32_t typeMode, ...);
844
845 *matches = 0;
846 *match = NULL;
847 switch (type) {
848 case PARAMETER_TRANSFER:
849 matchRoutine = SDDS_MatchParameters;
850 break;
851 case ARRAY_TRANSFER:
852 matchRoutine = SDDS_MatchArrays;
853 break;
854 default:
855 SDDS_Bomb("Invalid transfer type--this shouldn't happen");
856 exit(EXIT_FAILURE);
857 break;
858 }
859 first = 0;
860 for (i = 0; i < transfers; i++) {
861 if (transfer[i].type == type) {
862 if ((*matches = (*matchRoutine)(inSet, match, SDDS_MATCH_STRING, FIND_ANY_TYPE, transfer[i].name, SDDS_OR | (first ? SDDS_0_PREVIOUS : 0))) == -1) {
863 return 0;
864 }
865 first = 0;
866 }
867 }
868 return 1;
869}
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 1126 of file sddsmxref.c.

1126 {
1127 long i;
1128 if (edit_requests) {
1129 for (i = 0; i < edit_requests; i++) {
1130 free(edit_request[i].match_string);
1131 free(edit_request[i].edit_string);
1132 }
1133 free(edit_request);
1134 }
1135}
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 776 of file sddsmxref.c.

776 {
777 long i;
778 if (!rename) {
779 for (i = 0; i < refData->columns; i++) {
780 free(refData->orig_column[i]);
781 free(refData->new_column[i]);
782 }
783 for (i = 0; i < refData->parameters; i++) {
784 free(refData->orig_parameter[i]);
785 free(refData->new_parameter[i]);
786 }
787 for (i = 0; i < refData->arrays; i++) {
788 free(refData->orig_array[i]);
789 free(refData->new_array[i]);
790 }
791 }
792 if (refData->columns) {
793 free(refData->orig_column);
794 free(refData->new_column);
795 }
796 if (refData->parameters) {
797 free(refData->orig_parameter);
798 free(refData->new_parameter);
799 }
800 if (refData->arrays) {
801 free(refData->orig_array);
802 free(refData->new_array);
803 }
804}

◆ main()

int main ( int argc,
char ** argv )

Definition at line 161 of file sddsmxref.c.

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

978 {
979 long i, j;
980 char **new_name, s[1024];
981 char *ptr, **editstr;
982 char edit_buffer[1024];
983
984 *orig_flags = NULL;
985
986 *orig_flags = tmalloc(sizeof(**orig_flags) * orig_names);
987 new_name = tmalloc(sizeof(*new_name) * orig_names);
988
989 editstr = (char **)malloc(sizeof(*editstr) * edit_requests);
990 ptr = malloc(sizeof(char) * 256);
991 sprintf(s, "%" PRId32, 2);
992
993 for (i = 0; i < edit_requests; i++) {
994 SDDS_CopyString(&editstr[i], edit_request[i].edit_string);
995 if (strstr(editstr[i], "%%ld"))
996 replace_string(ptr, editstr[i], "%%ld", "%ld");
997 else if (strstr(editstr[i], "%ld"))
998 replace_string(ptr, editstr[i], "%ld", s);
999 else
1000 continue;
1001 free(editstr[i]);
1002 SDDS_CopyString(&editstr[i], ptr);
1003 }
1004 free(ptr);
1005 ptr = NULL;
1006 for (j = 0; j < orig_names; j++) {
1007 (*orig_flags)[j] = 0;
1008 SDDS_CopyString(&new_name[j], orig_name[j]);
1009 for (i = 0; i < edit_requests; i++) {
1010 ptr = expand_ranges(edit_request[i].match_string);
1011 free(edit_request[i].match_string);
1012 edit_request[i].match_string = ptr;
1013 if (wild_match(new_name[j], edit_request[i].match_string)) {
1014 strcpy(edit_buffer, new_name[j]);
1015 if (!edit_string(edit_buffer, editstr[i]))
1016 SDDS_Bomb("Error editing name");
1017 free(new_name[j]);
1018 SDDS_CopyString(&new_name[j], edit_buffer);
1019 (*orig_flags)[j] = 1;
1020 }
1021 }
1022 }
1023
1024 for (i = 0; i < edit_requests; i++)
1025 free(editstr[i]);
1026 free(editstr);
1027 return new_name;
1028}
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 871 of file sddsmxref.c.

874 {
875 long i, k = 0, *orig_columnflags;
876 long *orig_parameterflags, *orig_arrayflags;
877 char **column_names, **parameter_names, **array_names, **new_names;
878 int32_t columns, parameters, arrays;
879
880 columns = parameters = arrays = 0;
881 column_names = parameter_names = array_names = new_names = NULL;
882 orig_columnflags = orig_parameterflags = orig_arrayflags = NULL;
883
884 if (take_RefData->columns)
885 take_RefData->new_column = (char **)malloc(sizeof(*(take_RefData->new_column)) * take_RefData->columns);
886 if (take_RefData->parameters)
887 take_RefData->new_parameter = (char **)malloc(sizeof(*(take_RefData->new_parameter)) * take_RefData->parameters);
888 if (take_RefData->arrays)
889 take_RefData->new_array = (char **)malloc(sizeof(*(take_RefData->new_array)) * take_RefData->arrays);
890
891 /* Transfer renames to take_RefData */
892 for (i = 0; i < take_RefData->columns; i++)
893 if ((k = match_string(take_RefData->orig_column[i], rename_data.orig_column, rename_data.columns, EXACT_MATCH)) >= 0)
894 SDDS_CopyString(&take_RefData->new_column[i], rename_data.new_column[k]);
895 else
896 SDDS_CopyString(&take_RefData->new_column[i], take_RefData->orig_column[i]);
897
898 for (i = 0; i < take_RefData->parameters; i++)
899 if ((k = match_string(take_RefData->orig_parameter[i], rename_data.orig_parameter, rename_data.parameters, EXACT_MATCH)) >= 0)
900 SDDS_CopyString(&take_RefData->new_parameter[i], rename_data.new_parameter[k]);
901 else
902 SDDS_CopyString(&take_RefData->new_parameter[i], take_RefData->orig_parameter[i]);
903 for (i = 0; i < take_RefData->arrays; i++)
904 if ((k = match_string(take_RefData->orig_array[i], rename_data.orig_array, rename_data.arrays, EXACT_MATCH)) >= 0)
905 SDDS_CopyString(&take_RefData->new_array[i], rename_data.new_array[k]);
906 else
907 SDDS_CopyString(&take_RefData->new_array[i], take_RefData->orig_array[i]);
908
909 if (!(column_names = SDDS_GetColumnNames(SDDS_dataset, &columns))) {
910 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
911 exit(EXIT_FAILURE);
912 }
913 if (!(parameter_names = SDDS_GetParameterNames(SDDS_dataset, &parameters))) {
914 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
915 exit(EXIT_FAILURE);
916 }
917
918 if (!(array_names = SDDS_GetArrayNames(SDDS_dataset, &arrays))) {
919 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
920 exit(EXIT_FAILURE);
921 }
922
923 /* Process edit names */
924 if (edit_column_requests) {
925 if ((new_names = process_editnames(column_names, &orig_columnflags, columns, edit_column_request, edit_column_requests))) {
926 for (i = 0; i < columns; i++) {
927 if (orig_columnflags[i]) {
928 if ((k = match_string(column_names[i], take_RefData->orig_column, take_RefData->columns, EXACT_MATCH)) >= 0)
929 SDDS_CopyString(&take_RefData->new_column[k], new_names[i]);
930 }
931 free(new_names[i]);
932 }
933 free(new_names);
934 }
935 }
936 if (edit_parameter_requests) {
937 if ((new_names = process_editnames(parameter_names, &orig_parameterflags, parameters, edit_parameter_request, edit_parameter_requests))) {
938 for (i = 0; i < parameters; i++) {
939 if (orig_parameterflags[i]) {
940 if ((k = match_string(parameter_names[i], take_RefData->orig_parameter, take_RefData->parameters, EXACT_MATCH)) >= 0)
941 SDDS_CopyString(&take_RefData->new_parameter[k], new_names[i]);
942 }
943 free(new_names[i]);
944 }
945 free(new_names);
946 }
947 }
948
949 if (edit_array_requests) {
950 if ((new_names = process_editnames(array_names, &orig_arrayflags, arrays, edit_array_request, edit_array_requests))) {
951 for (i = 0; i < arrays; i++) {
952 if (orig_arrayflags[i]) {
953 if ((k = match_string(array_names[i], take_RefData->orig_array, take_RefData->arrays, EXACT_MATCH)) >= 0)
954 SDDS_CopyString(&take_RefData->new_array[k], new_names[i]);
955 }
956 free(new_names[i]);
957 }
958 free(new_names);
959 }
960 }
961 if (orig_columnflags)
962 free(orig_columnflags);
963 if (orig_parameterflags)
964 free(orig_parameterflags);
965 if (orig_arrayflags)
966 free(orig_arrayflags);
967 for (i = 0; i < columns; i++)
968 free(column_names[i]);
969 free(column_names);
970 for (i = 0; i < parameters; i++)
971 free(parameter_names[i]);
972 free(parameter_names);
973 for (i = 0; i < arrays; i++)
974 free(array_names[i]);
975 free(array_names);
976}
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 806 of file sddsmxref.c.

806 {
807 char *data1, *data2;
808 long index1, index2, size, type1, type2, i;
809 char s[SDDS_MAXLINE];
810 index2 = 0;
811 for (i = 0; i < equate_columns; i++) {
812 if ((index1 = SDDS_GetColumnIndex(SDDS1, equate_column[i][0])) < 0 ||
813 (index2 = SDDS_GetColumnIndex(SDDS2, equate_column[i][1])) < 0) {
814 SDDS_SetError("Problem equating rows");
815 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
816 }
817 type1 = SDDS1->layout.column_definition[index1].type;
818 type2 = SDDS2->layout.column_definition[index2].type;
819 if (equate_tolerance[i] == 0) {
820 if (type1 != type2) {
821 sprintf(s, "Problem equating rows--types don't match for column '%s'='%s'", equate_column[i][0], equate_column[i][1]);
822 SDDS_SetError(s);
823 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
824 }
825 size = SDDS_GetTypeSize(type1);
826 data1 = (char *)SDDS1->data[index1] + size * row1;
827 data2 = (char *)SDDS2->data[index2] + size * row2;
828 if (memcmp(data1, data2, size) != 0)
829 return 0;
830 } else {
831 double d1, d2;
832 SDDS_CastValue(SDDS1->data, index1, type1, SDDS_DOUBLE, &d1);
833 SDDS_CastValue(SDDS2->data, index2, type2, SDDS_DOUBLE, &d2);
834 if (fabs(d1 - d2) > equate_tolerance[i])
835 return 0;
836 }
837 }
838 return 1;
839}
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

Variable Documentation

◆ mode_name

char* mode_name[MODES]
static
Initial value:
= {
"column",
"parameter",
"array",
}

Definition at line 117 of file sddsmxref.c.

117 {
118 "column",
119 "parameter",
120 "array",
121};

◆ option

char* option[N_OPTIONS]
Initial value:
= {
"take",
"leave",
"match",
"equate",
"transfer",
"reuse",
"ifnot",
"nowarnings",
"ifis",
"pipe",
"fillin",
"rename",
"editnames",
"majorOrder",
}

Definition at line 65 of file sddsmxref.c.

65 {
66 "take",
67 "leave",
68 "match",
69 "equate",
70 "transfer",
71 "reuse",
72 "ifnot",
73 "nowarnings",
74 "ifis",
75 "pipe",
76 "fillin",
77 "rename",
78 "editnames",
79 "majorOrder",
80};

◆ transfer_type

char* transfer_type[TRANSFER_TYPES]
static
Initial value:
= {
"parameter", "array"}

Definition at line 85 of file sddsmxref.c.

85 {
86 "parameter", "array"};

◆ USAGE

char* USAGE
Initial value:
= "Usage:\n"
" sddsmxref [<input1>] <input2> [<output>] [options]\n\n"
"Options:\n"
" -pipe[=input][,output] Use standard input and/or output instead of files.\n"
" -ifis={column|parameter|array},<name>[,...] Specify names that must exist in <input1>.\n"
" -ifnot={column|parameter|array},<name>[,...] Specify names that must not exist in <input1>.\n"
" -transfer={parameter|array},<name>[,...] Specify parameters or arrays to transfer from <input2>.\n"
" -take=<column-name>[,...] Specify columns to take from <input2>.\n"
" -leave=<column-name>[,...] Specify columns not to take from <input2>.\n"
" Overrides -take if both specify the same column.\n"
" Use -leave=* to exclude all columns.\n"
" -fillIn Fill in NULL and 0 values for unmatched rows.\n"
" -match=<column-name>[=<column-name>][,...] Specify columns to match between <input1> and <input2>.\n"
" -equate=<column-name>[=<column-name>][,<tol>][,...] Specify columns to equate with an optional tolerance.\n"
" -reuse[=[rows][,page]] Allow reuse of rows from <input2>.\n"
" -rename={column|parameter|array},<old>=<new>[,...] Rename entities in the output data set.\n"
" -editnames={column|parameter|array},<wild>,<edit> Edit names of entities matching the wildcard.\n"
" -majorOrder=row|column Specify output major order.\n\n"
"Program by Michael Borland. (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")\n"

Definition at line 141 of file sddsmxref.c.