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

Detailed Description

Transposes numerical columns in an SDDS file.

This program reads an SDDS file with one or more pages, identifies all numerical columns, and transposes them as though they were a matrix. If the file contains multiple pages, additional pages are transposed only if they have the same number of rows as the first page. String columns are converted to string parameters, and string parameters listed in the "OldStringColumnNames" parameter become string columns in the output. If any string columns exist, the data in the first string column is used as the names of the columns in the output file. If no string columns exist, column names are generated from command line options. The names of the input file columns are saved as a string column in the output file with a name specified via the command line or the default "OldColumnName".

Usage

sddstranspose [<inputfile>] [<outputfile>]
[-pipe=[input][,output]]
[-oldColumnNames=<string>]
[-root=<string>]
[-digits=<integer>]
[-newColumnNames=<column>}]
[-matchColumn=<string>[,<string>,...]]
[-indexColumn]
[-noOldColumnNames]
[-symbol=<string>]
[-ascii]
[-verbose]
[-majorOrder=row|column]

Options

Optional Description
-pipe Reads input from and/or writes output to a pipe.
-oldColumnNames Specifies the name for the output file string column created for the input column names.
-root Uses the specified string to generate column names of the output file.
-digits Sets the minimum number of digits appended to column names. Default is 3.
-newColumnNames Uses the specified column as the source for new column names.
-matchColumn Only transposes columns matching the specified names.
-indexColumn Adds an index column to the output file.
-noOldColumnNames Does not create a column for old column names.
-symbol Specifies the symbol field for column definitions.
-ascii Outputs the file in ASCII format. Default is binary.
-verbose Prints incidental information to stderr.
-majorOrder Specifies the output file's major order (row-major or column-major).

Incompatibilities

  • -root is incompatible with:
    • -newColumnNames
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, C. Saunders, L. Emery, R. Soliday, H. Shang

Definition in file sddstranspose.c.

#include "mdb.h"
#include "scan.h"
#include "match_string.h"
#include "matlib.h"
#include "SDDS.h"
#include "SDDSutils.h"

Go to the source code of this file.

Functions

char ** TokenizeString (char *source, long n_items)
 
char * JoinStrings (char **source, long n_items, long buflen_increment)
 
int main (int argc, char **argv)
 

Function Documentation

◆ JoinStrings()

char * JoinStrings ( char ** source,
long n_items,
long buflen_increment )

Definition at line 720 of file sddstranspose.c.

720 {
721 char *buffer;
722 char *ptr;
723 long buffer_size, bufferLeft, bufferUsed;
724 long i, slen;
725 char *sptr;
726
727 buffer_size = buflen_increment;
728 buffer = (char *)malloc(sizeof(char) * buffer_size);
729 buffer[0] = '\0';
730 ptr = buffer;
731 bufferLeft = buffer_size - 2;
732 bufferUsed = 0;
733 for (i = 0; i < n_items; i++) {
734 sptr = source[i];
735 slen = strlen(sptr);
736 while ((slen + 5) > bufferLeft) {
737 buffer = trealloc(buffer, sizeof(char) * (buffer_size += buflen_increment));
738 bufferLeft += buflen_increment;
739 ptr = buffer + bufferUsed;
740 }
741 if (i) {
742 slen++;
743 *ptr++ = ' ';
744 }
745 *ptr++ = '"';
746 while (*sptr)
747 *ptr++ = *sptr++;
748 *ptr++ = '"';
749 *ptr = '\0';
750 bufferLeft -= slen + 2;
751 bufferUsed += slen + 2;
752 }
753
754 return buffer;
755}
void * trealloc(void *old_ptr, uint64_t size_of_block)
Reallocates a memory block to a new size.
Definition array.c:181

◆ main()

int main ( int argc,
char ** argv )

Definition at line 141 of file sddstranspose.c.

