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