58# include "common/xlconfig.h"
70# include "common/systype.h"
82 SET_SHEET_NAME_PARAMETER,
89char *option[N_OPTIONS] = {
102 " sdds2spreadsheet [<SDDSfilename>] [<outputname>]\n"
103 " [-pipe[=in][,out]]\n"
104 " [-column=<listOfColumns>]\n"
107 " [-delimiter=<delimiting-string>]\n"
111 " [-sheetName=<parameterName>]\n"
113 " -pipe Use standard SDDS toolkit pipe option.\n"
114 " -excel Write output in XLS Excel format.\n"
115 " -column Specify a comma-separated list of columns to include (default is all).\n"
116 " -units Include a row of units below the column names.\n"
117 " -noParameters Suppress the output of parameter data.\n"
118 " -sheetName Use the specified parameter to name each Excel sheet.\n"
119 " -delimiter Define a custom delimiter string (default is \"\\t\").\n"
120 " -all Include parameter, column, and array information.\n"
121 " -verbose Output detailed header information to the terminal.\n"
123 " - Excel 4.0 lines must be shorter than 255 characters.\n"
124 " - Wingz delimiter can only be \"\\t\"\n"
125 "\nProgram by Kenneth Evans. (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")\n";
127int main(
int argc,
char **argv) {
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;
142 char *text, *contents, *delimiter, *sheetNameParameter;
143 long verbose = 0, all = 0, nvariableparms = 0, excel = 0, line = 0, units = 0, includeParameters = 1;
145 unsigned long pipeFlags;
148 worksheet *ws = NULL;
155 input = output = NULL;
156 delimiter = DELIMITER;
158 columnRequestList = columnList = NULL;
159 columnDefinition = NULL;
161 nColumnsRequested = nColumns = 0;
162 sheetNameParameter = NULL;
164 argc =
scanargs(&s_arg, argc, argv);
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)) {
172 if (s_arg[i_arg].n_items < 2)
174 delimiter = s_arg[i_arg].list[1];
177 case SET_SHEET_NAME_PARAMETER:
178 if (s_arg[i_arg].n_items < 2)
180 sheetNameParameter = s_arg[i_arg].list[1];
183 case SET_NO_PARAMETERS:
184 includeParameters = 0;
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;
206 SDDS_Bomb(
"-excel option is not available because sdds2spreadsheet was not compiled with xlslib support");
215 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
220 fprintf(stderr,
"Unknown option: %s\n", s_arg[i_arg].list[0]);
226 input = s_arg[i_arg].list[0];
227 else if (output == NULL)
228 output = s_arg[i_arg].list[0];
230 SDDS_Bomb(
"Too many filenames provided.");
238 outfile = fopen(output,
"w");
240 fprintf(stderr,
"Cannot open output file %s\n", output);
246 SDDS_Bomb(
"-pipe=out and -excel options cannot be used together");
252 fprintf(outfile,
"Created from SDDS file: %s\n", input);
259 layout = &SDDS_table.layout;
262 if (verbose && input)
263 fprintf(stderr,
"\nFile %s is in SDDS protocol version %" PRId32
"\n", input, layout->version);
270 fprintf(stderr,
"Description: %s\n", text);
274 fprintf(outfile,
"%s%s\n", text ? text :
"No description", delimiter);
278 fprintf(stderr,
"Contents: %s\n", contents);
282 fprintf(outfile,
"%s%s\n", contents ? contents :
"No description", delimiter);
284 if (layout->data_mode.mode == SDDS_ASCII) {
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");
290 }
else if (verbose) {
291 fprintf(stderr,
"\nData is binary\n");
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],
"*");
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");
310 fprintf(outfile,
"\nColumns%s\nName%sUnits%sSymbol%sFormat%sType%sField Length%sDescription%s\n",
311 delimiter, delimiter, delimiter, delimiter, delimiter, delimiter, delimiter, delimiter);
313 for (j = 0; j < nColumnsRequested; j++) {
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++) {
327 columnList[i + nColumns] = columnName[i];
332 columnIndex[i + nColumns] = index;
333 columnDefinition[i + nColumns] = coldef = layout->column_definition + index;
336 fprintf(stderr,
"%-15s %-15s %-15s %-15s %-7s %-7" PRId32
" %s\n",
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 :
"");
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);
364 if (layout->n_parameters && includeParameters) {
366 fprintf(stderr,
"\n%" PRId32
" parameters:\n", layout->n_parameters);
367 fprintf(stderr,
"NAME UNITS SYMBOL TYPE DESCRIPTION\n");
371 fprintf(outfile,
"\nParameters%s\nName%sFixedValue%sUnits%sSymbol%sType%sDescription%s\n",
372 delimiter, delimiter, delimiter, delimiter, delimiter, delimiter, delimiter);
374 for (i = 0; i < layout->n_parameters; i++) {
375 pardef = layout->parameter_definition + i;
377 if (!pardef->fixed_value) {
384 fprintf(stderr,
"%-19s %-19s %-19s %-19s %s\n",
386 pardef->units ? pardef->units :
"",
387 pardef->symbol ? pardef->symbol :
"",
389 pardef->description ? pardef->description :
"");
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);
402 fprintf(outfile,
"%s%s%s%s%s\n",
403 pardef->name, delimiter, delimiter,
404 pardef->fixed_value ? pardef->fixed_value :
"", delimiter);
411 if (layout->n_arrays && all) {
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");
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);
423 for (i = 0; i < layout->n_arrays; i++) {
424 arraydef = layout->array_definition + i;
427 fprintf(stderr,
"%-15s %-15s %-15s %-7s %-8s*^%-5" PRId32
" %-7" PRId32
" %-15s %s\n",
431 arraydef->format_string,
433 arraydef->dimensions,
434 arraydef->field_length,
435 arraydef->group_name,
436 arraydef->description);
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);
456 w = xlsNewWorkbook();
464 while ((ntable = SDDS_ReadTable(&SDDS_table)) > 0) {
468 if (!sheetNameParameter) {
469 sprintf(sheet,
"Sheet%ld", ntable);
470 ws = xlsWorkbookSheet(w, sheet);
475 ws = xlsWorkbookSheet(w, name);
479 fprintf(outfile,
"\nTable %ld\n", ntable);
482 fprintf(outfile,
"\nTable %ld\n", ntable);
486 if (nvariableparms && includeParameters) {
487 for (i = 0; i < layout->n_parameters; i++) {
488 pardef = layout->parameter_definition + i;
490 if (pardef->fixed_value)
493 data = SDDS_table.parameter[i];
501 xlsWorksheetLabel(ws, line, 0, pardef->name, NULL);
502 switch (pardef->type) {
504 xlsWorksheetNumberDbl(ws, line, 1, *((
long double *)data), NULL);
507 xlsWorksheetNumberDbl(ws, line, 1, *((
double *)data), NULL);
510 xlsWorksheetNumberDbl(ws, line, 1, *((
float *)data), NULL);
513 xlsWorksheetNumberInt(ws, line, 1, *((uint64_t *)data), NULL);
516 xlsWorksheetNumberInt(ws, line, 1, *((int64_t *)data), NULL);
519 xlsWorksheetNumberInt(ws, line, 1, *((uint32_t *)data), NULL);
522 xlsWorksheetNumberInt(ws, line, 1, *((int32_t *)data), NULL);
525 xlsWorksheetNumberInt(ws, line, 1, *((
unsigned short *)data), NULL);
528 xlsWorksheetNumberInt(ws, line, 1, *((
short *)data), NULL);
531 xlsWorksheetLabel(ws, line, 1, *((
char **)data), NULL);
534 sprintf(buffer,
"%c", *((
char *)data));
535 xlsWorksheetLabel(ws, line, 1, buffer, NULL);
543 fprintf(outfile,
"%s%s%s", pardef->name, delimiter, delimiter);
545 fprintf(outfile,
"%s\n", delimiter);
555 nrows = SDDS_table.n_rows;
557 for (i = 0; i < nColumns; i++) {
558 coldef = columnDefinition[i];
561 xlsWorksheetLabel(ws, line, i, coldef->name, NULL);
563 fprintf(outfile,
"%s%s", coldef->name, delimiter);
566 fprintf(outfile,
"%s%s", coldef->name, delimiter);
571 fprintf(outfile,
"\n");
574 for (i = 0; i < nColumns; i++) {
575 coldef = columnDefinition[i];
578 xlsWorksheetLabel(ws, line, i, coldef->units ? coldef->units :
"", NULL);
580 fprintf(outfile,
"%s%s", coldef->units ? coldef->units :
"", delimiter);
583 fprintf(outfile,
"%s%s", coldef->units ? coldef->units :
"", delimiter);
588 fprintf(outfile,
"\n");
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]];
603 switch (coldef->type) {
605 xlsWorksheetNumberDbl(ws, line, i, ((
long double *)data)[j], NULL);
608 xlsWorksheetNumberDbl(ws, line, i, ((
double *)data)[j], NULL);
611 xlsWorksheetNumberDbl(ws, line, i, ((
float *)data)[j], NULL);
614 xlsWorksheetNumberInt(ws, line, i, ((uint64_t *)data)[j], NULL);
617 xlsWorksheetNumberInt(ws, line, i, ((int64_t *)data)[j], NULL);
620 xlsWorksheetNumberInt(ws, line, i, ((uint32_t *)data)[j], NULL);
623 xlsWorksheetNumberInt(ws, line, i, ((int32_t *)data)[j], NULL);
626 xlsWorksheetNumberInt(ws, line, i, ((
unsigned short *)data)[j], NULL);
629 xlsWorksheetNumberInt(ws, line, i, ((
short *)data)[j], NULL);
632 xlsWorksheetLabel(ws, line, i, ((
char **)data)[j], NULL);
635 sprintf(buffer,
"%c", ((
char *)data)[j]);
636 xlsWorksheetLabel(ws, line, i, buffer, NULL);
643 switch (coldef->type) {
645 fprintf(outfile,
"%.*g", DBL_DIG, ((
double *)data)[j]);
648 fprintf(outfile,
"%.*g", FLT_DIG, ((
float *)data)[j]);
654 fprintf(outfile,
"%s", delimiter);
660 fprintf(outfile,
"\n");
669 xlsWorkbookDump(w, output);
670 xlsDeleteWorkbook(w);
674 for (i = 0; i < nColumns; i++)
677 free(columnDefinition);
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
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)