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

Array Dereferencing Tool for SDDS Data Sets. More...

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

Go to the source code of this file.

Classes

struct  DEREF_REQUEST
 

Macros

#define COLUMN_CLASS   0
 
#define PARAMETER_CLASS   1
 
#define ARRAY_CLASS   2
 
#define CONSTANT_CLASS   3
 
#define CLASS_NAMES   4
 
#define EXIT_OUTBOUNDS   0x1U
 
#define DELETE_OUTBOUNDS   0x2U
 
#define ARRAY_SOURCE   0x1U
 
#define COLUMN_SOURCE   0x2U
 

Enumerations

enum  option_type {
  SET_COLUMN , SET_PARAMETER , SET_PIPE , SET_OUTOFBOUNDS ,
  SET_CONSTANT , SET_MAJOR_ORDER , N_OPTIONS
}
 

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)
 

Variables

static char * optionName [N_OPTIONS]
 
static char * USAGE
 

Detailed Description

Array Dereferencing Tool for SDDS Data Sets.

This program performs array dereferencing on SDDS (Self Describing Data Sets) data files. It allows users to create new columns or parameters by indexing into existing array or column data. The program supports various options for handling out-of-bounds indices and 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

  • -pipe=[input][,output]: Use standard input and/or output instead of files.
  • -column=<newName>,{arraySource|columnSource}=<name>,<indexColumnName>[,...]: Define a new column by dereferencing an existing array or column.
  • -parameter=<newName>,{arraySource|columnSource}=<name>,<indexParameterName>[,...]: Define a new parameter by dereferencing an existing array or column.
  • -constant=<newName>,{arraySource|columnSource}=<name>,<indexValue>[,<indexValue>]: Define a new constant by dereferencing an existing array or column.
  • -outOfBounds={exit|delete}: Specify the behavior when an index is out of bounds (exit the program or delete the row).
  • -majorOrder=row|column: Specify the major order for data processing.
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
M. Borland, R. Soliday, H. Shang

Definition in file sddsderef.c.

Macro Definition Documentation

◆ ARRAY_CLASS

#define ARRAY_CLASS   2

Definition at line 66 of file sddsderef.c.

◆ CLASS_NAMES

#define CLASS_NAMES   4

Definition at line 68 of file sddsderef.c.

◆ COLUMN_CLASS

#define COLUMN_CLASS   0

Definition at line 64 of file sddsderef.c.

◆ CONSTANT_CLASS

#define CONSTANT_CLASS   3

Definition at line 67 of file sddsderef.c.

◆ DELETE_OUTBOUNDS

#define DELETE_OUTBOUNDS   0x2U

Definition at line 102 of file sddsderef.c.

◆ EXIT_OUTBOUNDS

#define EXIT_OUTBOUNDS   0x1U

Definition at line 101 of file sddsderef.c.

◆ PARAMETER_CLASS

#define PARAMETER_CLASS   1

Definition at line 65 of file sddsderef.c.

Enumeration Type Documentation

◆ option_type

enum option_type

Definition at line 45 of file sddsderef.c.

45 {
46 SET_COLUMN,
47 SET_PARAMETER,
48 SET_PIPE,
49 SET_OUTOFBOUNDS,
50 SET_CONSTANT,
51 SET_MAJOR_ORDER,
52 N_OPTIONS
53};

Function Documentation

◆ addDerefRequest()

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

Definition at line 284 of file sddsderef.c.

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

480 {
481 SDDS_ARRAY *array;
482 long i, offset, size, index;
483 int64_t row, rows;
484 int32_t **indexData;
485
486 if (!(rows = outSet->n_rows))
487 return 1;
488 if (!(array = SDDS_GetArray(outSet, deref->source, NULL))) {
489 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
490 return 0;
491 }
492 if (deref->indexElements != array->definition->dimensions) {
493 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);
494 return 0;
495 }
496 size = SDDS_GetTypeSize(array->definition->type);
497 offset = 0;
498
499 if (!(indexData = (int32_t **)malloc(sizeof(*indexData) * deref->indexElements)))
500 SDDS_Bomb("memory allocation failure while derefencing column data");
501 for (i = 0; i < deref->indexElements; i++)
502 if (!(indexData[i] = (int32_t *)SDDS_GetNumericColumn(outSet, deref->indexElement[i], SDDS_LONG))) {
503 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
504 return 0;
505 }
506 for (row = 0; row < rows; row++) {
507 for (i = offset = 0; i < deref->indexElements; i++) {
508 /* get index values from columns */
509 index = indexData[i][row];
510 if (index < 0 || index > array->dimension[i]) {
511 offset = -1;
512 break;
513 }
514 offset = index + offset * array->dimension[i];
515 }
516
517 if (offset < 0 || offset >= array->elements) {
518 if (outOfBounds & EXIT_OUTBOUNDS) {
519 char s[1024], t[1024];
520 sprintf(s, "array index out of bounds: array %s, length %" PRId32 ", offset %ld\n", deref->source, array->elements, offset);
521 for (i = 0; i < deref->indexElements; i++) {
522 sprintf(t, " %s=%" PRId32 " (dim=%" PRId32 ")", deref->indexElement[i], indexData[i][row], array->dimension[i]);
523 strcat(s, t);
524 }
525 SDDS_Bomb(s);
526 }
527 if (!SDDS_AssertRowFlags(outSet, SDDS_INDEX_LIMITS, row, row, 0)) {
528 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
529 return 0;
530 }
531 } else if (!SDDS_SetRowValues(outSet, SDDS_SET_BY_INDEX | SDDS_PASS_BY_REFERENCE, row, deref->targetIndex, (char *)array->data + offset * size, -1)) {
532 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
533 return 0;
534 }
535 }
536 for (i = 0; i < deref->indexElements; i++)
537 free(indexData[i]);
538 free(indexData);
539 SDDS_FreeArray(array);
540 return 1;
541}
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 428 of file sddsderef.c.

