41# include "common/xlconfig.h"
53# include "common/systype.h"
65 SET_SHEET_NAME_PARAMETER,
72char *option[N_OPTIONS] = {
85 " sdds2spreadsheet [<SDDSfilename>] [<outputname>] "
86 "[-pipe[=in][,out]]\n"
87 " [-column=<listOfColumns>] [-units] [-noParameters]\n"
88 " [-delimiter=<delimiting-string>] [-all] [-verbose]\n"
89 " [-excel [-sheetName=<parameterName>]]\n"
91 " -pipe Use standard SDDS toolkit pipe option.\n"
92 " -excel Write output in XLS Excel format.\n"
93 " -column Specify a comma-separated list of columns to include (default is all).\n"
94 " -units Include a row of units below the column names.\n"
95 " -noParameters Suppress the output of parameter data.\n"
96 " -sheetName Use the specified parameter to name each Excel sheet.\n"
97 " -delimiter Define a custom delimiter string (default is \"\\t\").\n"
98 " -all Include parameter, column, and array information.\n"
99 " -verbose Output detailed header information to the terminal.\n"
101 " - Excel 4.0 lines must be shorter than 255 characters.\n"
102 " - Wingz delimiter can only be \"\\t\"\n"
103 "\nProgram by Kenneth Evans. (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")\n";
105int main(
int argc,
char **argv) {
106 FILE *outfile = NULL;
112 char **columnRequestList, **columnList;
113 long nColumnsRequested, nColumns;
114 char *input, *output;
115 long i, i_arg, ntable;
118 char *text, *contents, *delimiter, *sheetNameParameter;
119 long verbose = 0, all = 0, nvariableparms = 0, excel = 0, line = 0, units = 0, includeParameters = 1;
121 unsigned long pipeFlags;
124 worksheet *ws = NULL;
131 input = output = NULL;
132 delimiter = DELIMITER;
134 columnRequestList = columnList = NULL;
135 nColumnsRequested = nColumns = 0;
136 sheetNameParameter = NULL;
138 argc =
scanargs(&s_arg, argc, argv);
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)) {
146 if (s_arg[i_arg].n_items < 2)
148 delimiter = s_arg[i_arg].list[1];
151 case SET_SHEET_NAME_PARAMETER:
152 if (s_arg[i_arg].n_items < 2)
154 sheetNameParameter = s_arg[i_arg].list[1];
157 case SET_NO_PARAMETERS:
158 includeParameters = 0;
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;
180 SDDS_Bomb(
"-excel option is not available because sdds2spreadsheet was not compiled with xlslib support");
189 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
194 fprintf(stderr,
"Unknown option: %s\n", s_arg[i_arg].list[0]);
200 input = s_arg[i_arg].list[0];
201 else if (output == NULL)
202 output = s_arg[i_arg].list[0];
204 SDDS_Bomb(
"Too many filenames provided.");
212 outfile = fopen(output,
"w");
214 fprintf(stderr,
"Cannot open output file %s\n", output);
220 SDDS_Bomb(
"-pipe=out and -excel options cannot be used together");
226 fprintf(outfile,
"Created from SDDS file: %s\n", input);
233 layout = &SDDS_table.layout;
236 if (verbose && input)
237 fprintf(stderr,
"\nFile %s is in SDDS protocol version %" PRId32
"\n", input, layout->version);
244 fprintf(stderr,
"Description: %s\n", text);
248 fprintf(outfile,
"%s%s\n", text ? text :
"No description", delimiter);
252 fprintf(stderr,
"Contents: %s\n", contents);
256 fprintf(outfile,
"%s%s\n", contents ? contents :
"No description", delimiter);
258 if (layout->data_mode.mode == SDDS_ASCII) {
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");
264 }
else if (verbose) {
265 fprintf(stderr,
"\nData is binary\n");
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],
"*");
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");
284 fprintf(outfile,
"\nColumns%s\nName%sUnits%sSymbol%sFormat%sType%sField Length%sDescription%s\n",
285 delimiter, delimiter, delimiter, delimiter, delimiter, delimiter, delimiter, delimiter);
287 for (j = 0; j < nColumnsRequested; j++) {
295 columnList =
SDDS_Realloc(columnList,
sizeof(*columnList) * (nColumns + nc));
296 for (i = 0; i < nc; i++) {
297 columnList[i + nColumns] = columnName[i];
301 fprintf(stderr,
"%-15s %-15s %-15s %-15s %-7s %-7" PRId32
" %s\n",
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 :
"");
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);
328 if (layout->n_parameters && includeParameters) {
330 fprintf(stderr,
"\n%" PRId32
" parameters:\n", layout->n_parameters);
331 fprintf(stderr,
"NAME UNITS SYMBOL TYPE DESCRIPTION\n");
335 fprintf(outfile,
"\nParameters%s\nName%sFixedValue%sUnits%sSymbol%sType%sDescription%s\n",
336 delimiter, delimiter, delimiter, delimiter, delimiter, delimiter, delimiter);
338 for (i = 0; i < layout->n_parameters; i++) {
339 pardef = layout->parameter_definition + i;
341 if (!pardef->fixed_value) {
348 fprintf(stderr,
"%-19s %-19s %-19s %-19s %s\n",
350 pardef->units ? pardef->units :
"",
351 pardef->symbol ? pardef->symbol :
"",
353 pardef->description ? pardef->description :
"");
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);
366 fprintf(outfile,
"%s%s%s%s%s\n",
367 pardef->name, delimiter, delimiter,
368 pardef->fixed_value ? pardef->fixed_value :
"", delimiter);
375 if (layout->n_arrays && all) {
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");
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);
387 for (i = 0; i < layout->n_arrays; i++) {
388 arraydef = layout->array_definition + i;
391 fprintf(stderr,
"%-15s %-15s %-15s %-7s %-8s*^%-5" PRId32
" %-7" PRId32
" %-15s %s\n",
395 arraydef->format_string,
397 arraydef->dimensions,
398 arraydef->field_length,
399 arraydef->group_name,
400 arraydef->description);
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);
420 w = xlsNewWorkbook();
428 while ((ntable = SDDS_ReadTable(&SDDS_table)) > 0) {
432 if (!sheetNameParameter) {
433 sprintf(sheet,
"Sheet%ld", ntable);
434 ws = xlsWorkbookSheet(w, sheet);
439 ws = xlsWorkbookSheet(w, name);
443 fprintf(outfile,
"\nTable %ld\n", ntable);
446 fprintf(outfile,
"\nTable %ld\n", ntable);
450 if (nvariableparms && includeParameters) {
451 for (i = 0; i < layout->n_parameters; i++) {
452 pardef = layout->parameter_definition + i;
454 if (pardef->fixed_value)
465 xlsWorksheetLabel(ws, line, 0, pardef->name, NULL);
466 switch (pardef->type) {
468 xlsWorksheetNumberDbl(ws, line, 1, *((
long double *)data), NULL);
471 xlsWorksheetNumberDbl(ws, line, 1, *((
double *)data), NULL);
474 xlsWorksheetNumberDbl(ws, line, 1, *((
float *)data), NULL);
477 xlsWorksheetNumberInt(ws, line, 1, *((uint64_t *)data), NULL);
480 xlsWorksheetNumberInt(ws, line, 1, *((int64_t *)data), NULL);
483 xlsWorksheetNumberInt(ws, line, 1, *((uint32_t *)data), NULL);
486 xlsWorksheetNumberInt(ws, line, 1, *((int32_t *)data), NULL);
489 xlsWorksheetNumberInt(ws, line, 1, *((
unsigned short *)data), NULL);
492 xlsWorksheetNumberInt(ws, line, 1, *((
short *)data), NULL);
495 xlsWorksheetLabel(ws, line, 1, *((
char **)data), NULL);
498 sprintf(buffer,
"%c", *((
char *)data));
499 xlsWorksheetLabel(ws, line, 1, buffer, NULL);
507 fprintf(outfile,
"%s%s%s", pardef->name, delimiter, delimiter);
509 fprintf(outfile,
"%s\n", delimiter);
526 for (i = 0; i < nColumns; i++) {
530 xlsWorksheetLabel(ws, line, i, coldef->name, NULL);
532 fprintf(outfile,
"%s%s", coldef->name, delimiter);
535 fprintf(outfile,
"%s%s", coldef->name, delimiter);
540 fprintf(outfile,
"\n");
543 for (i = 0; i < nColumns; i++) {
547 xlsWorksheetLabel(ws, line, i, coldef->units ? coldef->units :
"", NULL);
549 fprintf(outfile,
"%s%s", coldef->units ? coldef->units :
"", delimiter);
552 fprintf(outfile,
"%s%s", coldef->units ? coldef->units :
"", delimiter);
557 fprintf(outfile,
"\n");
561 for (j = 0; j < nrows; j++) {
562 for (i = 0; i < nColumns; i++) {
572 switch (coldef->type) {
574 xlsWorksheetNumberDbl(ws, line, i, *((
long double *)data), NULL);
577 xlsWorksheetNumberDbl(ws, line, i, *((
double *)data), NULL);
580 xlsWorksheetNumberDbl(ws, line, i, *((
float *)data), NULL);
583 xlsWorksheetNumberInt(ws, line, i, *((uint64_t *)data), NULL);
586 xlsWorksheetNumberInt(ws, line, i, *((int64_t *)data), NULL);
589 xlsWorksheetNumberInt(ws, line, i, *((uint32_t *)data), NULL);
592 xlsWorksheetNumberInt(ws, line, i, *((int32_t *)data), NULL);
595 xlsWorksheetNumberInt(ws, line, i, *((
unsigned short *)data), NULL);
598 xlsWorksheetNumberInt(ws, line, i, *((
short *)data), NULL);
601 xlsWorksheetLabel(ws, line, i, *((
char **)data), NULL);
604 sprintf(buffer,
"%c", *((
char *)data));
605 xlsWorksheetLabel(ws, line, i, buffer, NULL);
612 switch (coldef->type) {
614 fprintf(outfile,
"%.*g", DBL_DIG, *((
double *)data));
617 fprintf(outfile,
"%.*g", FLT_DIG, *((
float *)data));
623 fprintf(outfile,
"%s", delimiter);
629 fprintf(outfile,
"\n");
638 xlsWorkbookDump(w, output);
639 xlsDeleteWorkbook(w);
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
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)