64# if defined(__BORLANDC__)
65# define _setmode(handle, amode) setmode(handle, amode)
72static char *mode_name[MODES] = {
80static char *order_names[ORDERS] = {
99char *option[N_OPTIONS] = {
112 "sdds2plaindata [<input>] [<output>]\n"
113 " [-pipe=[input][,output]]\n"
114 " [-outputMode={ascii|binary}]\n"
115 " [-separator=<string>]\n"
117 " [-order={rowMajor|columnMajor}]\n"
118 " [-parameter=<name>[,format=<string>]...]\n"
119 " [-column=<name>[,format=<string>]...]\n"
123 " -outputMode Specify output format: ascii or binary.\n"
124 " -separator Define the column separator string in ASCII mode.\n"
125 " -noRowCount Exclude the number of rows from the output file.\n"
126 " (Note: Binary mode always includes row count.)\n"
127 " -order Set data ordering: rowMajor (default) or columnMajor.\n"
128 " -parameter Include specified parameters in the output. Optionally specify a format.\n"
129 " -column Include specified columns in the output. Supports wildcards and optional format.\n"
130 " -labeled Add labels for each parameter or column in ASCII mode.\n"
131 " -nowarnings Suppress warning messages.\n\n"
132 "Program by Robert Soliday. (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")\n";
136int main(
int argc,
char **argv) {
143 long i_arg, retval, page_number = 0, size, columnOrder = 0;
147 char *input, *output;
148 unsigned long pipeFlags = 0, flags = 0;
149 long noWarnings = 0, tmpfile_used = 0;
152 long *parameterType, *columnType, *parameterIndex;
153 int32_t *columnIndex;
154 char **parameterUnits;
157 static char printBuffer[SDDS_MAXLINE * 16];
158 static char formatbuffer[100], formatbuffer2[100];
160 long binary = 0, noRowCount = 0;
161 char *separator, *ptr = NULL;
162 char **parameter, **parameterFormat;
163 char **column, **columnFormat, **columnUnits, **columnMatch, **columnMatchFormat, **columnName;
164 long parameters = 0, columns = 0, columnMatches = 0;
165 int32_t columnNames = 0;
167 input = output = NULL;
168 parameter = column = parameterFormat = columnFormat = columnMatch = columnMatchFormat = columnName = NULL;
171 parameterType = columnType = parameterIndex = NULL;
174 parameterUnits = columnUnits = NULL;
176 buffer =
tmalloc(
sizeof(
char) * 16);
179 argc =
scanargs(&s_arg, argc, argv);
183 for (i_arg = 1; i_arg < argc; i_arg++) {
184 if (s_arg[i_arg].arg_type == OPTION) {
185 switch (
match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
187 if (s_arg[i_arg].n_items != 2)
189 switch (
match_string(s_arg[i_arg].list[1], mode_name, MODES, 0)) {
202 if (s_arg[i_arg].n_items != 2)
204 separator = s_arg[i_arg].list[1];
207 if (s_arg[i_arg].n_items != 1)
212 if (s_arg[i_arg].n_items != 2)
214 switch (
match_string(s_arg[i_arg].list[1], order_names, ORDERS, 0)) {
227 if ((s_arg[i_arg].n_items != 2) && (s_arg[i_arg].n_items != 4))
229 parameter =
trealloc(parameter,
sizeof(*parameter) * (++parameters));
230 parameterFormat =
trealloc(parameterFormat,
sizeof(*parameterFormat) * (parameters));
231 parameter[parameters - 1] = s_arg[i_arg].list[1];
232 parameterFormat[parameters - 1] = NULL;
233 s_arg[i_arg].n_items -= 2;
234 if (!
scanItemList(&flags, s_arg[i_arg].list + 2, &s_arg[i_arg].n_items, 0,
"format",
SDDS_STRING, &(parameterFormat[parameters - 1]), 1, 0, NULL))
236 if (parameterFormat[parameters - 1]) {
237 replaceString(formatbuffer, parameterFormat[parameters - 1],
"ld", PRId32, -1, 0);
238 replaceString(formatbuffer2, formatbuffer,
"lu", PRIu32, -1, 0);
239 parameterFormat[parameters - 1] = malloc(
sizeof(*(parameterFormat[parameters - 1])) * (strlen(formatbuffer2) + 1));
240 sprintf(parameterFormat[parameters - 1],
"%s", formatbuffer2);
244 if ((s_arg[i_arg].n_items < 2))
247 columnMatch =
trealloc(columnMatch,
sizeof(*columnMatch) * (++columnMatches));
248 columnMatchFormat =
trealloc(columnMatchFormat,
sizeof(*columnMatchFormat) * (columnMatches));
249 SDDS_CopyString(&columnMatch[columnMatches - 1], s_arg[i_arg].list[1]);
250 columnMatchFormat[columnMatches - 1] = NULL;
251 s_arg[i_arg].n_items -= 2;
252 if (!
scanItemList(&flags, s_arg[i_arg].list + 2, &s_arg[i_arg].n_items, 0,
"format",
SDDS_STRING, &(columnMatchFormat[columnMatches - 1]), 1, 0, NULL))
254 if (columnMatchFormat[columnMatches - 1]) {
255 replaceString(formatbuffer, columnMatchFormat[columnMatches - 1],
"ld", PRId32, -1, 0);
256 replaceString(formatbuffer2, formatbuffer,
"lu", PRIu32, -1, 0);
257 columnMatchFormat[columnMatches - 1] = malloc(
sizeof(*(columnMatchFormat[columnMatches - 1])) * (strlen(formatbuffer2) + 1));
258 sprintf(columnMatchFormat[columnMatches - 1],
"%s", formatbuffer2);
261 column =
trealloc(column,
sizeof(*column) * (++columns));
262 columnFormat =
trealloc(columnFormat,
sizeof(*columnFormat) * (columns));
264 columnFormat[columns - 1] = NULL;
265 s_arg[i_arg].n_items -= 2;
266 if (!
scanItemList(&flags, s_arg[i_arg].list + 2, &s_arg[i_arg].n_items, 0,
"format",
SDDS_STRING, &(columnFormat[columns - 1]), 1, 0, NULL))
268 if (columnFormat[columns - 1]) {
269 replaceString(formatbuffer, columnFormat[columns - 1],
"ld", PRId32, -1, 0);
270 replaceString(formatbuffer2, formatbuffer,
"lu", PRIu32, -1, 0);
271 columnFormat[columns - 1] = malloc(
sizeof(*(columnFormat[columns - 1])) * (strlen(formatbuffer2) + 1));
272 sprintf(columnFormat[columns - 1],
"%s", formatbuffer2);
277 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
281 if (s_arg[i_arg].n_items != 1)
289 fprintf(stderr,
"error: unknown switch: %s\n", s_arg[i_arg].list[0]);
295 input = s_arg[i_arg].list[0];
296 }
else if (output == NULL) {
297 output = s_arg[i_arg].list[0];
299 fprintf(stderr,
"error: too many filenames provided.\n");
305 processFilenames(
"sdds2plaindata", &input, &output, pipeFlags, noWarnings, &tmpfile_used);
307 if (!columns && !columnMatches && !parameters)
308 SDDS_Bomb(
"error: you must specify at least one of the -column or -parameter options.");
320 for (i = 0; i < columnMatches; i++) {
322 for (j = 0; j < columnNames; j++) {
325 if (
match_string(columnName[j], column, columns, EXACT_MATCH) < 0) {
326 column =
trealloc(column,
sizeof(*column) * (columns + 1));
328 columnFormat =
trealloc(columnFormat,
sizeof(*columnFormat) * (columns + 1));
329 columnFormat[columns] = NULL;
330 if (columnMatchFormat[i])
335 column =
trealloc(column,
sizeof(*column) * (columns + 1));
337 columnFormat =
trealloc(columnFormat,
sizeof(*columnFormat) * (columns + 1));
338 columnFormat[columns] = NULL;
339 if (columnMatchFormat[i])
351 free(columnMatchFormat);
355 parameterType =
tmalloc(
sizeof(*parameterType) * parameters);
356 parameterIndex =
tmalloc(
sizeof(*parameterIndex) * parameters);
357 parameterUnits =
tmalloc(
sizeof(*parameterUnits) * parameters);
358 for (i = 0; i < parameters; i++) {
360 fprintf(stderr,
"error: parameter '%s' does not exist.\n", parameter[i]);
371 columnType =
tmalloc(
sizeof(*columnType) * columns);
372 columnIndex =
tmalloc(
sizeof(*columnIndex) * columns);
373 columnData =
tmalloc(
sizeof(*columnData) * columns);
374 columnUnits =
tmalloc(
sizeof(*columnUnits) * columns);
375 for (i = 0; i < columns; i++) {
377 fprintf(stderr,
"error: column '%s' does not exist.\n", column[i]);
391 if (_setmode(_fileno(stdout), _O_BINARY) == -1) {
392 fprintf(stderr,
"error: unable to set stdout to binary mode.\n");
400 fileID = fopen(output,
"wb");
402 fileID = fopen(output,
"w");
405 if (fileID == NULL) {
406 fprintf(stderr,
"error: unable to open output file for writing.\n");
411 layout = &SDDS_dataset.layout;
412 fBuffer = &SDDS_dummy.fBuffer;
413 fBuffer->buffer = NULL;
414 if (!fBuffer->buffer) {
415 if (!(fBuffer->buffer = fBuffer->data =
SDDS_Malloc(
sizeof(
char) * SDDS_FILEBUFFER_SIZE))) {
416 fprintf(stderr,
"error: unable to allocate buffer for binary output.\n");
419 fBuffer->bufferSize = SDDS_FILEBUFFER_SIZE;
420 fBuffer->bytesLeft = SDDS_FILEBUFFER_SIZE;
425 while (retval != page_number && (retval =
SDDS_ReadPage(&SDDS_dataset)) > 0) {
426 if (page_number && retval != page_number)
434 if ((binary) && (!noRowCount)) {
435 if (rows > INT32_MAX) {
438 fprintf(stderr,
"error: failed to write row count (overflow).\n");
442 fprintf(stderr,
"error: failed to write row count.\n");
448 fprintf(stderr,
"error: failed to write row count.\n");
454 for (i = 0; i < parameters; i++) {
462 fprintf(stderr,
"error: failed to write string parameter.\n");
465 }
else if (!
SDDS_BufferedWrite(SDDS_dataset.parameter[parameterIndex[i]],
SDDS_type_size[layout->parameter_definition[parameterIndex[i]].type - 1], fileID, fBuffer)) {
466 fprintf(stderr,
"error: failed to write parameter value.\n");
476 fputs(parameter[i], fileID);
477 fputs(separator, fileID);
478 if (parameterUnits[i])
479 fputs(parameterUnits[i], fileID);
480 fputs(separator, fileID);
482 fputs(printBuffer, fileID);
489 fprintf(fileID,
"\t%" PRId64
"\n", rows);
490 if (labeled && columns) {
491 for (j = 0; j < columns; j++) {
492 fputs(column[j], fileID);
493 if (j != (columns - 1))
494 fputs(separator, fileID);
497 for (j = 0; j < columns; j++) {
499 fputs(columnUnits[j], fileID);
500 if (j != (columns - 1))
501 fputs(separator, fileID);
511 for (j = 0; j < columns; j++) {
513 for (i = 0; i < rows; i++) {
515 fprintf(stderr,
"error: failed to write string data for column '%s'.\n", column[j]);
521 for (i = 0; i < rows; i++) {
522 if (!
SDDS_BufferedWrite((
char *)SDDS_dataset.data[columnIndex[j]] + i * size, size, fileID, fBuffer)) {
523 fprintf(stderr,
"error: failed to write data for column '%s'.\n", column[j]);
530 for (i = 0; i < rows; i++) {
531 for (j = 0; j < columns; j++) {
534 fprintf(stderr,
"error: failed to write string data for column '%s'.\n", column[j]);
539 if (!
SDDS_BufferedWrite((
char *)SDDS_dataset.data[columnIndex[j]] + i * size, size, fileID, fBuffer)) {
540 fprintf(stderr,
"error: failed to write data for column '%s'.\n", column[j]);
548 for (i = 0; i < columns; i++) {
555 for (i = 0; i < columns; i++) {
556 for (j = 0; j < rows; j++) {
558 fputs(printBuffer, fileID);
560 fprintf(fileID,
"%s", separator);
565 for (j = 0; j < rows; j++) {
566 for (i = 0; i < columns; i++) {
568 fputs(printBuffer, fileID);
569 if (i != columns - 1)
570 fprintf(fileID,
"%s", separator);
587 SDDS_SetError(
"Unable to write page--buffer flushing problem (SDDS_WriteBinaryPage)");
606 free(parameterFormat);
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_BufferedWrite(void *target, int64_t targetSize, FILE *fp, SDDS_FILEBUFFER *fBuffer)
int32_t SDDS_WriteBinaryString(char *string, FILE *fp, SDDS_FILEBUFFER *fBuffer)
Writes a binary string to a file with buffering.
int32_t SDDS_FlushBuffer(FILE *fp, SDDS_FILEBUFFER *fBuffer)
int32_t SDDS_type_size[SDDS_NUM_TYPES]
Array of sizes for each supported data type.
int32_t SDDS_GetParameterInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode,...)
Retrieves information about a specified parameter in the SDDS dataset.
int32_t SDDS_GetColumnInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode,...)
Retrieves information about a specified column in the SDDS dataset.
int32_t SDDS_FreeStringArray(char **string, int64_t strings)
Frees an array of strings by deallocating each individual string.
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
int32_t SDDS_GetParameterType(SDDS_DATASET *SDDS_dataset, int32_t index)
Retrieves the data type of a parameter in the SDDS dataset by its index.
int32_t SDDS_GetParameterIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named parameter in the SDDS dataset.
int32_t SDDS_SprintTypedValue(void *data, int64_t index, int32_t type, const char *format, char *buffer, uint32_t mode)
Formats a data value of a specified type into a string buffer using an optional printf format string.
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_Malloc(size_t size)
Allocates memory of a specified size.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
int32_t SDDS_GetColumnType(SDDS_DATASET *SDDS_dataset, int32_t index)
Retrieves the data type of a column in the SDDS dataset by its index.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
int32_t SDDS_CopyString(char **target, const char *source)
Copies a source string to a target string with memory allocation.
#define SDDS_STRING
Identifier for the string data type.
void * trealloc(void *old_ptr, uint64_t size_of_block)
Reallocates a memory block to a new size.
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.
char * cp_str(char **s, char *t)
Copies a string, allocating memory for storage.
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 replaceString(char *t, char *s, char *orig, char *repl, long count_limit, long here)
Replace occurrences of one string with another string with additional options.
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)
void free_scanargs(SCANNED_ARG **scanned, int argc)
long scanItemList(unsigned long *flags, char **item, long *items, unsigned long mode,...)
Scans a list of items and assigns values based on provided keywords and types.
int has_wildcards(char *template)
Check if a template string contains any wildcard characters.
char * expand_ranges(char *template)
Expand range specifiers in a wildcard template into explicit character lists.
int wild_match(char *string, char *template)
Determine whether one string is a wildcard match for another.