98 {
100 long i, j, i_arg, reuse, reusePage;
101 int64_t rows1, rows2, i1, i2;
102 SCANNED_ARG *s_arg;
103 char s[200], *ptr;
104 char **match_column, **equate_column;
105 long match_columns, equate_columns;
106 char *input1, *input2, *output;
107 long tmpfile_used, retval1, retval2;
108 long warnings, invert;
109 unsigned long pipeFlags, majorOrderFlag;
110 KEYED_EQUIVALENT **keyGroup = NULL;
111 long keyGroups = 0;
112 short columnMajorOrder = -1;
113
115 argc =
scanargs(&s_arg, argc, argv);
116 if (argc < 3)
118
119 input1 = input2 = output = NULL;
120 match_column = equate_column = NULL;
121 match_columns = equate_columns = reuse = reusePage = 0;
122 tmpfile_used = invert = 0;
123 warnings = 1;
124 pipeFlags = 0;
125
126 for (i_arg = 1; i_arg < argc; i_arg++) {
127 if (s_arg[i_arg].arg_type == OPTION) {
129 switch (
match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
130 case SET_MAJOR_ORDER:
131 majorOrderFlag = 0;
132 s_arg[i_arg].n_items--;
133 if (s_arg[i_arg].n_items > 0 &&
134 (!
scanItemList(&majorOrderFlag, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
135 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
136 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
137 SDDS_Bomb(
"invalid -majorOrder syntax/values");
138 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
139 columnMajorOrder = 1;
140 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
141 columnMajorOrder = 0;
142 break;
143 case SET_MATCH_COLUMN:
144 if (s_arg[i_arg].n_items != 2)
146 if (match_columns != 0)
147 SDDS_Bomb(
"only one -match option may be given");
148 match_column =
tmalloc(
sizeof(*match_column) * 2);
149 if ((ptr = strchr(s_arg[i_arg].list[1], '=')))
150 *ptr++ = 0;
151 else
152 ptr = s_arg[i_arg].list[1];
153 match_column[0] = s_arg[i_arg].list[1];
154 match_column[1] = ptr;
155 match_columns = 1;
156 break;
157 case SET_EQUATE_COLUMN:
158 if (s_arg[i_arg].n_items != 2)
160 if (equate_columns != 0)
161 SDDS_Bomb(
"only one -equate option may be given");
162 equate_column =
tmalloc(
sizeof(*equate_column) * 2);
163 if ((ptr = strchr(s_arg[i_arg].list[1], '=')))
164 *ptr++ = 0;
165 else
166 ptr = s_arg[i_arg].list[1];
167 equate_column[0] = s_arg[i_arg].list[1];
168 equate_column[1] = ptr;
169 equate_columns = 1;
170 break;
171 case SET_REUSE:
172 if (s_arg[i_arg].n_items == 1)
173 reuse = 1;
174 else {
175 char *reuseOptions[2] = {"rows", "page"};
176 for (i = 1; i < s_arg[i_arg].n_items; i++) {
177 switch (
match_string(s_arg[i_arg].list[i], reuseOptions, 2, 0)) {
178 case 0:
179 reuse = 1;
180 break;
181 case 1:
182 reusePage = 1;
183 break;
184 default:
186 break;
187 }
188 }
189 }
190 break;
191 case SET_INVERT:
192 invert = 1;
193 break;
194 case SET_NOWARNINGS:
195 warnings = 0;
196 break;
197 case SET_PIPE:
198 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
200 break;
201 default:
202 fprintf(stderr, "error: unknown switch: %s\n", s_arg[i_arg].list[0]);
204 break;
205 }
206 } else {
207 if (input1 == NULL)
208 input1 = s_arg[i_arg].list[0];
209 else if (input2 == NULL)
210 input2 = s_arg[i_arg].list[0];
211 else if (output == NULL)
212 output = s_arg[i_arg].list[0];
213 else
215 }
216 }
217
218 if (pipeFlags & USE_STDIN && input1) {
219 if (output)
220 SDDS_Bomb(
"too many filenames (sddsxref)");
221 output = input2;
222 input2 = input1;
223 input1 = NULL;
224 }
225 processFilenames(
"sddsselect", &input1, &output, pipeFlags, !warnings, &tmpfile_used);
226 if (!input2)
227 SDDS_Bomb(
"second input file not specified (sddsxref)");
228
229 if (equate_columns && match_columns)
230 SDDS_Bomb(
"only one of -equate or -match may be given");
231 if (!equate_columns && !match_columns)
232 SDDS_Bomb(
"one of -equate or -match must be given");
233
236 exit(EXIT_FAILURE);
237 }
240 exit(EXIT_FAILURE);
241 }
242
243 if (match_columns) {
246 sprintf(s, "error: column %s not found or not string type in file %s", match_column[0], input1 ? input1 : "stdin");
249 }
252 sprintf(s, "error: column %s not found or not string type in file %s", match_column[1], input2);
255 }
256 }
257 if (equate_columns) {
260 sprintf(s, "error: column %s not found or not numeric type in file %s", equate_column[0], input1 ? input1 : "stdin");
263 }
266 sprintf(s, "error: column %s not found or not numeric type in file %s", equate_column[1], input2);
269 }
270 }
271
272 if (output && pipeFlags & USE_STDOUT)
273 SDDS_Bomb(
"too many filenames with -pipe option");
274 if (!output && !(pipeFlags & USE_STDOUT)) {
275 if (warnings)
276 fprintf(stderr, "warning: existing file %s will be replaced (sddsselect)\n", input1 ? input1 : "stdin");
277 tmpfile_used = 1;
279 }
282 exit(EXIT_FAILURE);
283 }
284 if (columnMajorOrder != -1)
285 SDDS_output.layout.data_mode.column_major = columnMajorOrder;
286 else
287 SDDS_output.layout.data_mode.column_major = SDDS_1.layout.data_mode.column_major;
290
292 if (!reusePage) {
294 if (warnings)
295 fprintf(stderr, "warning: <input2> ends before <input1>\n");
296 if (invert) {
297
301 continue;
302 } else
303
304 break;
305 }
306 } else {
310 }
313
317 }
320 SDDS_SetError(
"Problem copying parameter or array data from second input file");
322 }
325 SDDS_SetError(
"Problem copying parameter or array data from first input file");
327 }
328 if (rows1) {
329 if (match_columns) {
330 char **string1, **string2;
331 long matched;
332 string2 = NULL;
334 fprintf(stderr, "Error: problem getting column %s from file %s\n", match_column[0], input1 ? input1 : "stdin");
336 }
337 if (rows2 && !(string2 =
SDDS_GetColumn(&SDDS_2, match_column[1]))) {
338 fprintf(stderr, "Error: problem getting column %s from file %s\n", match_column[1], input2);
340 }
341 if (rows2)
343 for (i1 = 0; i1 < rows1; i1++) {
345 sprintf(s, "Problem copying row %" PRId64 " of first data set", i1);
348 }
349 matched = 0;
351 matched = 1;
352 }
353 if ((!matched && !invert) || (matched && invert)) {
356 }
357 }
358 if (string1) {
359 for (i = 0; i < rows1; i++)
360 free(string1[i]);
361 free(string1);
362 string1 = NULL;
363 }
364 if (string2) {
365 for (i = 0; i < rows2; i++)
366 free(string2[i]);
367 free(string2);
368 string2 = NULL;
369 }
370 for (i = 0; i < keyGroups; i++) {
371 if (keyGroup[i]) {
372 if (keyGroup[i]->equivalent)
373 free(keyGroup[i]->equivalent);
374 free(keyGroup[i]);
375 keyGroup[i] = NULL;
376 }
377 }
378 if (keyGroups) {
379 free(keyGroup);
380 keyGroup = NULL;
381 keyGroups = 0;
382 }
383 } else if (equate_columns) {
384 double *value1, *value2;
385 long equated;
386 value2 = NULL;
388 fprintf(stderr, "Error: problem getting column %s from file %s\n", equate_column[0], input1 ? input1 : "stdin");
390 }
392 fprintf(stderr, "Error: problem getting column %s from file %s\n", equate_column[1], input2);
394 }
395 if (rows2)
397 for (i1 = 0; i1 < rows1; i1++) {
399 sprintf(s, "Problem copying row %" PRId64 " of first data set", i1);
402 }
403 equated = 0;
404 if (rows2 &&
406 equated = 1;
407 }
408 if ((!equated && !invert) || (equated && invert)) {
411 }
412 }
413 if (value1)
414 free(value1);
415 value1 = NULL;
416 if (rows2 && value2)
417 free(value2);
418 value2 = NULL;
419 for (i = 0; i < keyGroups; i++) {
420 if (keyGroup[i]) {
421 if (keyGroup[i]->equivalent)
422 free(keyGroup[i]->equivalent);
423 free(keyGroup[i]);
424 keyGroup[i] = NULL;
425 }
426 }
427 if (keyGroups) {
428 free(keyGroup);
429 keyGroup = NULL;
430 keyGroups = 0;
431 }
432 }
433 }
437 }
438 }
439
442 exit(EXIT_FAILURE);
443 }
445 exit(EXIT_FAILURE);
447 if (match_columns)
448 free(match_column);
449 return EXIT_SUCCESS;
450}
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_CopyPage(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
int32_t SDDS_CopyArrays(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
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.
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
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.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
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.
#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 * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
char * cp_str(char **s, char *t)
Copies a string, allocating memory for storage.
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.
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.
KEYED_EQUIVALENT ** MakeSortedKeyGroups(long *keyGroups, long keyType, void *data, long points)
Create sorted key groups from data.
long FindMatchingKeyGroup(KEYED_EQUIVALENT **keyGroup, long keyGroups, long keyType, void *searchKeyData, long reuse)
Find a matching key group for a search key.
char * tmpname(char *s)
Supplies a unique temporary filename.