38char *option[N_OPTIONS] = {
52 "Usage: sddsquery [OPTIONS] [<SDDSfilename>...]\n"
55 " -pipe[=input] Read input from a pipe.\n"
56 " -sddsOutput[=<filename>] Write SDDS output to a file.\n"
57 " -arraylist List arrays.\n"
58 " -associatelist List associates.\n"
59 " -columnlist List columns.\n"
60 " -parameterlist List parameters.\n"
61 " -version Show version information.\n"
62 " -delimiter=<string> Use <string> as a delimiter.\n"
63 " -appendunits[=bare] Append units to the output.\n"
64 " -readAll Read all pages.\n"
67 " sddsquery accesses a series of SDDS files and summarizes the file header for each. "
68 "It also provides lists of arrays, columns, parameters, or associates.\n"
70 "Program by Michael Borland. (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")\n";
72long InitializeSDDSHeaderOutput(
SDDS_DATASET *outSet,
char *filename);
78int main(
int argc,
char **argv) {
86 char **filename, *ptr, *sddsOutputFile;
87 long i, i_arg, filenames, file, append_units, sddsOutput;
89 char *text, *contents, *delimiter, *unitsTemplate;
91 unsigned long pipeFlags;
97 filenames = append_units = 0;
98 delimiter = sddsOutputFile = unitsTemplate = NULL;
103 argc =
scanargs(&s_arg, argc, argv);
105 for (i_arg = 1; i_arg < argc; i_arg++) {
106 if (s_arg[i_arg].arg_type == OPTION) {
108 switch (
match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
109 case SET_COLUMN_LIST:
110 list_request = SET_COLUMN_LIST;
112 case SET_PARAMETER_LIST:
113 list_request = SET_PARAMETER_LIST;
115 case SET_ASSOCIATE_LIST:
116 list_request = SET_ASSOCIATE_LIST;
119 list_request = SET_ARRAY_LIST;
122 list_request = SET_VERSION;
125 if (s_arg[i_arg].n_items < 2)
127 delimiter = s_arg[i_arg].list[1];
129 case SET_APPEND_UNITS:
131 if (s_arg[i_arg].n_items == 2) {
132 if (strncmp(s_arg[i_arg].list[1],
"bare", strlen(s_arg[i_arg].list[1])) == 0)
133 unitsTemplate =
" %s";
135 SDDS_Bomb(
"invalid -appendUnits syntax");
136 }
else if (s_arg[i_arg].n_items > 2)
137 SDDS_Bomb(
"invalid -appendUnits syntax");
139 unitsTemplate =
" (%s)";
142 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
147 sddsOutputFile = NULL;
148 if ((s_arg[i_arg].n_items != 1 && s_arg[i_arg].n_items != 2) ||
149 (s_arg[i_arg].n_items == 2 &&
SDDS_StringIsBlank(sddsOutputFile = s_arg[i_arg].list[1])))
156 bomb(
"unknown switch", USAGE);
160 filename =
trealloc(filename,
sizeof(*filename) * (filenames + 1));
161 filename[filenames++] = s_arg[i_arg].list[0];
165 if (!filenames && !(pipeFlags & USE_STDIN))
167 if (pipeFlags & USE_STDIN) {
169 filename1 =
tmalloc(
sizeof(*filename1) * (filenames + 1));
171 for (file = 0; file < filenames; file++)
172 filename1[file + 1] = filename[file];
175 filename = filename1;
179 fprintf(stderr,
"files: ");
180 for (file = 0; file < filenames; file++)
181 fprintf(stderr,
"%s ", filename[file] ? filename[file] :
"NULL");
182 fprintf(stderr,
"\n");
185 if (sddsOutput && !InitializeSDDSHeaderOutput(&SDDSout, sddsOutputFile)) {
190 for (file = 0; file < filenames; file++) {
192 fprintf(stderr,
"working on file %ld\n", file);
199 fprintf(stderr,
"file initialized\n");
203 fprintf(stderr,
"Making SDDS header summary\n");
205 if (!MakeSDDSHeaderSummary(&SDDSout, &SDDS_dataset, list_request, filename[file])) {
217 layout = &SDDS_dataset.layout;
218 if (list_request >= 0) {
219 switch (list_request) {
220 case SET_COLUMN_LIST:
222 fprintf(stderr,
"printing column info\n");
224 for (i = 0; i < layout->n_columns; i++) {
225 fputs(layout->column_definition[i].name, stdout);
226 if (append_units && layout->column_definition[i].units &&
228 fprintf(stdout, unitsTemplate, layout->column_definition[i].units);
229 fputs(delimiter ? delimiter :
"\n", stdout);
232 case SET_PARAMETER_LIST:
234 fprintf(stderr,
"printing parameter info\n");
236 for (i = 0; i < layout->n_parameters; i++) {
237 fputs(layout->parameter_definition[i].name, stdout);
238 if (append_units && layout->parameter_definition[i].units &&
240 fprintf(stdout, unitsTemplate, layout->parameter_definition[i].units);
241 fputs(delimiter ? delimiter :
"\n", stdout);
244 case SET_ASSOCIATE_LIST:
246 fprintf(stderr,
"printing associate info\n");
248 for (i = 0; i < layout->n_associates; i++) {
249 fputs(layout->associate_definition[i].filename, stdout);
250 fputs(delimiter ? delimiter :
"\n", stdout);
255 fprintf(stderr,
"printing array info\n");
257 for (i = 0; i < layout->n_arrays; i++) {
258 fputs(layout->array_definition[i].name, stdout);
259 if (append_units && layout->array_definition[i].units &&
261 fprintf(stdout, unitsTemplate, layout->array_definition[i].units);
262 fputs(delimiter ? delimiter :
"\n", stdout);
267 fprintf(stderr,
"printing version info\n");
270 if (!(fp = fopen(filename[file],
"r")) || !fgets(s, SDDS_MAXLINE, fp)) {
274 if (strncmp(s,
"SDDS", 4) != 0)
277 if (!(ptr = strchr(s,
'\n')))
287 SDDS_Bomb(
"something impossible happened!");
295 if (list_request != SET_VERSION && !
SDDS_Terminate(&SDDS_dataset)) {
303 fprintf(stdout,
"\nfile %s is in SDDS protocol version %" PRId32
"\n",
304 filename[file] ? filename[file] :
"stdin", layout->version);
308 fprintf(stdout,
"description: %s\n", text);
310 fprintf(stdout,
"contents: %s\n", contents);
311 if (layout->data_mode.mode == SDDS_ASCII) {
312 fprintf(stdout,
"\ndata is ASCII with %" PRId32
" lines per row and %" PRId32
" additional header lines expected.\n",
313 layout->data_mode.lines_per_row, layout->data_mode.additional_header_lines);
314 fprintf(stdout,
"row counts: %s\n", layout->data_mode.no_row_counts ?
"no" :
"yes");
316 if (!SDDS_dataset.layout.byteOrderDeclared)
317 fprintf(stdout,
"data is binary (no byte order declared)\n");
319 if (SDDS_dataset.swapByteOrder)
320 fprintf(stdout,
"data is little-endian binary\n");
322 fprintf(stdout,
"data is big-endian binary\n");
324 if (SDDS_dataset.swapByteOrder)
325 fprintf(stdout,
"data is big-endian binary\n");
327 fprintf(stdout,
"data is little-endian binary\n");
331 if (layout->n_columns) {
332 fprintf(stdout,
"\n%" PRId32
" columns of data:\n", layout->n_columns);
333 fprintf(stdout,
"NAME UNITS SYMBOL FORMAT TYPE FIELD DESCRIPTION\n");
334 fprintf(stdout,
" LENGTH\n");
335 for (i = 0; i < layout->n_columns; i++) {
336 coldef = layout->column_definition + i;
337 fprintf(stdout,
"%-15s %-15s %-15s %-15s %-7s %-7" PRId32
" %s\n",
338 coldef->name ? coldef->name :
"NULL",
339 coldef->units ? coldef->units :
"NULL",
340 coldef->symbol ? coldef->symbol :
"NULL",
341 coldef->format_string ? coldef->format_string :
"NULL",
343 coldef->field_length, coldef->description ? coldef->description :
"NULL");
347 if (layout->n_parameters) {
348 fprintf(stdout,
"\n%" PRId32
" parameters:\n", layout->n_parameters);
349 fprintf(stdout,
"NAME UNITS SYMBOL TYPE DESCRIPTION\n");
350 for (i = 0; i < layout->n_parameters; i++) {
351 pardef = layout->parameter_definition + i;
352 fprintf(stdout,
"%-19s %-19s %-19s %-19s %s\n",
353 pardef->name ? pardef->name :
"NULL",
354 pardef->units ? pardef->units :
"NULL",
355 pardef->symbol ? pardef->symbol :
"NULL",
357 pardef->description ? pardef->description :
"NULL");
361 if (layout->n_arrays) {
362 fprintf(stdout,
"\n%" PRId32
" arrays of data:\n", layout->n_arrays);
363 fprintf(stdout,
"NAME UNITS SYMBOL FORMAT TYPE FIELD GROUP DESCRIPTION\n");
364 fprintf(stdout,
" LENGTH NAME\n");
365 for (i = 0; i < layout->n_arrays; i++) {
366 arraydef = layout->array_definition + i;
367 fprintf(stdout,
"%-15s %-15s %-15s %-7s %-8s*^%-5" PRId32
" %-7" PRId32
" %-15s %s\n",
368 arraydef->name ? arraydef->name :
"NULL",
369 arraydef->units ? arraydef->units :
"NULL",
370 arraydef->symbol ? arraydef->symbol :
"NULL",
371 arraydef->format_string ? arraydef->format_string :
"NULL",
373 arraydef->dimensions,
374 arraydef->field_length,
375 arraydef->group_name ? arraydef->group_name :
"NULL",
376 arraydef->description ? arraydef->description :
"NULL");
380 if (layout->n_associates) {
381 fprintf(stdout,
"\n%" PRId32
" associates:\n", layout->n_associates);
382 fprintf(stdout,
"SDDS FILENAME PATH CONTENTS DESCRIPTION\n");
383 for (i = 0; i < layout->n_associates; i++)
384 fprintf(stdout,
"%-5s %-19s %-29s %-19s %s\n",
385 layout->associate_definition[i].sdds ?
"yes" :
"no",
386 layout->associate_definition[i].filename ? layout->associate_definition[i].filename :
"NULL",
387 layout->associate_definition[i].path ? layout->associate_definition[i].path :
"NULL",
388 layout->associate_definition[i].contents ? layout->associate_definition[i].contents :
"NULL",
389 layout->associate_definition[i].description ? layout->associate_definition[i].description :
"NULL");
408static long indexName, indexUnits, indexSymbol, indexFormat, indexType, indexDescription, indexGroup;
410long InitializeSDDSHeaderOutput(
SDDS_DATASET *outSet,
char *filename) {
430 switch (listRequest) {
431 case SET_COLUMN_LIST:
432 if (!MakeColumnHeaderSummary(outSet, inSet, inputFile))
435 case SET_PARAMETER_LIST:
436 if (!MakeParameterHeaderSummary(outSet, inSet, inputFile))
440 if (!MakeArrayHeaderSummary(outSet, inSet, inputFile))
444 if (!MakeColumnHeaderSummary(outSet, inSet, inputFile) ||
445 !MakeParameterHeaderSummary(outSet, inSet, inputFile) ||
446 !MakeArrayHeaderSummary(outSet, inSet, inputFile))
458 layout = &inSet->layout;
459 if (!layout->n_columns)
463 for (i = 0; i < layout->n_columns; i++) {
464 coldef = layout->column_definition + i;
466 indexName, coldef->name,
467 indexUnits, coldef->units,
468 indexSymbol, coldef->symbol,
469 indexFormat, coldef->format_string,
471 indexDescription, coldef->description,
472 indexGroup, NULL, -1))
477 "Filename", inputFile,
490 layout = &inSet->layout;
491 if (!layout->n_parameters)
495 for (i = 0; i < layout->n_parameters; i++) {
496 pardef = layout->parameter_definition + i;
498 indexName, pardef->name,
499 indexUnits, pardef->units,
500 indexSymbol, pardef->symbol,
501 indexFormat, pardef->format_string,
503 indexDescription, pardef->description,
504 indexGroup, NULL, -1))
508 "Class",
"parameter",
509 "Filename", inputFile,
522 layout = &inSet->layout;
523 if (!layout->n_arrays)
527 for (i = 0; i < layout->n_arrays; i++) {
528 arrdef = layout->array_definition + i;
530 indexName, arrdef->name,
531 indexUnits, arrdef->units,
532 indexSymbol, arrdef->symbol,
533 indexFormat, arrdef->format_string,
535 indexDescription, arrdef->description,
536 indexGroup, arrdef->group_name,
542 "Filename", inputFile,
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_SetRowValues(SDDS_DATASET *SDDS_dataset, int32_t mode, int64_t row,...)
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
int32_t SDDS_InitializeOutput(SDDS_DATASET *SDDS_dataset, int32_t data_mode, int32_t lines_per_row, const char *description, const char *contents, const char *filename)
Initializes the SDDS output dataset.
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
int32_t SDDS_DefineColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, int32_t field_length)
Defines a data column within the SDDS dataset.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
int32_t SDDS_DefineParameter(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, char *fixed_value)
Defines a data parameter with a fixed string value.
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.
int32_t SDDS_StringIsBlank(char *s)
Checks if a string is blank (contains only whitespace characters).
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
int32_t SDDS_IsBigEndianMachine()
Determines whether the current machine uses big-endian byte ordering.
#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 * delete_chars(char *s, char *t)
Removes all occurrences of characters found in string t from string s.
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)