127 {
128 FILE *outfile = NULL;
135 char **columnRequestList, **columnList;
136 int32_t *columnIndex;
137 long nColumnsRequested, nColumns;
138 char *input, *output;
139 long i, i_arg, ntable;
140 int64_t j, nrows;
141 SCANNED_ARG *s_arg;
142 char *text, *contents, *delimiter, *sheetNameParameter;
143 long verbose = 0, all = 0, nvariableparms = 0, excel = 0, line = 0, units = 0, includeParameters = 1;
144 void *data;
145 unsigned long pipeFlags;
146#ifdef USE_XLS
147 workbook *w = NULL;
148 worksheet *ws = NULL;
149#endif
150 char sheet[256];
151 char buffer[5];
152
154
155 input = output = NULL;
156 delimiter = DELIMITER;
157 pipeFlags = 0;
158 columnRequestList = columnList = NULL;
159 columnDefinition = NULL;
160 columnIndex = NULL;
161 nColumnsRequested = nColumns = 0;
162 sheetNameParameter = NULL;
163
164 argc =
scanargs(&s_arg, argc, argv);
165 if (argc == 1)
167
168 for (i_arg = 1; i_arg < argc; i_arg++) {
169 if (s_arg[i_arg].arg_type == OPTION) {
170 switch (
match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
171 case SET_DELIMITER:
172 if (s_arg[i_arg].n_items < 2)
174 delimiter = s_arg[i_arg].list[1];
175 break;
176
177 case SET_SHEET_NAME_PARAMETER:
178 if (s_arg[i_arg].n_items < 2)
180 sheetNameParameter = s_arg[i_arg].list[1];
181 break;
182
183 case SET_NO_PARAMETERS:
184 includeParameters = 0;
185 break;
186
187 case SET_ALL:
188 all = 1;
189 break;
190
191 case SET_UNITS:
192 units = 1;
193 break;
194
195 case SET_COLUMNS:
196 if (s_arg[i_arg].n_items < 2)
198 columnRequestList = s_arg[i_arg].list + 1;
199 nColumnsRequested = s_arg[i_arg].n_items - 1;
200 break;
201
202 case SET_EXCEL:
203#ifdef USE_XLS
204 excel = 1;
205#else
206 SDDS_Bomb(
"-excel option is not available because sdds2spreadsheet was not compiled with xlslib support");
207#endif
208 break;
209
210 case SET_VERBOSE:
211 verbose = 1;
212 break;
213
214 case SET_PIPE:
215 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
217 break;
218
219 default:
220 fprintf(stderr, "Unknown option: %s\n", s_arg[i_arg].list[0]);
221 exit(EXIT_FAILURE);
222 break;
223 }
224 } else {
225 if (input == NULL)
226 input = s_arg[i_arg].list[0];
227 else if (output == NULL)
228 output = s_arg[i_arg].list[0];
229 else
230 SDDS_Bomb(
"Too many filenames provided.");
231 }
232 }
233
235
236 if (output) {
237 if (!excel) {
238 outfile = fopen(output, "w");
239 if (!outfile) {
240 fprintf(stderr, "Cannot open output file %s\n", output);
241 exit(EXIT_FAILURE);
242 }
243 }
244 } else {
245 if (excel) {
246 SDDS_Bomb(
"-pipe=out and -excel options cannot be used together");
247 }
248 outfile = stdout;
249 }
250
251 if (input && !excel)
252 fprintf(outfile, "Created from SDDS file: %s\n", input);
253
256 exit(EXIT_FAILURE);
257 }
258
259 layout = &SDDS_table.layout;
260
261
262 if (verbose && input)
263 fprintf(stderr, "\nFile %s is in SDDS protocol version %" PRId32 "\n", input, layout->version);
264
267
268 if (text) {
269 if (verbose)
270 fprintf(stderr, "Description: %s\n", text);
271 }
272
273 if (!excel)
274 fprintf(outfile, "%s%s\n", text ? text : "No description", delimiter);
275
276 if (contents) {
277 if (verbose)
278 fprintf(stderr, "Contents: %s\n", contents);
279 }
280
281 if (!excel)
282 fprintf(outfile, "%s%s\n", contents ? contents : "No description", delimiter);
283
284 if (layout->data_mode.mode == SDDS_ASCII) {
285 if (verbose) {
286 fprintf(stderr, "\nData is ASCII with %" PRId32 " lines per row and %" PRId32 " additional header lines expected.\n",
287 layout->data_mode.lines_per_row, layout->data_mode.additional_header_lines);
288 fprintf(stderr, "Row counts: %s\n", layout->data_mode.no_row_counts ? "No" : "Yes");
289 }
290 } else if (verbose) {
291 fprintf(stderr, "\nData is binary\n");
292 }
293
294
295 if (layout->n_columns) {
296 if (nColumnsRequested == 0) {
297 nColumnsRequested = 1;
298 columnRequestList =
tmalloc(
sizeof(*columnRequestList) * 1);
299 columnRequestList[0] =
tmalloc(
sizeof(**columnRequestList) * 2);
300 strcpy(columnRequestList[0], "*");
301 }
302
303 if (verbose) {
304 fprintf(stderr, "\n%" PRId32 " columns of data:\n", layout->n_columns);
305 fprintf(stderr, "NAME UNITS SYMBOL FORMAT TYPE FIELD DESCRIPTION\n");
306 fprintf(stderr, " LENGTH\n");
307 }
308
309 if (all && !excel)
310 fprintf(outfile, "\nColumns%s\nName%sUnits%sSymbol%sFormat%sType%sField Length%sDescription%s\n",
311 delimiter, delimiter, delimiter, delimiter, delimiter, delimiter, delimiter, delimiter);
312
313 for (j = 0; j < nColumnsRequested; j++) {
314 int32_t nc;
315 char **columnName;
316
319
321 columnList =
SDDS_Realloc(columnList,
sizeof(*columnList) * (nColumns + nc));
322 columnDefinition =
SDDS_Realloc(columnDefinition,
sizeof(*columnDefinition) * (nColumns + nc));
323 columnIndex =
SDDS_Realloc(columnIndex,
sizeof(*columnIndex) * (nColumns + nc));
324 for (i = 0; i < nc; i++) {
325 int32_t index;
326
327 columnList[i + nColumns] = columnName[i];
330 exit(EXIT_FAILURE);
331 }
332 columnIndex[i + nColumns] = index;
333 columnDefinition[i + nColumns] = coldef = layout->column_definition + index;
334
335 if (verbose) {
336 fprintf(stderr, "%-15s %-15s %-15s %-15s %-7s %-7" PRId32 " %s\n",
337 coldef->name,
338 coldef->units ? coldef->units : "",
339 coldef->symbol ? coldef->symbol : "",
340 coldef->format_string ? coldef->format_string : "",
342 coldef->field_length,
343 coldef->description ? coldef->description : "");
344 }
345
346 if (all && !excel) {
347 fprintf(outfile, "%s%s%s%s%s%s%s%s%s%s%-7" PRId32 "%s%s%s\n",
348 coldef->name, delimiter,
349 coldef->units ? coldef->units : "", delimiter,
350 coldef->symbol ? coldef->symbol : "", delimiter,
351 coldef->format_string ? coldef->format_string : "", delimiter,
353 coldef->field_length, delimiter,
354 coldef->description ? coldef->description : "", delimiter);
355 }
356 }
357 free(columnName);
358 nColumns += nc;
359 }
360 }
361 }
362
363
364 if (layout->n_parameters && includeParameters) {
365 if (verbose) {
366 fprintf(stderr, "\n%" PRId32 " parameters:\n", layout->n_parameters);
367 fprintf(stderr, "NAME UNITS SYMBOL TYPE DESCRIPTION\n");
368 }
369
370 if (all && !excel)
371 fprintf(outfile, "\nParameters%s\nName%sFixedValue%sUnits%sSymbol%sType%sDescription%s\n",
372 delimiter, delimiter, delimiter, delimiter, delimiter, delimiter, delimiter);
373
374 for (i = 0; i < layout->n_parameters; i++) {
375 pardef = layout->parameter_definition + i;
376
377 if (!pardef->fixed_value) {
378 nvariableparms++;
379 if (!all)
380 continue;
381 }
382
383 if (verbose) {
384 fprintf(stderr, "%-19s %-19s %-19s %-19s %s\n",
385 pardef->name,
386 pardef->units ? pardef->units : "",
387 pardef->symbol ? pardef->symbol : "",
389 pardef->description ? pardef->description : "");
390 }
391
392 if (!excel) {
393 if (all) {
394 fprintf(outfile, "%s%s%s%s%s%s%s%s%s%s%s%s\n",
395 pardef->name, delimiter,
396 pardef->fixed_value ? pardef->fixed_value : "", delimiter,
397 pardef->units ? pardef->units : "", delimiter,
398 pardef->symbol ? pardef->symbol : "", delimiter,
400 pardef->description ? pardef->description : "", delimiter);
401 } else {
402 fprintf(outfile, "%s%s%s%s%s\n",
403 pardef->name, delimiter, delimiter,
404 pardef->fixed_value ? pardef->fixed_value : "", delimiter);
405 }
406 }
407 }
408 }
409
410
411 if (layout->n_arrays && all) {
412 if (verbose) {
413 fprintf(stderr, "\n%" PRId32 " arrays of data:\n", layout->n_arrays);
414 fprintf(stderr, "NAME UNITS SYMBOL FORMAT TYPE FIELD GROUP DESCRIPTION\n");
415 fprintf(stderr, " LENGTH NAME\n");
416 }
417
418 if (!excel) {
419 fprintf(outfile, "\nArrays%s\nName%sUnits%sSymbol%sFormat%sType%sField Length%sGroup Name%sDescription%s\n",
420 delimiter, delimiter, delimiter, delimiter, delimiter, delimiter, delimiter, delimiter, delimiter);
421 }
422
423 for (i = 0; i < layout->n_arrays; i++) {
424 arraydef = layout->array_definition + i;
425
426 if (verbose) {
427 fprintf(stderr, "%-15s %-15s %-15s %-7s %-8s*^%-5" PRId32 " %-7" PRId32 " %-15s %s\n",
428 arraydef->name,
429 arraydef->units,
430 arraydef->symbol,
431 arraydef->format_string,
433 arraydef->dimensions,
434 arraydef->field_length,
435 arraydef->group_name,
436 arraydef->description);
437 }
438
439 if (!excel) {
440 fprintf(outfile, "%s%s%s%s%s%s%s%s%s*^%-5" PRId32 "%s%-7" PRId32 "%s%s%s%s%s\n",
441 arraydef->name, delimiter,
442 arraydef->units, delimiter,
443 arraydef->symbol, delimiter,
444 arraydef->format_string, delimiter,
446 arraydef->dimensions, delimiter,
447 arraydef->field_length, delimiter,
448 arraydef->group_name, delimiter,
449 arraydef->description, delimiter);
450 }
451 }
452 }
453
454#ifdef USE_XLS
455 if (excel) {
456 w = xlsNewWorkbook();
457 }
458# ifdef __APPLE__
459
460# endif
461#endif
462
463
464 while ((ntable = SDDS_ReadTable(&SDDS_table)) > 0) {
465 line = 0;
466#ifdef USE_XLS
467 if (excel) {
468 if (!sheetNameParameter) {
469 sprintf(sheet, "Sheet%ld", ntable);
470 ws = xlsWorkbookSheet(w, sheet);
471 } else {
472 char *name;
475 ws = xlsWorkbookSheet(w, name);
476 free(name);
477 }
478 } else {
479 fprintf(outfile, "\nTable %ld\n", ntable);
480 }
481#else
482 fprintf(outfile, "\nTable %ld\n", ntable);
483#endif
484
485
486 if (nvariableparms && includeParameters) {
487 for (i = 0; i < layout->n_parameters; i++) {
488 pardef = layout->parameter_definition + i;
489
490 if (pardef->fixed_value)
491 continue;
492
493 data = SDDS_table.parameter[i];
494 if (!data) {
496 exit(EXIT_FAILURE);
497 }
498
499#ifdef USE_XLS
500 if (excel) {
501 xlsWorksheetLabel(ws, line, 0, pardef->name, NULL);
502 switch (pardef->type) {
504 xlsWorksheetNumberDbl(ws, line, 1, *((long double *)data), NULL);
505 break;
507 xlsWorksheetNumberDbl(ws, line, 1, *((double *)data), NULL);
508 break;
510 xlsWorksheetNumberDbl(ws, line, 1, *((float *)data), NULL);
511 break;
513 xlsWorksheetNumberInt(ws, line, 1, *((uint64_t *)data), NULL);
514 break;
516 xlsWorksheetNumberInt(ws, line, 1, *((int64_t *)data), NULL);
517 break;
519 xlsWorksheetNumberInt(ws, line, 1, *((uint32_t *)data), NULL);
520 break;
522 xlsWorksheetNumberInt(ws, line, 1, *((int32_t *)data), NULL);
523 break;
525 xlsWorksheetNumberInt(ws, line, 1, *((unsigned short *)data), NULL);
526 break;
528 xlsWorksheetNumberInt(ws, line, 1, *((short *)data), NULL);
529 break;
531 xlsWorksheetLabel(ws, line, 1, *((char **)data), NULL);
532 break;
534 sprintf(buffer, "%c", *((char *)data));
535 xlsWorksheetLabel(ws, line, 1, buffer, NULL);
536 break;
537 default:
538 break;
539 }
540 line++;
541 } else {
542#endif
543 fprintf(outfile, "%s%s%s", pardef->name, delimiter, delimiter);
545 fprintf(outfile, "%s\n", delimiter);
546#ifdef USE_XLS
547 }
548#endif
549 }
550 line++;
551 }
552
553
554 if (nColumns) {
555 nrows = SDDS_table.n_rows;
556
557 for (i = 0; i < nColumns; i++) {
558 coldef = columnDefinition[i];
559#ifdef USE_XLS
560 if (excel) {
561 xlsWorksheetLabel(ws, line, i, coldef->name, NULL);
562 } else {
563 fprintf(outfile, "%s%s", coldef->name, delimiter);
564 }
565#else
566 fprintf(outfile, "%s%s", coldef->name, delimiter);
567#endif
568 }
569 line++;
570 if (!excel)
571 fprintf(outfile, "\n");
572
573 if (units) {
574 for (i = 0; i < nColumns; i++) {
575 coldef = columnDefinition[i];
576#ifdef USE_XLS
577 if (excel) {
578 xlsWorksheetLabel(ws, line, i, coldef->units ? coldef->units : "", NULL);
579 } else {
580 fprintf(outfile, "%s%s", coldef->units ? coldef->units : "", delimiter);
581 }
582#else
583 fprintf(outfile, "%s%s", coldef->units ? coldef->units : "", delimiter);
584#endif
585 }
586 line++;
587 if (!excel)
588 fprintf(outfile, "\n");
589 }
590
591 if (nrows) {
592 for (j = 0; j < nrows; j++) {
593 for (i = 0; i < nColumns; i++) {
594 coldef = columnDefinition[i];
595 data = SDDS_table.data[columnIndex[i]];
596 if (!data) {
598 exit(EXIT_FAILURE);
599 }
600
601#ifdef USE_XLS
602 if (excel) {
603 switch (coldef->type) {
605 xlsWorksheetNumberDbl(ws, line, i, ((long double *)data)[j], NULL);
606 break;
608 xlsWorksheetNumberDbl(ws, line, i, ((double *)data)[j], NULL);
609 break;
611 xlsWorksheetNumberDbl(ws, line, i, ((float *)data)[j], NULL);
612 break;
614 xlsWorksheetNumberInt(ws, line, i, ((uint64_t *)data)[j], NULL);
615 break;
617 xlsWorksheetNumberInt(ws, line, i, ((int64_t *)data)[j], NULL);
618 break;
620 xlsWorksheetNumberInt(ws, line, i, ((uint32_t *)data)[j], NULL);
621 break;
623 xlsWorksheetNumberInt(ws, line, i, ((int32_t *)data)[j], NULL);
624 break;
626 xlsWorksheetNumberInt(ws, line, i, ((unsigned short *)data)[j], NULL);
627 break;
629 xlsWorksheetNumberInt(ws, line, i, ((short *)data)[j], NULL);
630 break;
632 xlsWorksheetLabel(ws, line, i, ((char **)data)[j], NULL);
633 break;
635 sprintf(buffer, "%c", ((char *)data)[j]);
636 xlsWorksheetLabel(ws, line, i, buffer, NULL);
637 break;
638 default:
639 break;
640 }
641 } else {
642#endif
643 switch (coldef->type) {
645 fprintf(outfile, "%.*g", DBL_DIG, ((double *)data)[j]);
646 break;
648 fprintf(outfile, "%.*g", FLT_DIG, ((float *)data)[j]);
649 break;
650 default:
652 break;
653 }
654 fprintf(outfile, "%s", delimiter);
655#ifdef USE_XLS
656 }
657#endif
658 }
659 if (!excel)
660 fprintf(outfile, "\n");
661 line++;
662 }
663 }
664 }
665 }
666
667#ifdef USE_XLS
668 if (excel) {
669 xlsWorkbookDump(w, output);
670 xlsDeleteWorkbook(w);
671 }
672#endif
673
674 for (i = 0; i < nColumns; i++)
675 free(columnList[i]);
676 free(columnList);
677 free(columnDefinition);
678 free(columnIndex);
679
680
681 fflush(stdout);
684 exit(EXIT_FAILURE);
685 }
686
687 return EXIT_SUCCESS;
688}
char * SDDS_type_name[SDDS_NUM_TYPES]
Array of supported data type names.
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
char ** SDDS_GetColumnNames(SDDS_DATASET *SDDS_dataset, int32_t *number)
Retrieves the names of all columns in the SDDS dataset.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
int32_t SDDS_PrintTypedValue(void *data, int64_t index, int32_t type, char *format, FILE *fp, uint32_t mode)
Prints a data value of a specified type using an optional printf format string.
#define SDDS_ULONG
Identifier for the unsigned 32-bit integer data type.
#define SDDS_FLOAT
Identifier for the float data type.
#define SDDS_STRING
Identifier for the string data type.
#define SDDS_ULONG64
Identifier for the unsigned 64-bit integer data type.
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
#define SDDS_SHORT
Identifier for the signed short integer data type.
#define SDDS_CHARACTER
Identifier for the character data type.
#define SDDS_USHORT
Identifier for the unsigned short integer data type.
#define SDDS_DOUBLE
Identifier for the double data type.
#define SDDS_LONGDOUBLE
Identifier for the long double data type.
#define SDDS_LONG64
Identifier for the signed 64-bit integer data 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.
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)
long processPipeOption(char **item, long items, unsigned long *flags)
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)