90char *option[N_OPTIONS] = {
107#define PARAMETER_TRANSFER 0
108#define ARRAY_TRANSFER 1
109#define TRANSFER_TYPES 2
110static char *transfer_type[TRANSFER_TYPES] = {
111 "parameter",
"array"};
122 char **new_parameter;
125 char **orig_parameter;
139#define PARAMETER_MODE 1
142static char *mode_name[MODES] = {
153char **process_editnames(
char **orig_name,
long **orig_flags,
long orig_names,
EDIT_NAME_REQUEST *edit_request,
long edit_requests);
155 REFDATA new_data,
long columns,
char *input2);
158void free_refdata(
REFDATA *refData,
long rename);
161typedef char *STRING_PAIR[2];
163long rows_equate(
SDDS_DATASET *SDDS1, int64_t row1,
SDDS_DATASET *SDDS2, int64_t row2,
long equate_columns, STRING_PAIR *equate_column,
164 double *equate_tolerance);
166char *USAGE =
"Usage:\n"
167 " sddsmxref [<input1>] <input2> [<output>] [options]\n"
168 " [-pipe[=input][,output]]\n"
169 " [-ifis={column|parameter|array},<name>[,...]]\n"
170 " [-ifnot={column|parameter|array},<name>[,...]]\n"
171 " [-transfer={parameter|array},<name>[,...]]\n"
172 " [-take=<column-name>[,...]]\n"
173 " [-leave=<column-name>[,...]]\n"
175 " [-match=<column-name>[=<column-name>][,...]]\n"
176 " [-equate=<column-name>[=<column-name>][,<tol>][,...]]\n"
177 " [-reuse[=[rows][,page]]]\n"
178 " [-rename={column|parameter|array},<old>=<new>[,...]]\n"
179 " [-editnames={column|parameter|array},<wild>,<edit>]\n"
180 " [-majorOrder=row|column]\n"
182 " -pipe[=input][,output] Use standard input and/or output instead of files.\n"
183 " -ifis={column|parameter|array},<name>[,...] Specify names that must exist in <input1>.\n"
184 " -ifnot={column|parameter|array},<name>[,...] Specify names that must not exist in <input1>.\n"
185 " -transfer={parameter|array},<name>[,...] Specify parameters or arrays to transfer from <input2>.\n"
186 " -take=<column-name>[,...] Specify columns to take from <input2>.\n"
187 " -leave=<column-name>[,...] Specify columns not to take from <input2>.\n"
188 " Overrides -take if both specify the same column.\n"
189 " Use -leave=* to exclude all columns.\n"
190 " -fillIn Fill in NULL and 0 values for unmatched rows.\n"
191 " -match=<column-name>[=<column-name>][,...] Specify columns to match between <input1> and <input2>.\n"
192 " -equate=<column-name>[=<column-name>][,<tol>][,...] Specify columns to equate with an optional tolerance.\n"
193 " -reuse[=[rows][,page]] Allow reuse of rows from <input2>.\n"
194 " -rename={column|parameter|array},<old>=<new>[,...] Rename entities in the output data set.\n"
195 " -editnames={column|parameter|array},<wild>,<edit> Edit names of entities matching the wildcard.\n"
196 " -majorOrder=row|column Specify output major order.\n\n"
197 "Program by Michael Borland. (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")\n";
199int main(
int argc,
char **argv) {
201 long i_arg, reuse, reusePage;
202 int64_t i, j, k, rows1, rows2, n;
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;
215 long warnings, fillIn;
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;
224 argc =
scanargs(&s_arg, argc, argv);
226 fprintf(stderr,
"%s\n", USAGE);
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;
238 ifnot_item.items = ifis_item.items = 0;
242 leave_all_columns = 0;
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;
251 for (i_arg = 1; i_arg < argc; i_arg++) {
252 if (s_arg[i_arg].arg_type == OPTION) {
254 switch (
match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
255 case SET_MAJOR_ORDER:
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;
265 case SET_LEAVE_COLUMNS:
266 if (s_arg[i_arg].n_items < 2) {
267 fprintf(stderr,
"%s\n", USAGE);
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;
275 case SET_TAKE_COLUMNS:
276 if (s_arg[i_arg].n_items < 2) {
277 fprintf(stderr,
"%s\n", USAGE);
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;
285 case SET_MATCH_COLUMNS:
286 if (s_arg[i_arg].n_items < 2) {
287 fprintf(stderr,
"%s\n", USAGE);
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],
'=')))
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;
299 match_columns += s_arg[i_arg].n_items - 1;
301 case SET_EQUATE_COLUMNS:
302 if (s_arg[i_arg].n_items < 2)
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++) {
308 if ((ptr = strchr(s_arg[i_arg].list[i],
'=')))
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;
317 sscanf(s_arg[i_arg].list[i],
"%le", &equate_tolerance[equate_columns - 1]);
322 if (s_arg[i_arg].n_items < 3)
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];
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];
342 transfers += s_arg[i_arg].n_items - 2;
345 if (s_arg[i_arg].n_items == 1)
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)) {
365 if (s_arg[i_arg].n_items < 3)
367 add_ifitem(&ifnot_item, s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1);
373 if (s_arg[i_arg].n_items < 3)
375 add_ifitem(&ifis_item, s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1);
378 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
385 if (s_arg[i_arg].n_items < 3)
387 switch (
match_string(s_arg[i_arg].list[1], mode_name, MODES, 0)) {
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],
'=')))
396 rename_data.orig_column[k + i - 2] = s_arg[i_arg].list[i];
397 rename_data.new_column[k + i - 2] = ptr;
399 rename_data.columns += s_arg[i_arg].n_items - 2;
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],
'=')))
409 rename_data.orig_parameter[k + i - 2] = s_arg[i_arg].list[i];
410 rename_data.new_parameter[k + i - 2] = ptr;
412 rename_data.parameters += s_arg[i_arg].n_items - 2;
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],
'=')))
422 rename_data.orig_array[k + i - 2] = s_arg[i_arg].list[i];
423 rename_data.new_array[k + i - 2] = ptr;
425 rename_data.arrays += s_arg[i_arg].n_items - 2;
428 SDDS_Bomb(
"invalid -rename syntax: specify column, parameter, or array keyword");
433 if (s_arg[i_arg].n_items != 4)
435 switch (
match_string(s_arg[i_arg].list[1], mode_name, MODES, 0)) {
437 edit_column_request =
trealloc(edit_column_request,
sizeof(*edit_column_request) * (edit_column_requests + 1));
440 edit_column_requests++;
443 edit_parameter_request =
trealloc(edit_parameter_request,
sizeof(*edit_parameter_request) * (edit_parameter_requests + 1));
446 edit_parameter_requests++;
449 edit_array_request =
trealloc(edit_array_request,
sizeof(*edit_array_request) * (edit_array_requests + 1));
452 edit_array_requests++;
455 SDDS_Bomb(
"invalid -editnames syntax: specify column, parameter, or array keyword");
460 fprintf(stderr,
"Error: Unknown switch: %s\n%s\n", s_arg[i_arg].list[0], USAGE);
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];
472 fprintf(stderr,
"Error: Too many filenames specified.\n%s\n", USAGE);
478 if (pipeFlags & USE_STDIN && input1) {
480 fprintf(stderr,
"Error: Too many filenames specified with -pipe option.\n%s\n", USAGE);
481 SDDS_Bomb(
"too many filenames (sddsmxref)");
487 processFilenames(
"sddsmxref", &input1, &output, pipeFlags, !warnings, &tmpfile_used);
489 SDDS_Bomb(
"Second input file not specified");
497 if (!check_ifitems(&SDDS_1, &ifnot_item, 0, warnings) || !check_ifitems(&SDDS_1, &ifis_item, 1, warnings))
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))
513 for (i = 0; i < take_columns; i++) {
515 sprintf(s,
"Error: Column '%s' not found in file '%s'", take_column[i], input2);
524 leave_all_columns = 0;
525 if (leave_columns == 1 && strcmp(leave_column[0],
"*") == 0)
526 leave_all_columns = 1;
530 for (i = 0; i < leave_columns; i++) {
543 SDDS_SetError(
"Error: No columns selected to take from input file.");
548 for (i = 0; i < match_columns; i++) {
551 sprintf(s,
"Error: Column '%s' not found or not of string type in file '%s'.", match_column[i][0], input1 ? input1 :
"stdin");
557 sprintf(s,
"Error: Column '%s' not found or not of string type in file '%s'.", match_column[i][1], input2);
562 for (i = 0; i < equate_columns; i++) {
565 sprintf(s,
"Error: Column '%s' not found or not of numeric type in file '%s'.", equate_column[i][0], input1 ? input1 :
"stdin");
571 sprintf(s,
"Error: Column '%s' not found or not of numeric type in file '%s'.", equate_column[i][1], input2);
579 take_RefData.columns = 0;
580 leave_all_columns = 1;
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;
590 if (output && (pipeFlags & USE_STDOUT))
591 SDDS_Bomb(
"Too many filenames specified with -pipe option.");
592 if (!output && !(pipeFlags & USE_STDOUT)) {
594 fprintf(stderr,
"Warning: Existing file '%s' will be replaced.\n", input1 ? input1 :
"stdin");
602 if (columnMajorOrder != -1)
603 SDDS_output.layout.data_mode.column_major = columnMajorOrder;
605 SDDS_output.layout.data_mode.column_major = SDDS_1.layout.data_mode.column_major;
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);
611 for (i = 0; i < take_RefData.columns; i++) {
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];
623 take_RefData.columns -= 1;
625 if (take_RefData.columns == 0)
632 if (!(output_column = (
char **)
SDDS_GetColumnNames(&SDDS_output, &output_columns)) || output_columns == 0) {
633 SDDS_SetError(
"Error: Problem getting output column names.");
637 for (i = 0; i < take_RefData.parameters; i++) {
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;
645 if (take_RefData.parameters == 0)
653 for (i = 0; i < take_RefData.arrays; i++) {
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;
661 if (take_RefData.arrays == 0)
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]);
681 fprintf(stderr,
"Warning: <input2> ends before <input1>.\n");
689 if (take_RefData.columns &&
695 row_used =
SDDS_Realloc(row_used,
sizeof(*row_used) * rows2);
707 if (!CopyParametersFromSecondInput(&SDDS_output, &SDDS_2, take_RefData)) {
708 SDDS_SetError(
"Error: Problem copying parameters from second input file.");
711 if (!CopyArraysFromSecondInput(&SDDS_output, &SDDS_2, take_RefData)) {
712 SDDS_SetError(
"Error: Problem copying arrays from second input file.");
717 SDDS_SetError(
"Error: Problem copying parameters or arrays from first input file.");
720 for (j = 0; j < rows1; j++) {
722 sprintf(s,
"Error: Problem copying row %" PRId64
" of first data set.", j);
726 SDDS_output.row_flag[j] = 1;
727 if (!match_columns && !equate_columns && !leave_all_columns) {
730 fprintf(stderr,
"Warning: No match for row %" PRId64
" (value %s)\n", j, match_value);
731 SDDS_output.row_flag[j] = 0;
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");
740 if (!leave_all_columns) {
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");
749 sprintf(s,
"Error: Problem setting rows of interest for column '%s'.", match_column[i][1]);
757 fprintf(stderr,
"Warning: No match for row %" PRId64
"\n", j);
758 SDDS_output.row_flag[j] = 0;
762 for (k = 0; k < rows2; k++) {
763 if (!SDDS_2.row_flag[k])
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");
777 fprintf(stderr,
"Warning: No match for row %" PRId64
"\n", j);
779 SDDS_output.row_flag[j] = 0;
785 SDDS_SetError(
"Error: Problem writing data to output file.");
800 free_refdata(&take_RefData, 0);
801 free_refdata(&rename_data, 1);
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);
814void free_refdata(
REFDATA *refData,
long rename) {
817 for (i = 0; i < refData->columns; i++) {
818 free(refData->orig_column[i]);
819 free(refData->new_column[i]);
821 for (i = 0; i < refData->parameters; i++) {
822 free(refData->orig_parameter[i]);
823 free(refData->new_parameter[i]);
825 for (i = 0; i < refData->arrays; i++) {
826 free(refData->orig_array[i]);
827 free(refData->new_array[i]);
830 if (refData->columns) {
831 free(refData->orig_column);
832 free(refData->new_column);
834 if (refData->parameters) {
835 free(refData->orig_parameter);
836 free(refData->new_parameter);
838 if (refData->arrays) {
839 free(refData->orig_array);
840 free(refData->new_array);
844long rows_equate(
SDDS_DATASET *SDDS1, int64_t row1,
SDDS_DATASET *SDDS2, int64_t row2,
long equate_columns, STRING_PAIR *equate_column,
double *equate_tolerance) {
846 long index1, index2, size, type1, type2, i;
847 char s[SDDS_MAXLINE];
849 for (i = 0; i < equate_columns; i++) {
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]);
864 data1 = (
char *)SDDS1->data[index1] + size * row1;
865 data2 = (
char *)SDDS2->data[index2] + size * row2;
866 if (memcmp(data1, data2, size) != 0)
872 if (fabs(d1 - d2) > equate_tolerance[i])
881 int32_t (*matchRoutine)(
SDDS_DATASET *SDDS_dataset,
char ***nameReturn, int32_t matchMode, int32_t typeMode, ...);
886 case PARAMETER_TRANSFER:
893 SDDS_Bomb(
"Invalid transfer type--this shouldn't happen");
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) {
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;
918 columns = parameters = arrays = 0;
919 column_names = parameter_names = array_names = new_names = NULL;
920 orig_columnflags = orig_parameterflags = orig_arrayflags = NULL;
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);
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]);
934 SDDS_CopyString(&take_RefData->new_column[i], take_RefData->orig_column[i]);
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]);
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]);
945 SDDS_CopyString(&take_RefData->new_array[i], take_RefData->orig_array[i]);
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)
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)
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)
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]);
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]);
1016char **process_editnames(
char **orig_name,
long **orig_flags,
long orig_names,
EDIT_NAME_REQUEST *edit_request,
long edit_requests) {
1018 char **new_name, s[1024];
1019 char *ptr, **editstr;
1020 char edit_buffer[1024];
1024 *orig_flags =
tmalloc(
sizeof(**orig_flags) * orig_names);
1025 new_name =
tmalloc(
sizeof(*new_name) * orig_names);
1027 editstr = (
char **)malloc(
sizeof(*editstr) * edit_requests);
1028 ptr = malloc(
sizeof(
char) * 256);
1029 sprintf(s,
"%" PRId32, 2);
1031 for (i = 0; i < edit_requests; i++) {
1033 if (strstr(editstr[i],
"%%ld"))
1035 else if (strstr(editstr[i],
"%ld"))
1044 for (j = 0; j < orig_names; j++) {
1045 (*orig_flags)[j] = 0;
1047 for (i = 0; i < edit_requests; i++) {
1050 edit_request[i].match_string = ptr;
1052 strcpy(edit_buffer, new_name[j]);
1057 (*orig_flags)[j] = 1;
1062 for (i = 0; i < edit_requests; i++)
1072 if (new_data.parameters == 0)
1074 for (i = 0; i < new_data.parameters; i++) {
1080 fprintf(stderr,
"Warning: Parameter '%s' not defined in output.\n", new_data.new_parameter[i]);
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]);
1096 if (new_data.arrays == 0)
1098 for (i = 0; i < new_data.arrays; i++) {
1102 sprintf(s,
"Warning: Array '%s' not defined in output.\n", new_data.new_array[i]);
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.");
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.");
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];
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)) {
1130long CopyRowToNewColumn(
SDDS_DATASET *target, int64_t target_row,
SDDS_DATASET *source, int64_t source_row,
REFDATA new_data,
long columns,
char *input2) {
1131 long i, j, k, type, size;
1137 for (i = 0; i < columns; i++) {
1139 sprintf(s,
"Error: Column '%s' not found in file '%s'.\n", new_data.orig_column[i], input2);
1141 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1145 sprintf(s,
"Error: Column '%s' not defined in output.\n", new_data.new_column[i]);
1147 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1152 if (!
SDDS_CopyString(((
char ***)target->data)[k] + target_row, ((
char ***)source->data)[j][source_row])) {
1158 memcpy((
char *)target->data[k] + size * target_row, (
char *)source->data[j] + size * source_row, size);
1166 if (edit_requests) {
1167 for (i = 0; i < edit_requests; i++) {
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_CopyParameters(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
int32_t SDDS_InitializeCopy(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, char *filename, char *filemode)
int32_t SDDS_CopyRowDirect(SDDS_DATASET *SDDS_target, int64_t target_row, SDDS_DATASET *SDDS_source, int64_t source_row)
int32_t SDDS_CopyArrays(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
int32_t SDDS_type_size[SDDS_NUM_TYPES]
Array of sizes for each supported data type.
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
int32_t SDDS_ClearPage(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_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.
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
int32_t SDDS_ZeroMemory(void *mem, int64_t n_bytes)
Sets a block of memory to zero.
int32_t SDDS_GetArrayIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named array in the SDDS dataset.
char ** SDDS_GetParameterNames(SDDS_DATASET *SDDS_dataset, int32_t *number)
Retrieves the names of all parameters in the SDDS dataset.
int32_t SDDS_GetParameterIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named parameter in the SDDS dataset.
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
int32_t SDDS_MatchParameters(SDDS_DATASET *SDDS_dataset, char ***nameReturn, int32_t matchMode, int32_t typeMode,...)
Matches and retrieves parameter names from an SDDS dataset based on specified criteria.
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_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_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
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.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
int32_t SDDS_GetTypeSize(int32_t type)
Retrieves the size in bytes of a specified SDDS data type.
int32_t SDDS_GetColumnType(SDDS_DATASET *SDDS_dataset, int32_t index)
Retrieves the data type of a column in the SDDS dataset by its index.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
char ** SDDS_GetArrayNames(SDDS_DATASET *SDDS_dataset, int32_t *number)
Retrieves the names of all arrays in the SDDS dataset.
int32_t SDDS_CopyString(char **target, const char *source)
Copies a source string to a target string with memory allocation.
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
int32_t SDDS_MatchArrays(SDDS_DATASET *SDDS_dataset, char ***nameReturn, int32_t matchMode, int32_t typeMode,...)
Matches and retrieves array names from an SDDS dataset based on specified criteria.
Header file for routines used by SDDS command-line applications.
long edit_string(char *text, char *edit)
Edits the provided text based on the specified edit commands.
#define SDDS_STRING
Identifier for the string data type.
#define SDDS_DOUBLE
Identifier for the double data type.
#define SDDS_NUMERIC_TYPE(type)
Checks if the given type identifier corresponds to any numeric type.
void * trealloc(void *old_ptr, uint64_t size_of_block)
Reallocates a memory block to a new size.
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
char * cp_str(char **s, char *t)
Copies a string, allocating memory for storage.
long tokenIsNumber(char *token)
Checks if the given token represents a valid number.
char * delete_chars(char *s, char *t)
Removes all occurrences of characters found in string t from string s.
long match_string(char *string, char **option, long n_options, long mode)
Matches a given string against an array of option strings based on specified modes.
int replace_string(char *t, char *s, char *orig, char *repl)
Replace all occurrences of one string with another string.
long replaceFileAndBackUp(char *file, char *replacement)
Replaces a file with a replacement file and creates a backup of the original.
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
long processPipeOption(char **item, long items, unsigned long *flags)
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
void free_scanargs(SCANNED_ARG **scanned, int argc)
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.
int has_wildcards(char *template)
Check if a template string contains any wildcard characters.
char * expand_ranges(char *template)
Expand range specifiers in a wildcard template into explicit character lists.
int wild_match(char *string, char *template)
Determine whether one string is a wildcard match for another.