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

Detailed Description

Array Dereferencing Tool for SDDS Data Sets.

This program performs array dereferencing on SDDS (Self Describing Data Sets) data files. Users can create new columns or parameters by indexing into existing array or column data. It supports customizable behavior for handling out-of-bounds indices and allows specifying the order of data processing (row-major or column-major).

Usage

sddsderef [<inputfile>] [<outputfile>]
[-pipe=[input][,output]]
[-column=<newName>,{arraySource|columnSource}=<name>,<indexColumnName>[,...]]
[-parameter=<newName>,{arraySource|columnSource}=<name>,<indexParameterName>[,...]]
[-constant=<newName>,{arraySource|columnSource}=<name>,<indexValue>[,<indexValue>]]
[-outOfBounds=exit|delete]
[-majorOrder=row|column]

Options

Option Description
-pipe Use standard input and/or output instead of files.
-column Define a new column by dereferencing an existing array or column.
-parameter Define a new parameter by dereferencing an existing array or column.
-constant Define a new constant by dereferencing an existing array or column.
-outOfBounds Specify behavior for out-of-bounds indices: exit the program or delete the row.
-majorOrder Specify the major order for processing: row or column.
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Authors
M. Borland, R. Soliday, H. Shang

Definition in file sddsderef.c.

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

Go to the source code of this file.

Functions

long DereferenceColumnWithParameter (SDDS_DATASET *outSet, DEREF_REQUEST *deref, unsigned long outOfBounds)
 
long DereferenceColumnWithColumn (SDDS_DATASET *outSet, DEREF_REQUEST *deref, unsigned long outOfBounds)
 
long DereferenceArrayWithParameter (SDDS_DATASET *outSet, DEREF_REQUEST *deref, unsigned long outOfBounds)
 
long DereferenceArrayWithColumn (SDDS_DATASET *outSet, DEREF_REQUEST *deref, unsigned long outOfBounds)
 
long DoDereferencing (SDDS_DATASET *outSet, DEREF_REQUEST *deref, long derefs, unsigned long outOfBounds)
 
void setupOutputFile (SDDS_DATASET *outSet, char *output, SDDS_DATASET *inSet, char *input, DEREF_REQUEST *deref, long derefs, short columnMajorOrder)
 
void addDerefRequest (DEREF_REQUEST **deref, long *derefs, char **argv, long argc, long class)
 
int main (int argc, char **argv)
 

Function Documentation

◆ addDerefRequest()

void addDerefRequest ( DEREF_REQUEST ** deref,
long * derefs,
char ** argv,
long argc,
long class )

Definition at line 289 of file sddsderef.c.

289 {
290 long i, items;
291 unsigned long flags;
292#define ARRAY_SOURCE 0x1U
293#define COLUMN_SOURCE 0x2U
294 if (argc < 3) {
295 fprintf(stderr, "error (sddsderef): too few values for -%s\n", optionName[class]);
296 exit(EXIT_FAILURE);
297 }
298 if (!(*deref = SDDS_Realloc(*deref, sizeof(**deref) * (*derefs + 1))))
299 SDDS_Bomb("memory allocation failure (addDerefRequest)");
300
301 /* Store the first non-optional argument */
302 (*deref)[*derefs].targetClass = class;
303 (*deref)[*derefs].target = argv[0];
304 argv++;
305 argc--;
306
307 /* parse the second argument (key=value form) */
308 items = 1;
309 if (!scanItemList(&flags, argv, &items, 0, "arraySource", SDDS_STRING, &(*deref)[*derefs].source, 1, ARRAY_SOURCE, "columnSource", SDDS_STRING, &(*deref)[*derefs].source, 1, COLUMN_SOURCE, NULL) ||
310 !flags ||
311 flags == (ARRAY_SOURCE | COLUMN_SOURCE)) {
312 fprintf(stderr, "error (sddsderef): one of arraySource or columnSource must be given with -column or -parameter\n");
313 exit(EXIT_FAILURE);
314 }
315 if (flags & ARRAY_SOURCE)
316 (*deref)[*derefs].sourceClass = ARRAY_CLASS;
317 else {
318 (*deref)[*derefs].sourceClass = COLUMN_CLASS;
319 if (argc > 2) {
320 fprintf(stderr, "error (sddsderef): too many indices for column dereference\n");
321 exit(EXIT_FAILURE);
322 }
323 }
324
325 /* parse the remaining list of arguments (names of data elements) */
326 argv++;
327 argc--;
328 (*deref)[*derefs].indexElements = argc;
329 (*deref)[*derefs].indexElement = NULL;
330 (*deref)[*derefs].indexValue = NULL;
331 if (class == CONSTANT_CLASS) {
332 if (!((*deref)[*derefs].indexValue = (long *)malloc(sizeof(long) * argc))) {
333 SDDS_Bomb("memory allocation failure (addDerefRequest)");
334 }
335 for (i = 0; i < argc; i++) {
336 if (sscanf(argv[i], "%ld", (*deref)[*derefs].indexValue + i) != 1)
337 SDDS_Bomb("constant doesn't contain scannable integer");
338 }
339 } else {
340 if (!((*deref)[*derefs].indexElement = (char **)malloc(sizeof(*(*deref)[*derefs].indexElement) * argc)))
341 SDDS_Bomb("memory allocation failure (addDerefRequest)");
342 for (i = 0; i < argc; i++)
343 (*deref)[*derefs].indexElement[i] = argv[i];
344 }
345 *derefs += 1;
346}
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
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
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.