428 {
429 SDDS_ARRAY *array;
430 long i, j, offset, size;
431 double value;
432 int32_t zeroValue = 0;
433 static char *blankString = "";
434 double data[4];
435
436 if (!(array = SDDS_GetArray(outSet, deref->source, NULL))) {
437 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
438 return 0;
439 }
440 if (deref->indexElements != array->definition->dimensions) {
441 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);
442 return 0;
443 }
444 size = SDDS_GetTypeSize(array->definition->type);
445 offset = 0;
446 for (i = 0, j = deref->indexElements - 1; i < deref->indexElements; i++, j--) {
447 if (deref->targetClass == CONSTANT_CLASS) {
448 value = deref->indexValue[i];
449 } else {
450 /* get index values from parameters */
451 if (!SDDS_GetParameterAsDouble(outSet, deref->indexElement[i], &value)) {
452 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
453 return 0;
454 }
455 }
456 offset = ((long)value) + offset * array->dimension[j];
457 }
458 if (offset < 0 || offset >= array->elements) {
459 if (outOfBounds & EXIT_OUTBOUNDS) {
460 char s[1024];
461 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);
462 SDDS_Bomb(s);
463 }
464 if (array->definition->type == SDDS_STRING)
465 memcpy((char *)data, (char *)&blankString, sizeof(blankString));
466 else
467 SDDS_CastValue((void *)&zeroValue, 0, SDDS_LONG, array->definition->type, (void *)data);
468 if (!SDDS_SetParameters(outSet, SDDS_SET_BY_INDEX | SDDS_PASS_BY_REFERENCE, deref->targetIndex, (void *)data, -1)) {
469 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
470 return 0;
471 }
472 } else if (!SDDS_SetParameters(outSet, SDDS_SET_BY_INDEX | SDDS_PASS_BY_REFERENCE, deref->targetIndex, (char *)array->data + offset * size, -1)) {
473 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
474 return 0;
475 }
476 SDDS_FreeArray(array);
477 return 1;
478}
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 543 of file sddsderef.c.

543 {
544 double data[4];
545 long offset;
546 int64_t rows, row;
547 long *indexData;
548
549 if (!(rows = outSet->n_rows)) {
550 return 1;
551 }
552 offset = 0;
553 if (!(indexData = (long *)SDDS_GetNumericColumn(outSet, deref->indexElement[0], SDDS_LONG))) {
554 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
555 return 0;
556 }
557
558 for (row = 0; row < rows; row++) {
559 offset = indexData[row];
560 if (offset < 0 || offset >= rows) {
561 if (outOfBounds & EXIT_OUTBOUNDS) {
562 char s[1024];
563 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);
564 SDDS_Bomb(s);
565 }
566 if (!SDDS_AssertRowFlags(outSet, SDDS_INDEX_LIMITS, row, row, 0)) {
567 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
568 return 0;
569 }
570 } else if (!SDDS_GetValueByAbsIndex(outSet, deref->sourceIndex, offset, (void *)data) ||
571 !SDDS_SetRowValues(outSet, SDDS_SET_BY_INDEX | SDDS_PASS_BY_REFERENCE, row, deref->targetIndex, (void *)data, -1)) {
572 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
573 return 0;
574 }
575 }
576 free(indexData);
577 return 1;
578}
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 386 of file sddsderef.c.

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

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

◆ main()

int main ( int argc,
char ** argv )

Definition at line 104 of file sddsderef.c.

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

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

Variable Documentation

◆ optionName

char* optionName[N_OPTIONS]
static
Initial value:
= {
"column",
"parameter",
"pipe",
"outofbounds",
"constant",
"majorOrder",
}

Definition at line 55 of file sddsderef.c.

55 {
56 "column",
57 "parameter",
58 "pipe",
59 "outofbounds",
60 "constant",
61 "majorOrder",
62};

◆ USAGE

char* USAGE
static
Initial value:
=
"Usage: sddsderef [<inputfile>] [<outputfile>]\n"
" [-pipe=[input][,output]]\n"
" [-column=<newName>,{arraySource|columnSource}=<name>,<indexColumnName>[,...]]\n"
" [-parameter=<newName>,{arraySource|columnSource}=<name>,<indexParameterName>[,...]]\n"
" [-constant=<newName>,{arraySource|columnSource}=<name>,<indexValue>[,<indexValue>]]\n"
" [-outOfBounds={exit|delete}] [-majorOrder=row|column]\n\n"
"Options:\n"
" -pipe Use standard input and/or output instead of files.\n"
" -column Define a new column by dereferencing an existing array or column.\n"
" -parameter Define a new parameter by dereferencing an existing array or column.\n"
" -constant Define a new constant by dereferencing an existing array or column.\n"
" -outOfBounds Specify behavior for out-of-bounds indices: 'exit' or 'delete'.\n"
" -majorOrder Specify the major order for processing: 'row' or 'column'.\n\n"
"Program by Michael Borland. (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")\n"

Definition at line 70 of file sddsderef.c.