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;
134 char **columnRequestList, **columnList;
135 long nColumnsRequested, nColumns;
136 char *input, *output;
137 long i, i_arg, ntable;
140 char *text, *contents, *delimiter, *sheetNameParameter;
141 long verbose = 0, all = 0, nvariableparms = 0, excel = 0, line = 0, units = 0, includeParameters = 1;
143 unsigned long pipeFlags;
146 worksheet *ws = NULL;
153 input = output = NULL;
154 delimiter = DELIMITER;
156 columnRequestList = columnList = NULL;
157 nColumnsRequested = nColumns = 0;
158 sheetNameParameter = NULL;
160 argc =
scanargs(&s_arg, argc, argv);
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)) {
168 if (s_arg[i_arg].n_items < 2)
170 delimiter = s_arg[i_arg].list[1];
173 case SET_SHEET_NAME_PARAMETER:
174 if (s_arg[i_arg].n_items < 2)
176 sheetNameParameter = s_arg[i_arg].list[1];
179 case SET_NO_PARAMETERS:
180 includeParameters = 0;
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;
202 SDDS_Bomb(
"-excel option is not available because sdds2spreadsheet was not compiled with xlslib support");
211 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
216 fprintf(stderr,
"Unknown option: %s\n", s_arg[i_arg].list[0]);
222 input = s_arg[i_arg].list[0];
223 else if (output == NULL)
224 output = s_arg[i_arg].list[0];
226 SDDS_Bomb(
"Too many filenames provided.");
234 outfile = fopen(output,
"w");
236 fprintf(stderr,
"Cannot open output file %s\n", output);
242 SDDS_Bomb(
"-pipe=out and -excel options cannot be used together");
248 fprintf(outfile,
"Created from SDDS file: %s\n", input);
255 layout = &SDDS_table.layout;
258 if (verbose && input)
259 fprintf(stderr,
"\nFile %s is in SDDS protocol version %" PRId32
"\n", input, layout->version);
266 fprintf(stderr,
"Description: %s\n", text);
270 fprintf(outfile,
"%s%s\n", text ? text :
"No description", delimiter);
274 fprintf(stderr,
"Contents: %s\n", contents);
278 fprintf(outfile,
"%s%s\n", contents ? contents :
"No description", delimiter);
280 if (layout->data_mode.mode == SDDS_ASCII) {
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");
286 }
else if (verbose) {
287 fprintf(stderr,
"\nData is binary\n");
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],
"*");
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");
306 fprintf(outfile,
"\nColumns%s\nName%sUnits%sSymbol%sFormat%sType%sField Length%sDescription%s\n",
307 delimiter, delimiter, delimiter, delimiter, delimiter, delimiter, delimiter, delimiter);
309 for (j = 0; j < nColumnsRequested; j++) {
317 columnList =
SDDS_Realloc(columnList,
sizeof(*columnList) * (nColumns + nc));
318 for (i = 0; i < nc; i++) {
319 columnList[i + nColumns] = columnName[i];
323 fprintf(stderr,
"%-15s %-15s %-15s %-15s %-7s %-7" PRId32
" %s\n",
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 :
"");
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);
350 if (layout->n_parameters && includeParameters) {
352 fprintf(stderr,
"\n%" PRId32
" parameters:\n", layout->n_parameters);
353 fprintf(stderr,
"NAME UNITS SYMBOL TYPE DESCRIPTION\n");
357 fprintf(outfile,
"\nParameters%s\nName%sFixedValue%sUnits%sSymbol%sType%sDescription%s\n",
358 delimiter, delimiter, delimiter, delimiter, delimiter, delimiter, delimiter);
360 for (i = 0; i < layout->n_parameters; i++) {
361 pardef = layout->parameter_definition + i;
363 if (!pardef->fixed_value) {
370 fprintf(stderr,
"%-19s %-19s %-19s %-19s %s\n",
372 pardef->units ? pardef->units :
"",
373 pardef->symbol ? pardef->symbol :
"",
375 pardef->description ? pardef->description :
"");
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);
388 fprintf(outfile,
"%s%s%s%s%s\n",
389 pardef->name, delimiter, delimiter,
390 pardef->fixed_value ? pardef->fixed_value :
"", delimiter);
397 if (layout->n_arrays && all) {
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");
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);
409 for (i = 0; i < layout->n_arrays; i++) {
410 arraydef = layout->array_definition + i;
413 fprintf(stderr,
"%-15s %-15s %-15s %-7s %-8s*^%-5" PRId32
" %-7" PRId32
" %-15s %s\n",
417 arraydef->format_string,
419 arraydef->dimensions,
420 arraydef->field_length,
421 arraydef->group_name,
422 arraydef->description);
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);
442 w = xlsNewWorkbook();
450 while ((ntable = SDDS_ReadTable(&SDDS_table)) > 0) {
454 if (!sheetNameParameter) {
455 sprintf(sheet,
"Sheet%ld", ntable);
456 ws = xlsWorkbookSheet(w, sheet);
461 ws = xlsWorkbookSheet(w, name);
465 fprintf(outfile,
"\nTable %ld\n", ntable);
468 fprintf(outfile,
"\nTable %ld\n", ntable);
472 if (nvariableparms && includeParameters) {
473 for (i = 0; i < layout->n_parameters; i++) {
474 pardef = layout->parameter_definition + i;
476 if (pardef->fixed_value)
487 xlsWorksheetLabel(ws, line, 0, pardef->name, NULL);
488 switch (pardef->type) {
490 xlsWorksheetNumberDbl(ws, line, 1, *((
long double *)data), NULL);
493 xlsWorksheetNumberDbl(ws, line, 1, *((
double *)data), NULL);
496 xlsWorksheetNumberDbl(ws, line, 1, *((
float *)data), NULL);
499 xlsWorksheetNumberInt(ws, line, 1, *((uint64_t *)data), NULL);
502 xlsWorksheetNumberInt(ws, line, 1, *((int64_t *)data), NULL);
505 xlsWorksheetNumberInt(ws, line, 1, *((uint32_t *)data), NULL);
508 xlsWorksheetNumberInt(ws, line, 1, *((int32_t *)data), NULL);
511 xlsWorksheetNumberInt(ws, line, 1, *((
unsigned short *)data), NULL);
514 xlsWorksheetNumberInt(ws, line, 1, *((
short *)data), NULL);
517 xlsWorksheetLabel(ws, line, 1, *((
char **)data), NULL);
520 sprintf(buffer,
"%c", *((
char *)data));
521 xlsWorksheetLabel(ws, line, 1, buffer, NULL);
529 fprintf(outfile,
"%s%s%s", pardef->name, delimiter, delimiter);
531 fprintf(outfile,
"%s\n", delimiter);
548 for (i = 0; i < nColumns; i++) {
552 xlsWorksheetLabel(ws, line, i, coldef->name, NULL);
554 fprintf(outfile,
"%s%s", coldef->name, delimiter);
557 fprintf(outfile,
"%s%s", coldef->name, delimiter);
562 fprintf(outfile,
"\n");
565 for (i = 0; i < nColumns; i++) {
569 xlsWorksheetLabel(ws, line, i, coldef->units ? coldef->units :
"", NULL);
571 fprintf(outfile,
"%s%s", coldef->units ? coldef->units :
"", delimiter);
574 fprintf(outfile,
"%s%s", coldef->units ? coldef->units :
"", delimiter);
579 fprintf(outfile,
"\n");
583 for (j = 0; j < nrows; j++) {
584 for (i = 0; i < nColumns; i++) {
594 switch (coldef->type) {
596 xlsWorksheetNumberDbl(ws, line, i, *((
long double *)data), NULL);
599 xlsWorksheetNumberDbl(ws, line, i, *((
double *)data), NULL);
602 xlsWorksheetNumberDbl(ws, line, i, *((
float *)data), NULL);
605 xlsWorksheetNumberInt(ws, line, i, *((uint64_t *)data), NULL);
608 xlsWorksheetNumberInt(ws, line, i, *((int64_t *)data), NULL);
611 xlsWorksheetNumberInt(ws, line, i, *((uint32_t *)data), NULL);
614 xlsWorksheetNumberInt(ws, line, i, *((int32_t *)data), NULL);
617 xlsWorksheetNumberInt(ws, line, i, *((
unsigned short *)data), NULL);
620 xlsWorksheetNumberInt(ws, line, i, *((
short *)data), NULL);
623 xlsWorksheetLabel(ws, line, i, *((
char **)data), NULL);
626 sprintf(buffer,
"%c", *((
char *)data));
627 xlsWorksheetLabel(ws, line, i, buffer, NULL);
634 switch (coldef->type) {
636 fprintf(outfile,
"%.*g", DBL_DIG, *((
double *)data));
639 fprintf(outfile,
"%.*g", FLT_DIG, *((
float *)data));
645 fprintf(outfile,
"%s", delimiter);
651 fprintf(outfile,
"\n");
660 xlsWorkbookDump(w, output);
661 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)