◆ DereferenceArrayWithColumn()

long DereferenceArrayWithColumn ( SDDS_DATASET * outSet,
DEREF_REQUEST * deref,
unsigned long outOfBounds )

Definition at line 485 of file sddsderef.c.

485 {
486 SDDS_ARRAY *array;
487 long i, offset, size, index;
488 int64_t row, rows;
489 int32_t **indexData;
490
491 if (!(rows = outSet->n_rows))
492 return 1;
493 if (!(array = SDDS_GetArray(outSet, deref->source, NULL))) {
494 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
495 return 0;
496 }
497 if (deref->indexElements != array->definition->dimensions) {
498 fprintf(stderr, "error: number of index elements (%ld) doesn't match number of array dimensions (%" PRId32 ") for array %s\n", deref->indexElements, array->definition->dimensions, deref->source);
499 return 0;
500 }
501 size = SDDS_GetTypeSize(array->definition->type);
502 offset = 0;
503
504 if (!(indexData = (int32_t **)malloc(sizeof(*indexData) * deref->indexElements)))
505 SDDS_Bomb("memory allocation failure while derefencing column data");
506 for (i = 0; i < deref->indexElements; i++)
507 if (!(indexData[i] = (int32_t *)SDDS_GetNumericColumn(outSet, deref->indexElement[i], SDDS_LONG))) {
508 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
509 return 0;
510 }
511 for (row = 0; row < rows; row++) {
512 for (i = offset = 0; i < deref->indexElements; i++) {
513 /* get index values from columns */
514 index = indexData[i][row];
515 if (index < 0 || index > array->dimension[i]) {
516 offset = -1;
517 break;
518 }
519 offset = index + offset * array->dimension[i];
520 }
521
522 if (offset < 0 || offset >= array->elements) {
523 if (outOfBounds & EXIT_OUTBOUNDS) {
524 char s[1024], t[1024];
525 sprintf(s, "array index out of bounds: array %s, length %" PRId32 ", offset %ld\n", deref->source, array->elements, offset);
526 for (i = 0; i < deref->indexElements; i++) {
527 sprintf(t, " %s=%" PRId32 " (dim=%" PRId32 ")", deref->indexElement[i], indexData[i][row], array->dimension[i]);
528 strcat(s, t);
529 }
530 SDDS_Bomb(s);
531 }
532 if (!SDDS_AssertRowFlags(outSet, SDDS_INDEX_LIMITS, row, row, 0)) {
533 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
534 return 0;
535 }
536 } else if (!SDDS_SetRowValues(outSet, SDDS_SET_BY_INDEX | SDDS_PASS_BY_REFERENCE, row, deref->targetIndex, (char *)array->data + offset * size, -1)) {
537 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
538 return 0;
539 }
540 }
541 for (i = 0; i < deref->indexElements; i++)
542 free(indexData[i]);
543 free(indexData);
544 SDDS_FreeArray(array);
545 return 1;
546}
int32_t SDDS_SetRowValues(SDDS_DATASET *SDDS_dataset, int32_t mode, int64_t row,...)
int32_t SDDS_AssertRowFlags(SDDS_DATASET *SDDS_dataset, uint32_t mode,...)
Sets acceptance flags for rows based on specified criteria.
void * SDDS_GetNumericColumn(SDDS_DATASET *SDDS_dataset, char *column_name, int32_t desiredType)
Retrieves the data of a specified numerical column as an array of a desired numerical type,...
SDDS_ARRAY * SDDS_GetArray(SDDS_DATASET *SDDS_dataset, char *array_name, SDDS_ARRAY *memory)
Retrieves an array from the current data table of an SDDS dataset.
void SDDS_FreeArray(SDDS_ARRAY *array)
Frees memory allocated for an SDDS array structure.
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_GetTypeSize(int32_t type)
Retrieves the size in bytes of a specified SDDS data type.
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61