141 {
142 SCANNED_ARG *s_arg;
143 SDDS_DATASET inputPage, outputPage;
144
145 char *inputfile, *outputfile;
146 char **inputColumnName, **inputStringColumnName, **inputDoubleColumnName;
147 char **outputStringColumnName, **outputDoubleColumnName, **matchColumn = NULL;
148 long inputDoubleColumns, inputStringColumns, indexColumn = 0, noOldColumnNamesColumn = 0;
149 int64_t inputRows;
150 int32_t matchColumns = 0;
151 long outputRows, outputDoubleColumns, outputStringColumns;
152 char **inputParameterName;
153 int32_t inputParameters;
154 int32_t inputColumns;
155 char *inputDescription, *inputContents;
156 char *outputDescription;
157 long i, i_arg, col;
158 char *buffer;
159 char **columnOfStrings;
160 long buffer_size;
161#define BUFFER_SIZE_INCREMENT 16384
162 MATRIX *R, *RInv;
163 long OldStringColumnsDefined;
164 char *inputStringRows, *outputStringRows;
165 char **stringArray, *stringParameter;
166 long token_length;
167 long verbose;
168 char format[32];
169 long digits;
170 char *Symbol, *Root;
171 void *parameterPointer;
172 long ascii;
173 unsigned long pipeFlags, majorOrderFlag;
174 long tmpfile_used, noWarnings;
175 long ipage = 0, columnType;
176 char *oldColumnNames, *newColumnNamesColumn;
177 short columnMajorOrder = -1;
178
179 inputColumnName = outputStringColumnName = outputDoubleColumnName = inputParameterName = NULL;
180 outputRows = outputDoubleColumns = outputStringColumns = OldStringColumnsDefined = 0;
181
183
184 argc = scanargs(&s_arg, argc, argv);
185 if (argc == 1)
186 bomb(NULL, USAGE);
187
188 inputfile = outputfile = NULL;
189 verbose = 0;
190 Symbol = Root = NULL;
191 ascii = 0;
192 digits = 3;
193 pipeFlags = 0;
194 tmpfile_used = 0;
195 noWarnings = 0;
196 oldColumnNames = NULL;
197 newColumnNamesColumn = NULL;
198
199 for (i_arg = 1; i_arg < argc; i_arg++) {
200 if (s_arg[i_arg].arg_type == OPTION) {
201 switch (match_string(s_arg[i_arg].list[0], commandline_option, N_OPTIONS, UNIQUE_MATCH)) {
202 case CLO_MAJOR_ORDER:
203 majorOrderFlag = 0;
204 s_arg[i_arg].n_items--;
205 if (s_arg[i_arg].n_items > 0 &&
206 (!scanItemList(&majorOrderFlag, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
207 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
208 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
209 SDDS_Bomb("invalid -majorOrder syntax/values");
210 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
211 columnMajorOrder = 1;
212 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
213 columnMajorOrder = 0;
214 break;
215 case CLO_MATCH_COLUMN:
216 matchColumns = s_arg[i_arg].n_items - 1;
217 matchColumn = s_arg[i_arg].list + 1;
218 break;
219 case CLO_INDEX_COLUMN:
220 indexColumn = 1;
221 break;
222 case CLO_NO_OLDCOLUMNNAMES:
223 noOldColumnNamesColumn = 1;
224 break;
225 case CLO_VERBOSE:
226 verbose = 1;
227 break;
228 case CLO_ASCII:
229 ascii = 1;
230 break;
231 case CLO_DIGITS:
232 if (!(get_long(&digits, s_arg[i_arg].list[1])))
233 bomb("No integer provided for option -digits", USAGE);
234 break;
235 case CLO_COLUMNROOT:
236 if (!(Root = s_arg[i_arg].list[1]))
237 SDDS_Bomb("No root string provided with -root option");
238 break;
239 case CLO_SYMBOL:
240 if (!(Symbol = s_arg[i_arg].list[1]))
241 SDDS_Bomb("No symbol string provided with -symbol option");
242 break;
243 case CLO_PIPE:
244 if (!processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
245 SDDS_Bomb("Invalid -pipe syntax");
246 break;
247 case CLO_OLDCOLUMNNAMES:
248 if (!(oldColumnNames = s_arg[i_arg].list[1]))
249 SDDS_Bomb("No string provided for -oldColumnNames option");
250 break;
251 case CLO_NEWCOLUMNNAMES:
252 if (s_arg[i_arg].n_items != 2 || SDDS_StringIsBlank(newColumnNamesColumn = s_arg[i_arg].list[1]))
253 SDDS_Bomb("Invalid syntax or value for -newColumnNames option");
254 break;
255 default:
256 bomb("Unrecognized option provided", USAGE);
257 }
258 } else {
259 if (!inputfile)
260 inputfile = s_arg[i_arg].list[0];
261 else if (!outputfile)
262 outputfile = s_arg[i_arg].list[0];
263 else
264 bomb("Too many filenames provided", USAGE);
265 }
266 }
267
268 processFilenames("sddstranspose", &inputfile, &outputfile, pipeFlags, noWarnings, &tmpfile_used);
269 if (newColumnNamesColumn && Root)
270 SDDS_Bomb("-root and -newColumnNames options are incompatible");
271
272 if (!SDDS_InitializeInput(&inputPage, inputfile) ||
273 !(inputParameterName = (char **)SDDS_GetParameterNames(&inputPage, &inputParameters)) ||
274 !SDDS_GetDescription(&inputPage, &inputDescription, &inputContents))
275 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
276
277 if (matchColumns)
278 inputColumnName = getMatchingSDDSNames(&inputPage, matchColumn, matchColumns, &inputColumns, SDDS_MATCH_COLUMN);
279 else {
280 if (!(inputColumnName = (char **)SDDS_GetColumnNames(&inputPage, &inputColumns)))
281 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
282 }
283
284 inputDoubleColumns = 0;
285 inputStringColumns = 0;
286 inputDoubleColumnName = (char **)malloc(inputColumns * sizeof(char *));
287 inputStringColumnName = (char **)malloc(inputColumns * sizeof(char *));
288 inputRows = 0;
289
290 /***********
291 * Read data
292 ***********/
293 while (0 < SDDS_ReadTable(&inputPage)) {
294 ipage++;
295#if defined(DEBUG)
296 fprintf(stderr, "Working on page %ld\n", ipage);
297#endif
298 if (ipage == 1) {
299 if (!SDDS_SetColumnFlags(&inputPage, 0))
300 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
301
302 /* Count the string and numerical columns in the input file */
303 for (i = 0; i < inputColumns; i++) {
304 if (SDDS_NUMERIC_TYPE(columnType = SDDS_GetColumnType(&inputPage, i))) {
305 inputDoubleColumnName[inputDoubleColumns] = inputColumnName[i];
306 inputDoubleColumns++;
307 }
308 }
309 for (i = 0; i < inputPage.layout.n_columns; i++) {
310 if (inputPage.layout.column_definition[i].type == SDDS_STRING) {
311 inputStringColumnName[inputStringColumns] = inputPage.layout.column_definition[i].name;
312 inputStringColumns++;
313 }
314 }
315 if (!(inputRows = SDDS_CountRowsOfInterest(&inputPage)))
316 SDDS_Bomb("No rows in dataset.");
317 } else {
318 /* These statements are executed on subsequent pages */
319 if (inputRows != SDDS_CountRowsOfInterest(&inputPage)) {
320 SDDS_Bomb("Datasets have differing number of rows. Processing stopped before reaching end of input file.");
321 }
322 }
323
324 if (inputRows > INT32_MAX) {
325 SDDS_Bomb("Too many rows in dataset.");
326 }
327
328#if defined(DEBUG)
329 fprintf(stderr, "Row flags set\n");
330#endif
331 if (inputDoubleColumns == 0)
332 SDDS_Bomb("No numerical columns in file.");
333
334 if ((ipage == 1) && verbose) {
335 fprintf(stderr, "Number of numerical columns: %ld.\n", inputDoubleColumns);
336 fprintf(stderr, "Number of string columns: %ld.\n", inputStringColumns);
337 fprintf(stderr, "Number of rows: %" PRId64 ".\n", inputRows);
338 }
339
340 /****************
341 * Transpose data
342 ****************/
343 if (inputDoubleColumns) {
344 if (ipage == 1) {
345 m_alloc(&RInv, inputRows, inputDoubleColumns);
346 m_alloc(&R, inputDoubleColumns, inputRows);
347 }
348 for (col = 0; col < inputDoubleColumns; col++) {
349 if (!(R->a[col] = (double *)SDDS_GetColumnInDoubles(&inputPage, inputDoubleColumnName[col]))) {
350 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
351 }
352 }
353 if (verbose) {
354 m_show(R, "%9.6le ", "Transpose of input matrix:\n", stdout);
355 }
356 m_trans(RInv, R);
357 }
358
359 /***************************
360 * Determine existence of
361 * transposed string columns
362 ***************************/
363 if (ipage == 1) {
364 OldStringColumnsDefined = 0;
365 switch (SDDS_CheckParameter(&inputPage, OLD_STRING_COLUMN_NAMES, NULL, SDDS_STRING, NULL)) {
366 case SDDS_CHECK_OKAY:
367 OldStringColumnsDefined = 1;
368 break;
369 case SDDS_CHECK_NONEXISTENT:
370 break;
371 case SDDS_CHECK_WRONGTYPE:
372 case SDDS_CHECK_WRONGUNITS:
373 fprintf(stderr, "Error: Parameter OldStringColumns has incorrect type or units.\n");
374 exit(EXIT_FAILURE);
375 break;
376 }
377
378 if (OldStringColumnsDefined) {
379 /* Decompose OldStringColumns into names of string columns for the output file */
380 if (!SDDS_GetParameter(&inputPage, OLD_STRING_COLUMN_NAMES, &inputStringRows))
381 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
382
383 if (verbose) {
384 fprintf(stderr, "Parameter OldStringColumns: %s.\n", inputStringRows);
385 }
386
387 outputStringColumnName = (char **)malloc(sizeof(char *));
388 outputStringColumns = 0;
389 buffer_size = BUFFER_SIZE_INCREMENT;
390 buffer = (char *)malloc(sizeof(char) * buffer_size);
391 while (0 <= (token_length = SDDS_GetToken(inputStringRows, buffer, BUFFER_SIZE_INCREMENT))) {
392 if (!token_length)
393 SDDS_Bomb("A null string was detected in parameter OldStringColumns.");
394
395 if (!SDDS_CopyString(&outputStringColumnName[outputStringColumns], buffer))
396 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
397
398 if (verbose) {
399 fprintf(stderr, "Output string column: %s\n", outputStringColumnName[outputStringColumns]);
400 }
401 outputStringColumns++;
402 }
403 }
404 }
405
406 /*********************
407 * Define output page
408 *********************/
409 if (ipage == 1) {
410 outputRows = inputDoubleColumns;
411 outputDoubleColumns = inputRows;
412
413 if (inputDescription) {
414 outputDescription = (char *)malloc(sizeof(char) * (strlen("Transpose of ") + strlen(inputDescription) + 1));
415 strcpy(outputDescription, "Transpose of ");
416 strcat(outputDescription, inputDescription);
417 if (!SDDS_InitializeOutput(&outputPage, ascii ? SDDS_ASCII : SDDS_BINARY, 1, outputDescription, inputContents, outputfile))
418 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
419 free(outputDescription);
420 } else {
421 if (!SDDS_InitializeOutput(&outputPage, ascii ? SDDS_ASCII : SDDS_BINARY, 1, NULL, NULL, outputfile))
422 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
423 }
424
425 SDDS_DeferSavingLayout(&outputPage, 1);
426
427 if (columnMajorOrder != -1)
428 outputPage.layout.data_mode.column_major = columnMajorOrder;
429 else
430 outputPage.layout.data_mode.column_major = inputPage.layout.data_mode.column_major;
431
432 /***********************************
433 * Define names for numerical columns
434 ***********************************/
435 if (!Root && inputStringColumns) {
436 /* Use specified string column, or first string column encountered */
437 if (!newColumnNamesColumn)
438 /* First string column encountered */
439 outputDoubleColumnName = (char **)SDDS_GetColumn(&inputPage, inputStringColumnName[0]);
440 else {
441 /* Use specified string column */
442 if (SDDS_CheckColumn(&inputPage, newColumnNamesColumn, NULL, SDDS_STRING, stderr) != SDDS_CHECK_OKAY)
443 SDDS_Bomb("Column specified with -newColumnNames does not exist in input file.");
444 outputDoubleColumnName = (char **)SDDS_GetColumn(&inputPage, newColumnNamesColumn);
445 }
446
447 for (i = 1; i < inputRows; i++) {
448 if (match_string(outputDoubleColumnName[i - 1], outputDoubleColumnName + i, inputRows - i, EXACT_MATCH) >= 0) {
449 fprintf(stderr, "Error: Duplicate column name '%s' found in input file string column '%s'. Cannot be used as output column names.\n",
450 outputDoubleColumnName[i - 1], newColumnNamesColumn ? newColumnNamesColumn : inputStringColumnName[0]);
451 exit(EXIT_FAILURE);
452 }
453 }
454 } else {
455 /* Use command line options to generate column names in the output file */
456 outputDoubleColumnName = (char **)malloc(outputDoubleColumns * sizeof(char *));
457 digits = MAX(digits, (long)(log10(inputRows) + 1));
458 if (!Root) {
459 Root = (char *)malloc(sizeof(char) * (strlen("Column") + 1));
460 strcpy(Root, "Column");
461 }
462 if (outputDoubleColumns != 1) {
463 for (i = 0; i < outputDoubleColumns; i++) {
464 outputDoubleColumnName[i] = (char *)malloc(sizeof(char) * (strlen(Root) + digits + 1));
465 sprintf(format, "%s%%0%ldld", Root, digits);
466 sprintf(outputDoubleColumnName[i], format, i);
467 }
468 } else { /* Only one row to transpose */
469 outputDoubleColumnName[0] = (char *)malloc(sizeof(char) * (strlen(Root) + 1));
470 strcpy(outputDoubleColumnName[0], Root);
471 }
472 }
473
474 /*************************
475 * Define string columns
476 *************************/
477 if (OldStringColumnsDefined) {
478 if (!SDDS_DefineSimpleColumns(&outputPage, outputStringColumns, outputStringColumnName, NULL, SDDS_STRING))
479 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
480 } else {
481 /* By default, at least one string column should exist for old column names */
482 if (!noOldColumnNamesColumn) {
483 outputStringColumns = 1;
484 outputStringColumnName = (char **)malloc(sizeof(char *));
485 if (oldColumnNames) {
486 /* Command line option specification */
487 outputStringColumnName[0] = oldColumnNames;
488 } else {
489 outputStringColumnName[0] = (char *)malloc(sizeof(char) * (strlen("OldColumnNames") + 1));
490 strcpy(outputStringColumnName[0], "OldColumnNames");
491 }
492 if (0 > SDDS_DefineColumn(&outputPage, outputStringColumnName[0], NULL, NULL, NULL, NULL, SDDS_STRING, 0))
493 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
494 }
495 }
496
497 if (indexColumn && !SDDS_DefineSimpleColumn(&outputPage, "Index", NULL, SDDS_LONG))
498 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
499
500 /*************************
501 * Define numerical columns
502 *************************/
503 for (i = 0; i < outputDoubleColumns; i++) {
504 if (Symbol) {
505 if (0 > SDDS_DefineColumn(&outputPage, outputDoubleColumnName[i], Symbol, NULL, NULL, NULL, SDDS_DOUBLE, 0))
506 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
507 } else {
508 if (0 > SDDS_DefineColumn(&outputPage, outputDoubleColumnName[i], NULL, NULL, NULL, NULL, SDDS_DOUBLE, 0))
509 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
510 }
511 }
512
513 /********************************
514 * Define string parameters
515 * i.e., transposed string columns
516 ********************************/
517 if (inputStringColumns > 1) {
518 if (0 > SDDS_DefineParameter(&outputPage, OLD_STRING_COLUMN_NAMES, NULL, NULL, "Transposed string columns", NULL, SDDS_STRING, NULL))
519 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
520 for (i = 0; i < inputStringColumns; i++) {
521 if (0 > SDDS_DefineParameter(&outputPage, inputStringColumnName[i], NULL, NULL, "Transposed string column data", NULL, SDDS_STRING, NULL))
522 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
523 }
524 }
525
526 /*************************
527 * Transfer other parameters
528 *************************/
529 if (inputParameters) {
530 for (i = 0; i < inputParameters; i++) {
531 if ((0 > match_string(inputParameterName[i], outputStringColumnName, outputStringColumns, 0) &&
532 strcasecmp(inputParameterName[i], OLD_STRING_COLUMN_NAMES))) {
533 if (0 > SDDS_TransferParameterDefinition(&outputPage, &inputPage, inputParameterName[i], NULL))
534 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
535 }
536 }
537 }
538
539 /***************
540 * Write layout
541 ***************/
542 SDDS_DeferSavingLayout(&outputPage, 0);
543
544 /* If InputFile is not already transferred to the output file, then create it */
545 switch (SDDS_CheckParameter(&outputPage, "InputFile", NULL, SDDS_STRING, NULL)) {
546 case SDDS_CHECK_NONEXISTENT:
547 if (0 > SDDS_DefineParameter(&outputPage, "InputFile", NULL, NULL, "Original matrix file", NULL, SDDS_STRING, NULL))
548 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
549 break;
550 default:
551 break;
552 }
553
554 if (!SDDS_WriteLayout(&outputPage))
555 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
556 }
557
558#if defined(DEBUG)
559 fprintf(stderr, "Table layout defined\n");
560#endif
561
562 if (!SDDS_StartTable(&outputPage, outputRows))
563 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
564 if (ipage == 1) {
565 if (!SDDS_SetParameters(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, "InputFile", inputfile ? inputfile : "pipe", NULL))
566 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
567 }
568
569 /***************************************
570 * Assign string columns from input
571 * to string parameters in output
572 ***************************************/
573 if (inputStringColumns > 1) {
574 for (i = 0; i < inputStringColumns; i++) {
575 columnOfStrings = (char **)SDDS_GetColumn(&inputPage, inputStringColumnName[i]);
576 stringParameter = JoinStrings(columnOfStrings, inputRows, BUFFER_SIZE_INCREMENT);
577 if (!SDDS_SetParameters(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, inputStringColumnName[i], stringParameter, NULL))
578 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
579 free(columnOfStrings);
580 free(stringParameter);
581 }
582 outputStringRows = JoinStrings(inputStringColumnName, inputStringColumns, BUFFER_SIZE_INCREMENT);
583 if (!SDDS_SetParameters(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, OLD_STRING_COLUMN_NAMES, outputStringRows, NULL))
584 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
585 }
586
587#if defined(DEBUG)
588 fprintf(stderr, "String parameters assigned\n");
589#endif
590
591 if (inputParameters) {
592 for (i = 0; i < inputParameters; i++) {
593 if ((0 > match_string(inputParameterName[i], outputStringColumnName, outputStringColumns, 0) &&
594 strcasecmp(inputParameterName[i], OLD_STRING_COLUMN_NAMES))) {
595 parameterPointer = (void *)SDDS_GetParameter(&inputPage, inputParameterName[i], NULL);
596 if (!SDDS_SetParameters(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_REFERENCE, inputParameterName[i], parameterPointer, NULL))
597 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
598 free(parameterPointer);
599 }
600 }
601 }
602
603#if defined(DEBUG)
604 fprintf(stderr, "Input parameters assigned\n");
605#endif
606
607 /**********************************
608 * Assign data to output table part
609 * of data set
610 **********************************/
611 if (outputRows) {
612 /***************************
613 * Assign string column data
614 ***************************/
615 if (OldStringColumnsDefined) {
616 for (i = 0; i < outputStringColumns; i++) {
617 if (!SDDS_GetParameter(&inputPage, outputStringColumnName[i], &stringParameter))
618 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
619 stringArray = TokenizeString(stringParameter, outputRows);
620 if (!SDDS_SetColumn(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_REFERENCE, stringArray, outputRows, outputStringColumnName[i]))
621 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
622 free(stringArray);
623 }
624 } else {
625 if (!noOldColumnNamesColumn &&
626 !SDDS_SetColumn(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_REFERENCE, inputDoubleColumnName, outputRows, outputStringColumnName[0]))
627 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
628 }
629
630#if defined(DEBUG)
631 fprintf(stderr, "String data columns assigned\n");
632#endif
633
634 /***************************
635 * Assign numerical column data
636 ***************************/
637 for (i = 0; i < outputDoubleColumns; i++) /* i is the row index */
638 if (!SDDS_SetColumn(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_REFERENCE, RInv->a[i], outputRows, outputDoubleColumnName[i]))
639 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
640
641 if (indexColumn) {
642 for (i = 0; i < outputRows; i++)
643 if (!SDDS_SetRowValues(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, i, "Index", i, NULL))
644 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
645 }
646
647#if defined(DEBUG)
648 fprintf(stderr, "Numerical data columns assigned\n");
649#endif
650 }
651
652#if defined(DEBUG)
653 fprintf(stderr, "Data assigned\n");
654#endif
655
656 if (!SDDS_WriteTable(&outputPage))
657 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
658
659#if defined(DEBUG)
660 fprintf(stderr, "Data written out\n");
661#endif
662 }
663
664 if (inputDoubleColumns) {
665 m_free(&RInv);
666 m_free(&R);
667 }
668 if (inputColumnName) {
669 SDDS_FreeStringArray(inputColumnName, inputColumns);
670 free(inputColumnName);
671 }
672 if (inputStringColumns)
673 free(inputStringColumnName);
674 if (inputDescription)
675 free(inputDescription);
676 if (inputParameterName) {
677 SDDS_FreeStringArray(inputParameterName, inputParameters);
678 free(inputParameterName);
679 }
680 if (outputDoubleColumns) {
681 SDDS_FreeStringArray(outputDoubleColumnName, outputDoubleColumns);
682 free(outputDoubleColumnName);
683 }
684
685 if (!SDDS_Terminate(&inputPage))
686 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
687 if (ipage > 0) {
688 if (!SDDS_Terminate(&outputPage))
689 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
690 }
691 if (tmpfile_used && !replaceFileAndBackUp(inputfile, outputfile))
692 exit(EXIT_FAILURE);
693
694 return EXIT_SUCCESS;
695}
void SDDS_DeferSavingLayout(SDDS_DATASET *SDDS_dataset, int32_t mode)
Definition SDDS_copy.c:603
int32_t SDDS_SetRowValues(SDDS_DATASET *SDDS_dataset, int32_t mode, int64_t row,...)
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
int32_t SDDS_SetColumn(SDDS_DATASET *SDDS_dataset, int32_t mode, void *data, int64_t rows,...)
Sets the values for one data column in the current data table of an SDDS dataset.
void * SDDS_GetColumn(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves a copy of the data for a specified column, including only rows marked as "of interest".
int64_t SDDS_CountRowsOfInterest(SDDS_DATASET *SDDS_dataset)
Counts the number of rows marked as "of interest" in the current data table.
void * SDDS_GetParameter(SDDS_DATASET *SDDS_dataset, char *parameter_name, void *memory)
Retrieves the value of a specified parameter from the current data table of a data set.
int32_t SDDS_SetColumnFlags(SDDS_DATASET *SDDS_dataset, int32_t column_flag_value)
Sets the acceptance flags for all columns in the current data table of a data set.
int32_t SDDS_GetDescription(SDDS_DATASET *SDDS_dataset, char **text, char **contents)
Retrieves the text and contents descriptions from an SDDS dataset.
double * SDDS_GetColumnInDoubles(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves the data of a specified numerical column as an array of doubles, considering only rows mark...
int32_t SDDS_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:49
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_InitializeOutput(SDDS_DATASET *SDDS_dataset, int32_t data_mode, int32_t lines_per_row, const char *description, const char *contents, const char *filename)
Initializes the SDDS output dataset.
int32_t SDDS_DefineSimpleColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *unit, int32_t type)
Defines a simple data column within the SDDS dataset.
int32_t SDDS_DefineSimpleColumns(SDDS_DATASET *SDDS_dataset, int32_t number, char **name, char **unit, int32_t type)
Defines multiple simple data columns of the same data type within the SDDS dataset.
int32_t SDDS_DefineColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, int32_t field_length)
Defines a data column within the SDDS dataset.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
int32_t SDDS_DefineParameter(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, char *fixed_value)
Defines a data parameter with a fixed string value.
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.
int32_t SDDS_FreeStringArray(char **string, int64_t strings)
Frees an array of strings by deallocating each individual string.
char ** getMatchingSDDSNames(SDDS_DATASET *dataset, char **matchName, int32_t matches, int32_t *names, short type)
Retrieves an array of matching SDDS entity names based on specified criteria.
char ** SDDS_GetParameterNames(SDDS_DATASET *SDDS_dataset, int32_t *number)
Retrieves the names of all parameters in the SDDS dataset.
int32_t SDDS_CheckColumn(SDDS_DATASET *SDDS_dataset, char *name, char *units, int32_t type, FILE *fp_message)
Checks if a column exists in the SDDS dataset with the specified name, units, and type.
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.
Definition SDDS_utils.c:432
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
int32_t SDDS_StringIsBlank(char *s)
Checks if a string is blank (contains only whitespace characters).
int32_t SDDS_GetToken(char *s, char *buffer, int32_t buflen)
Extracts the next token from a string, handling quoted substrings and escape characters.
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.
Definition SDDS_utils.c:342
int32_t SDDS_CheckParameter(SDDS_DATASET *SDDS_dataset, char *name, char *units, int32_t type, FILE *fp_message)
Checks if a parameter exists in the SDDS dataset with the specified name, units, and type.
int32_t SDDS_CopyString(char **target, const char *source)
Copies a source string to a target string with memory allocation.
Definition SDDS_utils.c:856
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
#define SDDS_NUMERIC_TYPE(type)
Checks if the given type identifier corresponds to any numeric type.
Definition SDDStypes.h:138
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
int get_long(long *iptr, char *s)
Parses a long integer value from the given string.
Definition data_scan.c:255
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.
Definition replacefile.c:75
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
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.

◆ TokenizeString()

char ** TokenizeString ( char * source,
long n_items )

Definition at line 697 of file sddstranspose.c.

697 {
698 char *buffer;
699 long buflen;
700 char *ptr;
701 char **string_array;
702 long i;
703
704 if (!source)
705 return NULL;
706 ptr = source;
707 string_array = (char **)malloc(sizeof(char *) * n_items);
708 buflen = strlen(source) + 1;
709 buffer = (char *)malloc(sizeof(char) * buflen);
710 for (i = 0; i < n_items; i++) {
711 if (SDDS_GetToken(ptr, buffer, buflen) != -1)
712 SDDS_CopyString(&string_array[i], buffer);
713 else
714 SDDS_CopyString(&string_array[i], "");
715 }
716 free(buffer);
717 return string_array;
718}