65char *option[N_OPTIONS] = {
82#define PARAMETER_TRANSFER 0
83#define ARRAY_TRANSFER 1
84#define TRANSFER_TYPES 2
85static char *transfer_type[TRANSFER_TYPES] = {
86 "parameter",
"array"};
100 char **orig_parameter;
114#define PARAMETER_MODE 1
117static char *mode_name[MODES] = {
128char **process_editnames(
char **orig_name,
long **orig_flags,
long orig_names,
EDIT_NAME_REQUEST *edit_request,
long edit_requests);
130 REFDATA new_data,
long columns,
char *input2);
133void free_refdata(
REFDATA *refData,
long rename);
136typedef char *STRING_PAIR[2];
138long rows_equate(
SDDS_DATASET *SDDS1, int64_t row1,
SDDS_DATASET *SDDS2, int64_t row2,
long equate_columns, STRING_PAIR *equate_column,
139 double *equate_tolerance);
141char *USAGE =
"Usage:\n"
142 " sddsmxref [<input1>] <input2> [<output>] [options]\n\n"
144 " -pipe[=input][,output] Use standard input and/or output instead of files.\n"
145 " -ifis={column|parameter|array},<name>[,...] Specify names that must exist in <input1>.\n"
146 " -ifnot={column|parameter|array},<name>[,...] Specify names that must not exist in <input1>.\n"
147 " -transfer={parameter|array},<name>[,...] Specify parameters or arrays to transfer from <input2>.\n"
148 " -take=<column-name>[,...] Specify columns to take from <input2>.\n"
149 " -leave=<column-name>[,...] Specify columns not to take from <input2>.\n"
150 " Overrides -take if both specify the same column.\n"
151 " Use -leave=* to exclude all columns.\n"
152 " -fillIn Fill in NULL and 0 values for unmatched rows.\n"
153 " -match=<column-name>[=<column-name>][,...] Specify columns to match between <input1> and <input2>.\n"
154 " -equate=<column-name>[=<column-name>][,<tol>][,...] Specify columns to equate with an optional tolerance.\n"
155 " -reuse[=[rows][,page]] Allow reuse of rows from <input2>.\n"
156 " -rename={column|parameter|array},<old>=<new>[,...] Rename entities in the output data set.\n"
157 " -editnames={column|parameter|array},<wild>,<edit> Edit names of entities matching the wildcard.\n"
158 " -majorOrder=row|column Specify output major order.\n\n"
159 "Program by Michael Borland. (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")\n";
161int main(
int argc,
char **argv) {
163 long i_arg, reuse, reusePage;
164 int64_t i, j, k, rows1, rows2, n;
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;
177 long warnings, fillIn;
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;
186 argc =
scanargs(&s_arg, argc, argv);
188 fprintf(stderr,
"%s\n", USAGE);
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;
200 ifnot_item.items = ifis_item.items = 0;
204 leave_all_columns = 0;
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;
213 for (i_arg = 1; i_arg < argc; i_arg++) {
214 if (s_arg[i_arg].arg_type == OPTION) {
216 switch (
match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
217 case SET_MAJOR_ORDER:
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;
227 case SET_LEAVE_COLUMNS:
228 if (s_arg[i_arg].n_items < 2) {
229 fprintf(stderr,
"%s\n", USAGE);
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;
237 case SET_TAKE_COLUMNS:
238 if (s_arg[i_arg].n_items < 2) {
239 fprintf(stderr,
"%s\n", USAGE);
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;
247 case SET_MATCH_COLUMNS:
248 if (s_arg[i_arg].n_items < 2) {
249 fprintf(stderr,
"%s\n", USAGE);
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],
'=')))
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;
261 match_columns += s_arg[i_arg].n_items - 1;
263 case SET_EQUATE_COLUMNS:
264 if (s_arg[i_arg].n_items < 2)
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++) {
270 if ((ptr = strchr(s_arg[i_arg].list[i],
'=')))
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;
279 sscanf(s_arg[i_arg].list[i],
"%le", &equate_tolerance[equate_columns - 1]);
284 if (s_arg[i_arg].n_items < 3)
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];
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];
304 transfers += s_arg[i_arg].n_items - 2;
307 if (s_arg[i_arg].n_items == 1)
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)) {
327 if (s_arg[i_arg].n_items < 3)
329 add_ifitem(&ifnot_item, s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1);
335 if (s_arg[i_arg].n_items < 3)
337 add_ifitem(&ifis_item, s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1);
340 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
347 if (s_arg[i_arg].n_items < 3)
349 switch (
match_string(s_arg[i_arg].list[1], mode_name, MODES, 0)) {
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],
'=')))
358 rename_data.orig_column[k + i - 2] = s_arg[i_arg].list[i];
359 rename_data.new_column[k + i - 2] = ptr;
361 rename_data.columns += s_arg[i_arg].n_items - 2;
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],
'=')))
371 rename_data.orig_parameter[k + i - 2] = s_arg[i_arg].list[i];
372 rename_data.new_parameter[k + i - 2] = ptr;
374 rename_data.parameters += s_arg[i_arg].n_items - 2;
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],
'=')))
384 rename_data.orig_array[k + i - 2] = s_arg[i_arg].list[i];
385 rename_data.new_array[k + i - 2] = ptr;
387 rename_data.arrays += s_arg[i_arg].n_items - 2;
390 SDDS_Bomb(
"invalid -rename syntax: specify column, parameter, or array keyword");
395 if (s_arg[i_arg].n_items != 4)
397 switch (
match_string(s_arg[i_arg].list[1], mode_name, MODES, 0)) {
399 edit_column_request =
trealloc(edit_column_request,
sizeof(*edit_column_request) * (edit_column_requests + 1));
401 SDDS_CopyString(&edit_column_request[edit_column_requests].edit_string, s_arg[i_arg].list[3]);
402 edit_column_requests++;
405 edit_parameter_request =
trealloc(edit_parameter_request,
sizeof(*edit_parameter_request) * (edit_parameter_requests + 1));
407 SDDS_CopyString(&edit_parameter_request[edit_parameter_requests].edit_string, s_arg[i_arg].list[3]);
408 edit_parameter_requests++;
411 edit_array_request =
trealloc(edit_array_request,
sizeof(*edit_array_request) * (edit_array_requests + 1));
413 SDDS_CopyString(&edit_array_request[edit_array_requests].edit_string, s_arg[i_arg].list[3]);
414 edit_array_requests++;
417 SDDS_Bomb(
"invalid -editnames syntax: specify column, parameter, or array keyword");
422 fprintf(stderr,
"Error: Unknown switch: %s\n%s\n", s_arg[i_arg].list[0], USAGE);
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];
434 fprintf(stderr,
"Error: Too many filenames specified.\n%s\n", USAGE);
440 if (pipeFlags & USE_STDIN && input1) {
442 fprintf(stderr,
"Error: Too many filenames specified with -pipe option.\n%s\n", USAGE);
443 SDDS_Bomb(
"too many filenames (sddsmxref)");
449 processFilenames(
"sddsmxref", &input1, &output, pipeFlags, !warnings, &tmpfile_used);
451 SDDS_Bomb(
"Second input file not specified");
459 if (!check_ifitems(&SDDS_1, &ifnot_item, 0, warnings) || !check_ifitems(&SDDS_1, &ifis_item, 1, warnings))
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))
475 for (i = 0; i < take_columns; i++) {
477 sprintf(s,
"Error: Column '%s' not found in file '%s'", take_column[i], input2);
486 leave_all_columns = 0;
487 if (leave_columns == 1 && strcmp(leave_column[0],
"*") == 0)
488 leave_all_columns = 1;
492 for (i = 0; i < leave_columns; i++) {
505 SDDS_SetError(
"Error: No columns selected to take from input file.");
510 for (i = 0; i < match_columns; i++) {
513 sprintf(s,
"Error: Column '%s' not found or not of string type in file '%s'.", match_column[i][0], input1 ? input1 :
"stdin");
519 sprintf(s,
"Error: Column '%s' not found or not of string type in file '%s'.", match_column[i][1], input2);
524 for (i = 0; i < equate_columns; i++) {
527 sprintf(s,
"Error: Column '%s' not found or not of numeric type in file '%s'.", equate_column[i][0], input1 ? input1 :
"stdin");
533 sprintf(s,
"Error: Column '%s' not found or not of numeric type in file '%s'.", equate_column[i][1], input2);
541 take_RefData.columns = 0;
542 leave_all_columns = 1;
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;
552 if (output && (pipeFlags & USE_STDOUT))
553 SDDS_Bomb(
"Too many filenames specified with -pipe option.");
554 if (!output && !(pipeFlags & USE_STDOUT)) {
556 fprintf(stderr,
"Warning: Existing file '%s' will be replaced.\n", input1 ? input1 :
"stdin");
564 if (columnMajorOrder != -1)
565 SDDS_output.layout.data_mode.column_major = columnMajorOrder;
567 SDDS_output.layout.data_mode.column_major = SDDS_1.layout.data_mode.column_major;
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);
573 for (i = 0; i < take_RefData.columns; i++) {
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];
585 take_RefData.columns -= 1;
587 if (take_RefData.columns == 0)
594 if (!(output_column = (
char **)
SDDS_GetColumnNames(&SDDS_output, &output_columns)) || output_columns == 0) {
595 SDDS_SetError(
"Error: Problem getting output column names.");
599 for (i = 0; i < take_RefData.parameters; i++) {
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;
607 if (take_RefData.parameters == 0)
615 for (i = 0; i < take_RefData.arrays; i++) {
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;
623 if (take_RefData.arrays == 0)
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]);
643 fprintf(stderr,
"Warning: <input2> ends before <input1>.\n");
651 if (take_RefData.columns &&
657 row_used =
SDDS_Realloc(row_used,
sizeof(*row_used) * rows2);
669 if (!CopyParametersFromSecondInput(&SDDS_output, &SDDS_2, take_RefData)) {
670 SDDS_SetError(
"Error: Problem copying parameters from second input file.");
673 if (!CopyArraysFromSecondInput(&SDDS_output, &SDDS_2, take_RefData)) {
674 SDDS_SetError(
"Error: Problem copying arrays from second input file.");
679 SDDS_SetError(
"Error: Problem copying parameters or arrays from first input file.");
682 for (j = 0; j < rows1; j++) {
684 sprintf(s,
"Error: Problem copying row %" PRId64
" of first data set.", j);
688 SDDS_output.row_flag[j] = 1;
689 if (!match_columns && !equate_columns && !leave_all_columns) {
692 fprintf(stderr,
"Warning: No match for row %" PRId64
" (value %s)\n", j, match_value);
693 SDDS_output.row_flag[j] = 0;
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");
702 if (!leave_all_columns) {
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");
711 sprintf(s,
"Error: Problem setting rows of interest for column '%s'.", match_column[i][1]);
719 fprintf(stderr,
"Warning: No match for row %" PRId64
"\n", j);
720 SDDS_output.row_flag[j] = 0;
724 for (k = 0; k < rows2; k++) {
725 if (!SDDS_2.row_flag[k])
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");
739 fprintf(stderr,
"Warning: No match for row %" PRId64
"\n", j);
741 SDDS_output.row_flag[j] = 0;
747 SDDS_SetError(
"Error: Problem writing data to output file.");
762 free_refdata(&take_RefData, 0);
763 free_refdata(&rename_data, 1);
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);
776void free_refdata(
REFDATA *refData,
long rename) {
779 for (i = 0; i < refData->columns; i++) {
780 free(refData->orig_column[i]);
781 free(refData->new_column[i]);
783 for (i = 0; i < refData->parameters; i++) {
784 free(refData->orig_parameter[i]);
785 free(refData->new_parameter[i]);
787 for (i = 0; i < refData->arrays; i++) {
788 free(refData->orig_array[i]);
789 free(refData->new_array[i]);
792 if (refData->columns) {
793 free(refData->orig_column);
794 free(refData->new_column);
796 if (refData->parameters) {
797 free(refData->orig_parameter);
798 free(refData->new_parameter);
800 if (refData->arrays) {
801 free(refData->orig_array);
802 free(refData->new_array);
806long rows_equate(
SDDS_DATASET *SDDS1, int64_t row1,
SDDS_DATASET *SDDS2, int64_t row2,
long equate_columns, STRING_PAIR *equate_column,
double *equate_tolerance) {
808 long index1, index2, size, type1, type2, i;
809 char s[SDDS_MAXLINE];
811 for (i = 0; i < equate_columns; i++) {
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]);
826 data1 = (
char *)SDDS1->data[index1] + size * row1;
827 data2 = (
char *)SDDS2->data[index2] + size * row2;
828 if (memcmp(data1, data2, size) != 0)
834 if (fabs(d1 - d2) > equate_tolerance[i])
843 int32_t (*matchRoutine)(
SDDS_DATASET *SDDS_dataset,
char ***nameReturn, int32_t matchMode, int32_t typeMode, ...);
848 case PARAMETER_TRANSFER:
855 SDDS_Bomb(
"Invalid transfer type--this shouldn't happen");
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) {
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;
880 columns = parameters = arrays = 0;
881 column_names = parameter_names = array_names = new_names = NULL;
882 orig_columnflags = orig_parameterflags = orig_arrayflags = NULL;
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);
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]);
896 SDDS_CopyString(&take_RefData->new_column[i], take_RefData->orig_column[i]);
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]);
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]);
907 SDDS_CopyString(&take_RefData->new_array[i], take_RefData->orig_array[i]);
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)
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)
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)
961 if (orig_columnflags)
962 free(orig_columnflags);
963 if (orig_parameterflags)
964 free(orig_parameterflags);
966 free(orig_arrayflags);
967 for (i = 0; i < columns; i++)
968 free(column_names[i]);
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]);
978char **process_editnames(
char **orig_name,
long **orig_flags,
long orig_names,
EDIT_NAME_REQUEST *edit_request,
long edit_requests) {
980 char **new_name, s[1024];
981 char *ptr, **editstr;
982 char edit_buffer[1024];
986 *orig_flags =
tmalloc(
sizeof(**orig_flags) * orig_names);
987 new_name =
tmalloc(
sizeof(*new_name) * orig_names);
989 editstr = (
char **)malloc(
sizeof(*editstr) * edit_requests);
990 ptr = malloc(
sizeof(
char) * 256);
991 sprintf(s,
"%" PRId32, 2);
993 for (i = 0; i < edit_requests; i++) {
995 if (strstr(editstr[i],
"%%ld"))
997 else if (strstr(editstr[i],
"%ld"))
1006 for (j = 0; j < orig_names; j++) {
1007 (*orig_flags)[j] = 0;
1009 for (i = 0; i < edit_requests; i++) {
1012 edit_request[i].match_string = ptr;
1014 strcpy(edit_buffer, new_name[j]);
1015 if (!edit_string(edit_buffer, editstr[i]))
1019 (*orig_flags)[j] = 1;
1024 for (i = 0; i < edit_requests; i++)
1034 if (new_data.parameters == 0)
1036 for (i = 0; i < new_data.parameters; i++) {
1042 fprintf(stderr,
"Warning: Parameter '%s' not defined in output.\n", new_data.new_parameter[i]);
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]);
1058 if (new_data.arrays == 0)
1060 for (i = 0; i < new_data.arrays; i++) {
1064 sprintf(s,
"Warning: Array '%s' not defined in output.\n", new_data.new_array[i]);
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.");
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.");
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];
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)) {
1092long CopyRowToNewColumn(
SDDS_DATASET *target, int64_t target_row,
SDDS_DATASET *source, int64_t source_row,
REFDATA new_data,
long columns,
char *input2) {
1093 long i, j, k, type, size;
1099 for (i = 0; i < columns; i++) {
1101 sprintf(s,
"Error: Column '%s' not found in file '%s'.\n", new_data.orig_column[i], input2);
1103 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1107 sprintf(s,
"Error: Column '%s' not defined in output.\n", new_data.new_column[i]);
1109 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1114 if (!
SDDS_CopyString(((
char ***)target->data)[k] + target_row, ((
char ***)source->data)[j][source_row])) {
1120 memcpy((
char *)target->data[k] + size * target_row, (
char *)source->data[j] + size * source_row, size);
1128 if (edit_requests) {
1129 for (i = 0; i < edit_requests; i++) {
1131 free(edit_request[i].edit_string);
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.
#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.