◆ DereferenceArrayWithParameter()

long DereferenceArrayWithParameter ( SDDS_DATASET * outSet,
DEREF_REQUEST * deref,
unsigned long outOfBounds )

Definition at line 433 of file sddsderef.c.

433 {
434 SDDS_ARRAY *array;
435 long i, j, offset, size;
436 double value;
437 int32_t zeroValue = 0;
438 static char *blankString = "";
439 double data[4];
440
441 if (!(array = SDDS_GetArray(outSet, deref->source, NULL))) {
442 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
443 return 0;
444 }
445 if (deref->indexElements != array->definition->dimensions) {
446 fprintf(stderr, "error: number of index elements (%ld) doesn't match number of array dimensions (%" PRId32 ") for array %s\n", deref->indexElements, array->definition->dimensions, deref->source);
447 return 0;
448 }
449 size = SDDS_GetTypeSize(array->definition->type);
450 offset = 0;
451 for (i = 0, j = deref->indexElements - 1; i < deref->indexElements; i++, j--) {
452 if (deref->targetClass == CONSTANT_CLASS) {
453 value = deref->indexValue[i];
454 } else {
455 /* get index values from parameters */
456 if (!SDDS_GetParameterAsDouble(outSet, deref->indexElement[i], &value)) {
457 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
458 return 0;
459 }
460 }
461 offset = ((long)value) + offset * array->dimension[j];
462 }
463 if (offset < 0 || offset >= array->elements) {
464 if (outOfBounds & EXIT_OUTBOUNDS) {
465 char s[1024];
466 sprintf(s, "array index out of bounds: array %s, length %" PRId32 ", offset %ld\n %s=%ld", deref->source, array->elements, offset, deref->indexElement[0], offset);
467 SDDS_Bomb(s);
468 }
469 if (array->definition->type == SDDS_STRING)
470 memcpy((char *)data, (char *)&blankString, sizeof(blankString));
471 else
472 SDDS_CastValue((void *)&zeroValue, 0, SDDS_LONG, array->definition->type, (void *)data);
473 if (!SDDS_SetParameters(outSet, SDDS_SET_BY_INDEX | SDDS_PASS_BY_REFERENCE, deref->targetIndex, (void *)data, -1)) {
474 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
475 return 0;
476 }
477 } else if (!SDDS_SetParameters(outSet, SDDS_SET_BY_INDEX | SDDS_PASS_BY_REFERENCE, deref->targetIndex, (char *)array->data + offset * size, -1)) {
478 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
479 return 0;
480 }
481 SDDS_FreeArray(array);
482 return 1;
483}
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
double * SDDS_GetParameterAsDouble(SDDS_DATASET *SDDS_dataset, char *parameter_name, double *memory)
Retrieves the value of a specified parameter as a double from the current data table of an SDDS datas...
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.

◆ DereferenceColumnWithColumn()

long DereferenceColumnWithColumn ( SDDS_DATASET * outSet,
DEREF_REQUEST * deref,
unsigned long outOfBounds )

Definition at line 548 of file sddsderef.c.

548 {
549 double data[4];
550 long offset;
551 int64_t rows, row;
552 long *indexData;
553
554 if (!(rows = outSet->n_rows)) {
555 return 1;
556 }
557 offset = 0;
558 if (!(indexData = (long *)SDDS_GetNumericColumn(outSet, deref->indexElement[0], SDDS_LONG))) {
559 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
560 return 0;
561 }
562
563 for (row = 0; row < rows; row++) {
564 offset = indexData[row];
565 if (offset < 0 || offset >= rows) {
566 if (outOfBounds & EXIT_OUTBOUNDS) {
567 char s[1024];
568 sprintf(s, "column index out of bounds: column %s, length %" PRId64 ", offset %ld\n %s=%ld\n", deref->source, rows, offset, deref->indexElement[0], offset);
569 SDDS_Bomb(s);
570 }
571 if (!SDDS_AssertRowFlags(outSet, SDDS_INDEX_LIMITS, row, row, 0)) {
572 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
573 return 0;
574 }
575 } else if (!SDDS_GetValueByAbsIndex(outSet, deref->sourceIndex, offset, (void *)data) ||
576 !SDDS_SetRowValues(outSet, SDDS_SET_BY_INDEX | SDDS_PASS_BY_REFERENCE, row, deref->targetIndex, (void *)data, -1)) {
577 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
578 return 0;
579 }
580 }
581 free(indexData);
582 return 1;
583}
void * SDDS_GetValueByAbsIndex(SDDS_DATASET *SDDS_dataset, int32_t column_index, int64_t row_index, void *memory)
Retrieves the value from a specified column and absolute row index, optionally storing it in provided...

