78#if !defined(MAXDOUBLE)
79# define MAXDOUBLE 1.79769313486231570e+308
82char *option[N_OPTIONS] = {
96 "Usage: sddsconvertalarmlog [<input-file>] [<output-file>]\n"
97 " [-pipe=[input][,output]]\n"
102 " [-minimumInterval=<seconds>]\n"
103 " [-snapshot=<epochtime>]\n"
104 " [-time=[start=<epochtime>,end=<epochtime>]]\n"
105 " [-delete=<column-names>]\n"
106 " [-retain=<column-names>]\n"
108 " -pipe=[input][,output] Use pipe for input and/or output.\n"
109 " -binary Output in binary format.\n"
110 " -ascii Output in ASCII format.\n"
111 " -double Use double precision for output.\n"
112 " -float Use float precision for output.\n"
113 " -minimumInterval=<seconds> Set minimum interval between data points.\n"
114 " -snapshot=<epochtime> Take a snapshot at the specified epoch time.\n"
115 " -time=[start=<epochtime>][,end=<epochtime>]\n"
116 " Filter data by time range.\n"
117 " -delete={<matching-string>[,...]} Delete columns matching the pattern.\n"
118 " -retain={<matching-string>[,...]} Retain only columns matching the pattern.\n"
119 "\nProgram by Robert Soliday. (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")\n";
121long SDDS_SetRowValuesMod(
SDDS_DATASET *SDDS_dataset,
long mode, int64_t row, ...);
122char **process_name_options(
char **orig_name,
long orig_names,
char **
delete,
long deletes,
char **retain,
long retains,
long *num_matched,
long **origToNewIndex);
124int main(
int argc,
char **argv) {
128 long tmpfile_used, noWarnings;
129 char *input, *output;
130 long ascii_output, binary_output;
131 unsigned long pipeFlags;
136 long readbackNameIndex = -1, controlNameIndex = -1;
137 long timeIndex = -1, valueIndex = -1, controlNameIndexIndex = -1, previousRowIndex = -1;
138 double *timeData = NULL, *valueData = NULL, *previousRowData = NULL;
139 int32_t *controlNameIndexData = NULL;
143 int64_t row, rows, snapshotrow = 0, initRow = 0, outrow;
144 double *rowdata = NULL;
145 long *origToNewIndex = NULL;
146 double minimumInterval = -1;
147 double timeInterval, previousTime = 0;
148 int64_t totalRows = 0, currentRows = 0;
149 short filterTime = 0;
150 double startTime = 0, endTime = MAXDOUBLE;
151 int64_t startTimeRow = 0, endTimeRow = 0;
153 char **ColumnName = NULL;
155 char **retain_name = NULL;
156 long retain_names = 0;
157 char **delete_name = NULL;
158 long delete_names = 0;
161 argc =
scanargs(&s_arg, argc, argv);
163 fprintf(stderr,
"%s", USAGE);
166 input = output = NULL;
167 ascii_output = binary_output = noWarnings = 0;
172 for (i_arg = 1; i_arg < argc; i_arg++) {
173 if (s_arg[i_arg].arg_type == OPTION) {
175 switch (
match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
191 if (s_arg[i_arg].n_items < 2) {
192 fprintf(stderr,
"invalid -snapshot syntax\n");
196 if (sscanf(s_arg[i_arg].list[1],
"%lf", &epochtime) != 1) {
197 fprintf(stderr,
"invalid -snapshot syntax or value\n");
202 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags)) {
203 fprintf(stderr,
"invalid -pipe syntax\n");
207 case SET_MININTERVAL:
208 if (s_arg[i_arg].n_items < 2) {
209 fprintf(stderr,
"invalid -minimumInterval syntax\n");
212 if (sscanf(s_arg[i_arg].list[1],
"%lf", &minimumInterval) != 1) {
213 fprintf(stderr,
"invalid -minimumInterval syntax or value\n");
218 s_arg[i_arg].n_items -= 1;
220 if (!
scanItemList(&flags, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
223 fprintf(stderr,
"invalid -time syntax\n");
226 s_arg[i_arg].n_items += 1;
229 retain_name =
trealloc(retain_name,
sizeof(*retain_name) * (retain_names + s_arg[i_arg].n_items - 1));
230 for (i = 1; i < s_arg[i_arg].n_items; i++)
231 retain_name[i - 1 + retain_names] = s_arg[i_arg].list[i];
232 retain_names += s_arg[i_arg].n_items - 1;
235 delete_name =
trealloc(delete_name,
sizeof(*delete_name) * (delete_names + s_arg[i_arg].n_items - 1));
236 for (i = 1; i < s_arg[i_arg].n_items; i++)
237 delete_name[i - 1 + delete_names] = s_arg[i_arg].list[i];
238 delete_names += s_arg[i_arg].n_items - 1;
241 fprintf(stderr,
"Error (%s): unknown switch: %s\n", argv[0], s_arg[i_arg].list[0]);
247 input = s_arg[i_arg].list[0];
248 else if (output == NULL)
249 output = s_arg[i_arg].list[0];
251 fprintf(stderr,
"too many filenames\n");
257 if ((snapshot == 1) && (minimumInterval >= 0)) {
258 fprintf(stderr,
"-snapshot and -minimumInterval options cannot be used together\n");
261 if ((snapshot == 1) && (filterTime == 1)) {
262 fprintf(stderr,
"-snapshot and -time options cannot be used together\n");
266 processFilenames(
"sddsconvertalarmlog", &input, &output, pipeFlags, noWarnings, &tmpfile_used);
279 if ((readbackNameIndex == -1) && (controlNameIndex == -1)) {
280 fprintf(stderr,
"Error: ReadbackName and ControlName arrays are both missing from the input file.\n");
283 if (timeIndex == -1) {
284 fprintf(stderr,
"Error: Time column is missing\n");
287 if (valueIndex == -1) {
288 fprintf(stderr,
"Error: Value column is missing\n");
291 if (controlNameIndexIndex == -1) {
292 fprintf(stderr,
"Error: ControlNameIndex column is missing\n");
296 if (!
SDDS_InitializeOutput(&SDDS_output, ascii_output ? SDDS_ASCII : (binary_output ? SDDS_BINARY : SDDS_input.layout.data_mode.mode), 1, NULL, NULL, output)) {
302 while (SDDS_ReadTable(&SDDS_input) > 0) {
304 rows = SDDS_RowCount(&SDDS_input);
306 if (readbackNameIndex != -1) {
307 readbackNameArray =
SDDS_GetArray(&SDDS_input,
"ReadbackName", NULL);
309 readbackNameArray =
SDDS_GetArray(&SDDS_input,
"ControlName", NULL);
311 if (readbackNameArray == NULL) {
316 origToNewIndex = malloc(
sizeof(
long) * readbackNameArray->elements);
317 for (i = 0; i < readbackNameArray->elements; i++) {
318 origToNewIndex[i] = -1;
321 ColumnName = process_name_options(((
char **)readbackNameArray->data), readbackNameArray->elements, delete_name, delete_names, retain_name, retain_names, &ColumnNames, &origToNewIndex);
322 rowdata = malloc(
sizeof(
double) * ColumnNames);
323 for (i = 0; i < ColumnNames; i++) {
340 if (SDDS_StartTable(&SDDS_output, 1) == 0) {
345 if (SDDS_StartTable(&SDDS_output, 100) == 0) {
352 if (readbackNameIndex != -1) {
353 readbackNameArray2 =
SDDS_GetArray(&SDDS_input,
"ReadbackName", NULL);
355 readbackNameArray2 =
SDDS_GetArray(&SDDS_input,
"ControlName", NULL);
357 if (readbackNameArray2 == NULL) {
361 if (readbackNameArray->elements != readbackNameArray2->elements) {
362 fprintf(stderr,
"Error: Unable to process multiple pages with different ReadbackName and/or ControlName columns\n");
365 for (i = 0; i < readbackNameArray->elements; i++) {
366 if (strcmp((
char *)((
char **)readbackNameArray->data)[i], (
char *)((
char **)readbackNameArray2->data)[i]) != 0) {
367 fprintf(stderr,
"Error: Unable to process multiple pages with different ReadbackName and/or ControlName columns\n");
387 for (row = 0; row < rows; row++) {
388 if (timeData[row] <= epochtime) {
396 for (row = 0; row < rows; row++) {
397 if (timeData[row] <= startTime) {
403 for (row = 0; row < rows; row++) {
404 if (timeData[row] <= endTime) {
411 if (previousRowIndex != -1) {
416 for (row = rows - 1; row >= 0; row--) {
417 if (previousRowData[row] == -2) {
418 if (origToNewIndex[controlNameIndexData[row]] == -1) {
425 free(previousRowData);
428 if (minimumInterval > 0) {
429 previousTime = timeData[0] - minimumInterval - 1;
431 for (row = 0; row < rows; row++) {
432 if ((readbackNameArray->elements < controlNameIndexData[row]) ||
433 (controlNameIndexData[row] < 0)) {
437 if (origToNewIndex[controlNameIndexData[row]] == -1) {
440 rowdata[origToNewIndex[controlNameIndexData[row]]] = valueData[row];
441 if (previousRowIndex != -1) {
446 if (((snapshot == 0) && (filterTime == 0)) ||
447 ((snapshot == 1) && (row == snapshotrow)) ||
448 ((filterTime == 1) && (row >= startTimeRow) && (row <= endTimeRow))) {
449 if (minimumInterval > 0) {
450 timeInterval = timeData[row] - previousTime;
451 if (timeInterval <= minimumInterval) {
454 previousTime = timeData[row];
457 if ((snapshot == 0) && (totalRows == currentRows)) {
465 if (SDDS_SetRowValuesMod(&SDDS_output, SDDS_SET_BY_INDEX | SDDS_PASS_BY_REFERENCE, outrow, 0, &timeData[row], -1) == 0) {
469 for (i = 0; i < ColumnNames; i++) {
470 if (SDDS_SetRowValuesMod(&SDDS_output, SDDS_SET_BY_INDEX | SDDS_PASS_BY_REFERENCE, outrow, i + 1, &rowdata[i], -1) == 0) {
484 if (controlNameIndexData)
485 free(controlNameIndexData);
490 free(origToNewIndex);
493 for (i = 0; i < ColumnNames; i++) {
501 if (SDDS_WriteTable(&SDDS_output) == 0) {
518long SDDS_SetRowValuesMod(
SDDS_DATASET *SDDS_dataset,
long mode, int64_t row, ...) {
528 if (!(mode & SDDS_SET_BY_INDEX || mode & SDDS_SET_BY_NAME) ||
529 !(mode & SDDS_PASS_BY_VALUE || mode & SDDS_PASS_BY_REFERENCE)) {
530 SDDS_SetError(
"Unable to set column values--unknown mode (SDDS_SetRowValues)");
537 row -= SDDS_dataset->first_row_in_mem;
538 if (row >= SDDS_dataset->n_rows_allocated) {
539 sprintf(buffer,
"Unable to set column values--row number (%" PRId64
") exceeds exceeds allocated memory (%" PRId64
") (SDDS_SetRowValues)", row, SDDS_dataset->n_rows_allocated);
543 if (row > SDDS_dataset->n_rows - 1)
544 SDDS_dataset->n_rows = row + 1;
546 va_start(argptr, row);
547 layout = &SDDS_dataset->layout;
552 fprintf(stderr,
"setting row %" PRId64
" (mem slot %" PRId64
")\n", row + SDDS_dataset->first_row_in_mem, row);
555 if (mode & SDDS_SET_BY_INDEX) {
556 if ((index = va_arg(argptr, int32_t)) == -1) {
560 if (index < 0 || index >= layout->n_columns) {
561 SDDS_SetError(
"Unable to set column values--index out of range (SDDS_SetRowValues)");
566 fprintf(stderr,
"Setting values for column #%ld\n", index);
569 if ((name = va_arg(argptr,
char *)) == NULL) {
574 fprintf(stderr,
"Setting values for column %s\n", name);
577 SDDS_SetError(
"Unable to set column values--name not recognized (SDDS_SetRowValues)");
582 switch (layout->column_definition[index].type) {
584 if (mode & SDDS_PASS_BY_VALUE)
585 *(((
short *)SDDS_dataset->data[index]) + row) = (short)va_arg(argptr,
int);
587 *(((
short *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr,
short *));
590 if (mode & SDDS_PASS_BY_VALUE)
591 *(((
unsigned short *)SDDS_dataset->data[index]) + row) = (
unsigned short)va_arg(argptr,
unsigned int);
593 *(((
unsigned short *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr,
unsigned short *));
596 if (mode & SDDS_PASS_BY_VALUE)
597 *(((int32_t *)SDDS_dataset->data[index]) + row) = va_arg(argptr, int32_t);
599 *(((int32_t *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr, int32_t *));
602 if (mode & SDDS_PASS_BY_VALUE)
603 *(((uint32_t *)SDDS_dataset->data[index]) + row) = va_arg(argptr, uint32_t);
605 *(((uint32_t *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr, uint32_t *));
608 if (mode & SDDS_PASS_BY_VALUE)
609 *(((int64_t *)SDDS_dataset->data[index]) + row) = va_arg(argptr, int64_t);
611 *(((int64_t *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr, int64_t *));
614 if (mode & SDDS_PASS_BY_VALUE)
615 *(((uint64_t *)SDDS_dataset->data[index]) + row) = va_arg(argptr, uint64_t);
617 *(((uint64_t *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr, uint64_t *));
620 if (mode & SDDS_PASS_BY_VALUE)
621 *(((
float *)SDDS_dataset->data[index]) + row) = (float)va_arg(argptr,
double);
623 *(((
float *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr,
double *));
626 if (mode & SDDS_PASS_BY_VALUE)
627 *(((
double *)SDDS_dataset->data[index]) + row) = va_arg(argptr,
double);
629 *(((
double *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr,
double *));
632 if (mode & SDDS_PASS_BY_VALUE)
633 *(((
long double *)SDDS_dataset->data[index]) + row) = va_arg(argptr,
long double);
635 *(((
long double *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr,
long double *));
638 if (((
char **)SDDS_dataset->data[index])[row]) {
639 free(((
char **)SDDS_dataset->data[index])[row]);
640 ((
char **)SDDS_dataset->data[index])[row] = NULL;
642 if (mode & SDDS_PASS_BY_VALUE) {
643 if (!
SDDS_CopyString((
char **)SDDS_dataset->data[index] + row, va_arg(argptr,
char *))) {
644 SDDS_SetError(
"Unable to set string column value--allocation failure (SDDS_SetRowValues)");
648 if (!
SDDS_CopyString((
char **)SDDS_dataset->data[index] + row, *(va_arg(argptr,
char **)))) {
649 SDDS_SetError(
"Unable to set string column value--allocation failure (SDDS_SetRowValues)");
655 if (mode & SDDS_PASS_BY_VALUE)
656 *(((
char *)SDDS_dataset->data[index]) + row) = (char)va_arg(argptr,
int);
658 *(((
char *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr,
char *));
661 SDDS_SetError(
"Unknown data type encountered (SDDS_SetRowValues");
665 }
while (retval == -1);
670char **process_name_options(
char **orig_name,
long orig_names,
char **
delete,
long deletes,
char **retain,
long retains,
long *num_matched,
long **origToNewIndex) {
674 long *orig_flag = NULL;
676 orig_flag =
tmalloc(
sizeof(*orig_flag) * orig_names);
677 for (i = 0; i < orig_names; i++)
681 for (i = 0; i < deletes; i++) {
686 for (j = 0; j < orig_names; j++) {
687 for (i = 0; i < deletes; i++) {
694 for (i = 0; i < deletes; i++) {
701 for (i = 0; i < retains; i++) {
707 for (j = 0; j < orig_names; j++)
709 for (j = 0; j < orig_names; j++) {
712 for (i = 0; i < retains; i++) {
719 for (i = 0; i < retains; i++) {
726 for (j = 0; j < orig_names; j++) {
730 new_name =
tmalloc(
sizeof(*new_name) * (*num_matched));
732 for (j = 0; j < orig_names; j++) {
734 (*origToNewIndex)[j] = i;
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_LengthenTable(SDDS_DATASET *SDDS_dataset, int64_t n_additional_rows)
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_DefineSimpleColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *unit, int32_t type)
Defines a simple data column within the SDDS dataset.
int32_t SDDS_DefineSimpleColumns(SDDS_DATASET *SDDS_dataset, int32_t number, char **name, char **unit, int32_t type)
Defines multiple simple data columns of the same data type within the SDDS dataset.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
void SDDS_FreeArray(SDDS_ARRAY *array)
Frees memory allocated for an SDDS array structure.
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
int32_t SDDS_VerifyArrayExists(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
Verifies the existence of an array in the SDDS dataset based on specified criteria.
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
int32_t SDDS_CheckDataset(SDDS_DATASET *SDDS_dataset, const char *caller)
Validates the SDDS dataset pointer.
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_VerifyColumnExists(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
Verifies the existence of a column in the SDDS dataset based on specified criteria.
int32_t SDDS_CopyString(char **target, const char *source)
Copies a source string to a target string with memory allocation.
#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 * 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.
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.
long replaceFileAndBackUp(char *file, char *replacement)
Replaces a file with a replacement file and creates a backup of the original.
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.
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.