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