◆ DereferenceColumnWithParameter()

long DereferenceColumnWithParameter ( SDDS_DATASET * outSet,
DEREF_REQUEST * deref,
unsigned long outOfBounds )

Definition at line 391 of file sddsderef.c.

391 {
392 double data[4];
393 long offset, type;
394 int64_t rows;
395 double value;
396 int32_t zeroValue = 0;
397 static char *blankString = "";
398
399 if (!(rows = outSet->n_rows))
400 return 1;
401 type = SDDS_GetColumnType(outSet, deref->sourceIndex);
402 if (deref->targetClass == CONSTANT_CLASS) {
403 value = deref->indexValue[0];
404 } else if (!SDDS_GetParameterAsDouble(outSet, deref->indexElement[0], &value)) {
405 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
406 return 0;
407 }
408 offset = ((long)value);
409 if (offset < 0 || offset >= rows) {
410 if (outOfBounds & EXIT_OUTBOUNDS) {
411 char s[1024];
412 sprintf(s, "column index out of bounds: column %s, length %" PRId64 ", offset %ld\n %s=%ld", deref->source, rows, offset, deref->indexElement[0], offset);
413 SDDS_Bomb(s);
414 }
415 if (type == SDDS_STRING)
416 memcpy((char *)data, (char *)&blankString, sizeof(blankString));
417 else
418 SDDS_CastValue((void *)&zeroValue, 0, SDDS_LONG, type, (void *)data);
419 } else {
420 if (!SDDS_GetValueByAbsIndex(outSet, deref->sourceIndex, offset, (void *)data)) {
421 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
422 return 0;
423 }
424 }
425
426 if (!SDDS_SetParameters(outSet, SDDS_SET_BY_INDEX | SDDS_PASS_BY_REFERENCE, deref->targetIndex, (void *)data, -1)) {
427 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
428 return 0;
429 }
430 return 1;
431}
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.

◆ DoDereferencing()

long DoDereferencing ( SDDS_DATASET * outSet,
DEREF_REQUEST * deref,
long derefs,
unsigned long outOfBounds )

Definition at line 348 of file sddsderef.c.

348 {
349 long i;
350 for (i = 0; i < derefs; i++) {
351 switch (deref[i].targetClass) {
352 case PARAMETER_CLASS:
353 case CONSTANT_CLASS:
354 switch (deref[i].sourceClass) {
355 case ARRAY_CLASS:
356 if (!DereferenceArrayWithParameter(outSet, deref + i, outOfBounds))
357 return 0;
358 break;
359 case COLUMN_CLASS:
360 if (!DereferenceColumnWithParameter(outSet, deref + i, outOfBounds))
361 return 0;
362 break;
363 default:
364 SDDS_Bomb("invalid source class--code error (DoDereferencing)");
365 break;
366 }
367 break;
368 case COLUMN_CLASS:
369 switch (deref[i].sourceClass) {
370 case ARRAY_CLASS:
371 if (!DereferenceArrayWithColumn(outSet, deref + i, outOfBounds))
372 return 0;
373 break;
374 case COLUMN_CLASS:
375 if (!DereferenceColumnWithColumn(outSet, deref + i, outOfBounds))
376 return 0;
377 break;
378 default:
379 SDDS_Bomb("invalid source class--code error (DoDereferencing)");
380 break;
381 }
382 break;
383 default:
384 SDDS_Bomb("invalid target class--code error (DoDereferencing)");
385 break;
386 }
387 }
388 return 1;
389}

◆ main()

int main ( int argc,
char ** argv )

Definition at line 109 of file sddsderef.c.

109 {
110 SDDS_DATASET inSet, outSet;
111 SCANNED_ARG *s_arg;
112 long i_arg;
113 char *input, *output;
114 long derefRequests, code;
115 unsigned long outOfBounds;
116 DEREF_REQUEST *derefRequest;
117 unsigned long pipeFlags, majorOrderFlag;
118 short columnMajorOrder = -1;
119
121 argc = scanargs(&s_arg, argc, argv);
122 if (argc < 2)
123 bomb(NULL, USAGE);
124
125 input = output = NULL;
126 derefRequests = 0;
127 derefRequest = NULL;
128 pipeFlags = 0;
129 outOfBounds = EXIT_OUTBOUNDS;
130
131 for (i_arg = 1; i_arg < argc; i_arg++) {
132 if (s_arg[i_arg].arg_type == OPTION) {
133 switch (match_string(s_arg[i_arg].list[0], optionName, N_OPTIONS, 0)) {
134 case SET_MAJOR_ORDER:
135 majorOrderFlag = 0;
136 s_arg[i_arg].n_items--;
137 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)))
138 SDDS_Bomb("invalid -majorOrder syntax/values");
139 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
140 columnMajorOrder = 1;
141 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
142 columnMajorOrder = 0;
143 break;
144 case SET_COLUMN:
145 if (s_arg[i_arg].n_items < 4)
146 SDDS_Bomb("invalid -column syntax");
147 addDerefRequest(&derefRequest, &derefRequests, s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, COLUMN_CLASS);
148 break;
149 case SET_PARAMETER:
150 if (s_arg[i_arg].n_items < 4)
151 SDDS_Bomb("invalid -parameter syntax");
152 addDerefRequest(&derefRequest, &derefRequests, s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, PARAMETER_CLASS);
153 break;
154 case SET_CONSTANT:
155 if (s_arg[i_arg].n_items < 4)
156 SDDS_Bomb("invalid -constant syntax");
157 addDerefRequest(&derefRequest, &derefRequests, s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, CONSTANT_CLASS);
158 break;
159 case SET_PIPE:
160 if (!processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
161 SDDS_Bomb("invalid -pipe syntax");
162 break;
163 case SET_OUTOFBOUNDS:
164 s_arg[i_arg].n_items -= 1;
165 outOfBounds = 0;
166 if (s_arg[i_arg].n_items != 1 || !scanItemList(&outOfBounds, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0, "exit", -1, NULL, 0, EXIT_OUTBOUNDS, "delete", -1, NULL, 0, DELETE_OUTBOUNDS, NULL) || !outOfBounds) {
167 SDDS_Bomb("invalid -outOfBounds syntax/values");
168 }
169 break;
170 default:
171 fprintf(stderr, "error: unknown/ambiguous option: %s\n", s_arg[i_arg].list[0]);
172 exit(EXIT_FAILURE);
173 break;
174 }
175 } else {
176 if (input == NULL)
177 input = s_arg[i_arg].list[0];
178 else if (output == NULL)
179 output = s_arg[i_arg].list[0];
180 else
181 SDDS_Bomb("too many filenames");
182 }
183 }
184
185 processFilenames("sddsderef", &input, &output, pipeFlags, 0, NULL);
186
187 setupOutputFile(&outSet, output, &inSet, input, derefRequest, derefRequests, columnMajorOrder);
188
189 while ((code = SDDS_ReadPage(&inSet)) > 0) {
190 if (!SDDS_CopyPage(&outSet, &inSet))
191 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
192 if (!DoDereferencing(&outSet, derefRequest, derefRequests, outOfBounds))
193 SDDS_Bomb("problem doing dereferencing");
194 if (!SDDS_WritePage(&outSet))
195 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
196 }
197 if (code == 0)
198 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
199 if (!SDDS_Terminate(&inSet) || !SDDS_Terminate(&outSet)) {
200 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
201 exit(EXIT_FAILURE);
202 }
203 return EXIT_SUCCESS;
204}
int32_t SDDS_CopyPage(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:578
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.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
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 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

◆ setupOutputFile()

void setupOutputFile ( SDDS_DATASET * outSet,
char * output,
SDDS_DATASET * inSet,
char * input,
DEREF_REQUEST * deref,
long derefs,
short columnMajorOrder )

Definition at line 206 of file sddsderef.c.

206 {
207 long i, j;
208 if (!SDDS_InitializeInput(inSet, input) ||
209 !SDDS_InitializeCopy(outSet, inSet, output, "w"))
210 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
211 if (columnMajorOrder != -1)
212 outSet->layout.data_mode.column_major = columnMajorOrder;
213 else
214 outSet->layout.data_mode.column_major = inSet->layout.data_mode.column_major;
215 for (i = 0; i < derefs; i++) {
216 switch (deref[i].sourceClass) {
217 case ARRAY_CLASS:
218 if (SDDS_GetArrayIndex(outSet, deref[i].source) < 0) {
219 fprintf(stderr, "error (sddsderef): no array %s in input\n", deref[i].source);
220 exit(EXIT_FAILURE);
221 }
222 break;
223 case COLUMN_CLASS:
224 if (SDDS_GetColumnIndex(outSet, deref[i].source) < 0) {
225 fprintf(stderr, "error (sddsderef): no column %s in input\n", deref[i].source);
226 exit(EXIT_FAILURE);
227 }
228 break;
229 default:
230 SDDS_Bomb("invalid source class in setupOutputFile (coding error)");
231 break;
232 }
233 switch (deref[i].targetClass) {
234 case PARAMETER_CLASS:
235 case CONSTANT_CLASS:
236 switch (deref[i].sourceClass) {
237 case ARRAY_CLASS:
238 if (!SDDS_DefineParameterLikeArray(outSet, outSet, deref[i].source, deref[i].target))
239 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
240 deref[i].sourceIndex = SDDS_GetArrayIndex(outSet, deref[i].source);
241 break;
242 case COLUMN_CLASS:
243 if (!SDDS_DefineParameterLikeColumn(outSet, outSet, deref[i].source, deref[i].target))
244 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
245 deref[i].sourceIndex = SDDS_GetColumnIndex(outSet, deref[i].source);
246 break;
247 }
248 deref[i].targetIndex = SDDS_GetParameterIndex(outSet, deref[i].target);
249 if (deref[i].targetClass == PARAMETER_CLASS) {
250 for (j = 0; j < deref[i].indexElements; j++) {
251 if (SDDS_GetParameterIndex(outSet, deref[i].indexElement[j]) < 0) {
252 fprintf(stderr, "error (sddsderef): no parameter %s in input\n", deref[i].indexElement[j]);
253 exit(EXIT_FAILURE);
254 }
255 }
256 }
257 break;
258 case COLUMN_CLASS:
259 switch (deref[i].sourceClass) {
260 case ARRAY_CLASS:
261 if (!SDDS_DefineColumnLikeArray(outSet, outSet, deref[i].source, deref[i].target))
262 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
263 deref[i].sourceIndex = SDDS_GetArrayIndex(outSet, deref[i].source);
264 break;
265 case COLUMN_CLASS:
266 if (!SDDS_TransferColumnDefinition(outSet, outSet, deref[i].source, deref[i].target))
267 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
268 deref[i].sourceIndex = SDDS_GetColumnIndex(outSet, deref[i].source);
269 break;
270 }
271 deref[i].targetIndex = SDDS_GetColumnIndex(outSet, deref[i].target);
272 for (j = 0; j < deref[i].indexElements; j++) {
273 if (SDDS_GetColumnIndex(outSet, deref[i].indexElement[j]) < 0) {
274 fprintf(stderr, "error (sddsderef): no column %s in input\n", deref[i].indexElement[j]);
275 exit(EXIT_FAILURE);
276 }
277 }
278 break;
279 default:
280 fprintf(stderr, "error (sddsderef): invalid target data class (internal error)\n");
281 exit(EXIT_FAILURE);
282 break;
283 }
284 }
285 if (!SDDS_WriteLayout(outSet))
286 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
287}
int32_t SDDS_InitializeCopy(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, char *filename, char *filemode)
Definition SDDS_copy.c:40
int32_t SDDS_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:49
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_DefineParameterLikeColumn(SDDS_DATASET *target, SDDS_DATASET *source, char *name, char *newName)
Defines a parameter in the target dataset based on a column definition from the source dataset.
int32_t SDDS_DefineColumnLikeArray(SDDS_DATASET *target, SDDS_DATASET *source, char *name, char *newName)
Defines a column in the target dataset based on an array definition from the source dataset.
int32_t SDDS_DefineParameterLikeArray(SDDS_DATASET *target, SDDS_DATASET *source, char *name, char *newName)
Defines a parameter in the target dataset based on an array definition from the source dataset.
int32_t SDDS_GetArrayIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named array 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.