39 COL_RELATED_CONTROL_NAME,
41 COL_RELATED_VALUE_STRING,
55 char *relatedControlName;
57 char *relatedValueString;
60#if !defined(MAXDOUBLE)
61# define MAXDOUBLE 1.79769313486231570e+308
64static char *option[N_OPTIONS] = {
76static const char *outputColumnName[N_OUTPUT_COLUMNS] = {
87 "RelatedValueString"};
90 "Usage: sddsconvertalarmlog [<input-file>] [<output-file>]\n"
91 " [-pipe=[input][,output]]\n"
92 " [-binary | -ascii]\n"
93 " [-float | -double]\n"
94 " [-minimumInterval=<seconds>]\n"
95 " [-snapshot=<epochtime>]\n"
96 " [-time=[start=<epochtime>][,end=<epochtime>]]\n"
97 " [-delete=<column-names>]\n"
98 " [-retain=<column-names>]\n"
100 " -pipe=[input][,output] Use pipe for input and/or output.\n"
101 " -binary Output in binary format.\n"
102 " -ascii Output in ASCII format.\n"
103 " -double Use double precision for the computed Time column.\n"
104 " -float Use float precision for the computed Time column.\n"
105 " -minimumInterval=<seconds> Set minimum interval between output rows.\n"
106 " -snapshot=<epochtime> Output the latest alarm state for each PV at the epoch time.\n"
107 " -time=[start=<epochtime>][,end=<epochtime>]\n"
108 " Filter data by epoch time range.\n"
109 " -delete={<matching-string>[,...]} Delete output columns matching the pattern.\n"
110 " -retain={<matching-string>[,...]} Retain only output columns matching the pattern.\n"
111 "\nProgram by Robert Soliday. (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")\n";
113static int NameMatchesList(
const char *name,
char **list,
long items);
114static int NameSelected(
const char *name,
char **deleteName,
long deleteNames,
char **retainName,
long retainNames);
115static int DefineOutputColumns(
SDDS_DATASET *outSet, int32_t *outIndex,
int *available,
long outputType);
116static int EnsureRows(
SDDS_DATASET *outSet, int64_t *allocatedRows, int64_t neededRows);
118static double ComputeEpochTime(
double timeOfDay,
double startTime,
double startHour);
119static char *ArrayString(
SDDS_ARRAY *array, int32_t index);
120static char *StringColumnValue(
char **column, int64_t row);
122static int CopyStringOrBlank(
char **target,
const char *source);
125int main(
int argc,
char **argv) {
128 char *input, *output;
129 char **retainName, **deleteName;
130 long retainNames, deleteNames;
131 long i, i_arg, noWarnings, tmpfile_used;
132 unsigned long pipeFlags, flags;
133 long ascii_output, binary_output, outputType;
135 double snapshotTime, minimumInterval, previousOutputTime, startTime, endTime;
137 int32_t outIndex[N_OUTPUT_COLUMNS];
138 int available[N_OUTPUT_COLUMNS];
139 int hasIndexedData, hasExplicitData, copiedParameters;
140 int hasControlNameString, hasAlarmStatusString, hasAlarmSeverityString;
141 int hasDescriptionString, hasRelatedControlNameString;
142 int hasControlName, hasAlarmStatus, hasAlarmSeverity;
143 int hasDescription, hasRelatedControlName, hasDuration, hasRelatedValueString;
144 int hasPreviousRow, hasTimeOfDayWS, hasTimeOfDay, hasTime;
145 int64_t allocatedRows, outputRows, snapshotEvents;
149 argc =
scanargs(&s_arg, argc, argv);
151 fprintf(stderr,
"%s", USAGE);
155 input = output = NULL;
156 retainName = deleteName = NULL;
157 retainNames = deleteNames = 0;
158 noWarnings = tmpfile_used = 0;
160 ascii_output = binary_output = 0;
164 minimumInterval = -1;
165 previousOutputTime = -MAXDOUBLE;
167 startTime = -MAXDOUBLE;
170 for (i_arg = 1; i_arg < argc; i_arg++) {
171 if (s_arg[i_arg].arg_type == OPTION) {
173 switch (
match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
189 if (s_arg[i_arg].n_items < 2 ||
190 sscanf(s_arg[i_arg].list[1],
"%lf", &snapshotTime) != 1) {
191 fprintf(stderr,
"invalid -snapshot syntax or value\n");
197 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags)) {
198 fprintf(stderr,
"invalid -pipe syntax\n");
202 case SET_MININTERVAL:
203 if (s_arg[i_arg].n_items < 2 ||
204 sscanf(s_arg[i_arg].list[1],
"%lf", &minimumInterval) != 1) {
205 fprintf(stderr,
"invalid -minimumInterval syntax or value\n");
210 s_arg[i_arg].n_items -= 1;
212 if (!
scanItemList(&flags, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
215 fprintf(stderr,
"invalid -time syntax\n");
218 s_arg[i_arg].n_items += 1;
221 retainName =
trealloc(retainName,
sizeof(*retainName) * (retainNames + s_arg[i_arg].n_items - 1));
222 for (i = 1; i < s_arg[i_arg].n_items; i++)
223 retainName[i - 1 + retainNames] = s_arg[i_arg].list[i];
224 retainNames += s_arg[i_arg].n_items - 1;
227 deleteName =
trealloc(deleteName,
sizeof(*deleteName) * (deleteNames + s_arg[i_arg].n_items - 1));
228 for (i = 1; i < s_arg[i_arg].n_items; i++)
229 deleteName[i - 1 + deleteNames] = s_arg[i_arg].list[i];
230 deleteNames += s_arg[i_arg].n_items - 1;
233 fprintf(stderr,
"Error (%s): unknown switch: %s\n", argv[0], s_arg[i_arg].list[0]);
238 input = s_arg[i_arg].list[0];
239 else if (output == NULL)
240 output = s_arg[i_arg].list[0];
242 fprintf(stderr,
"too many filenames\n");
248 if (snapshot && minimumInterval >= 0) {
249 fprintf(stderr,
"-snapshot and -minimumInterval options cannot be used together\n");
252 if (snapshot && filterTime) {
253 fprintf(stderr,
"-snapshot and -time options cannot be used together\n");
257 processFilenames(
"sddsconvertalarmlog", &input, &output, pipeFlags, noWarnings, &tmpfile_used);
268 hasRelatedControlNameString =
SDDS_CheckArray(&SDDS_input,
"RelatedControlNameString", NULL,
SDDS_STRING, NULL) == SDDS_CHECK_OK;
281 hasIndexedData = hasControlNameString && hasAlarmStatusString && hasAlarmSeverityString &&
285 hasExplicitData = hasControlName && hasAlarmStatus && hasAlarmSeverity;
286 if (!hasIndexedData && !hasExplicitData) {
287 fprintf(stderr,
"Error: input file has neither indexed alarm-log data nor explicit alarm-log columns.\n");
288 fprintf(stderr,
" Expected ControlNameString/AlarmStatusString/AlarmSeverityString arrays with index columns,\n");
289 fprintf(stderr,
" or ControlName/AlarmStatus/AlarmSeverity string columns.\n");
292 if (!hasTime && !hasTimeOfDay) {
293 fprintf(stderr,
"Error: TimeOfDay column is missing and no Time column is available.\n");
297 for (i = 0; i < N_OUTPUT_COLUMNS; i++) {
298 available[i] = NameSelected(outputColumnName[i], deleteName, deleteNames, retainName, retainNames);
301 available[COL_PREVIOUS_ROW] = available[COL_PREVIOUS_ROW] && hasPreviousRow;
302 available[COL_TIME_OF_DAY_WS] = available[COL_TIME_OF_DAY_WS] && hasTimeOfDayWS;
303 available[COL_TIME_OF_DAY] = available[COL_TIME_OF_DAY] && hasTimeOfDay;
304 available[COL_DESCRIPTION] = available[COL_DESCRIPTION] && (hasDescription || (hasIndexedData && hasDescriptionString));
305 available[COL_RELATED_CONTROL_NAME] = available[COL_RELATED_CONTROL_NAME] && (hasRelatedControlName || (hasIndexedData && hasRelatedControlNameString));
306 available[COL_DURATION] = available[COL_DURATION] && hasDuration;
307 available[COL_RELATED_VALUE_STRING] = available[COL_RELATED_VALUE_STRING] && hasRelatedValueString;
310 ascii_output ? SDDS_ASCII : (binary_output ? SDDS_BINARY : SDDS_input.layout.data_mode.mode),
311 1, NULL, NULL, output) ||
313 !DefineOutputColumns(&SDDS_output, outIndex, available, outputType) ||
321 copiedParameters = 0;
322 snapshotEvent = NULL;
325 if (!SDDS_StartTable(&SDDS_output, 0)) {
330 while (SDDS_ReadTable(&SDDS_input) > 0) {
332 double pageStartTime, pageStartHour;
333 double *timeData, *timeOfDayData, *timeOfDayWSData, *durationData, *previousRowData;
334 int32_t *controlNameIndexData, *alarmStatusIndexData, *alarmSeverityIndexData;
335 char **controlNameData, **alarmStatusData, **alarmSeverityData;
336 char **descriptionData, **relatedControlNameData, **relatedValueStringData;
337 SDDS_ARRAY *controlNameArray, *alarmStatusArray, *alarmSeverityArray;
338 SDDS_ARRAY *descriptionArray, *relatedControlNameArray;
340 rows = SDDS_RowCount(&SDDS_input);
341 if (!copiedParameters) {
346 copiedParameters = 1;
349 pageStartTime = pageStartHour = 0;
353 fprintf(stderr,
"Error: StartTime and StartHour parameters are required when Time is absent.\n");
362 controlNameIndexData = alarmStatusIndexData = alarmSeverityIndexData = NULL;
363 controlNameData = alarmStatusData = alarmSeverityData = NULL;
364 descriptionData = relatedControlNameData = relatedValueStringData = NULL;
365 controlNameArray = alarmStatusArray = alarmSeverityArray = NULL;
366 descriptionArray = relatedControlNameArray = NULL;
368 if ((hasTime && !timeData) || (hasTimeOfDay && !timeOfDayData) ||
369 (hasTimeOfDayWS && !timeOfDayWSData) || (hasDuration && !durationData) ||
370 (hasPreviousRow && !previousRowData)) {
375 if (hasIndexedData) {
379 controlNameArray =
SDDS_GetArray(&SDDS_input,
"ControlNameString", NULL);
380 alarmStatusArray =
SDDS_GetArray(&SDDS_input,
"AlarmStatusString", NULL);
381 alarmSeverityArray =
SDDS_GetArray(&SDDS_input,
"AlarmSeverityString", NULL);
382 descriptionArray = hasDescriptionString ?
SDDS_GetArray(&SDDS_input,
"DescriptionString", NULL) : NULL;
383 relatedControlNameArray = hasRelatedControlNameString ?
SDDS_GetArray(&SDDS_input,
"RelatedControlNameString", NULL) : NULL;
384 if (!controlNameIndexData || !alarmStatusIndexData || !alarmSeverityIndexData ||
385 !controlNameArray || !alarmStatusArray || !alarmSeverityArray ||
386 (hasDescriptionString && !descriptionArray) ||
387 (hasRelatedControlNameString && !relatedControlNameArray)) {
396 if (hasAlarmSeverity)
400 if (hasRelatedControlName)
401 relatedControlNameData =
SDDS_GetColumn(&SDDS_input,
"RelatedControlName");
402 if (hasRelatedValueString)
403 relatedValueStringData =
SDDS_GetColumn(&SDDS_input,
"RelatedValueString");
405 if ((hasControlName && !controlNameData) || (hasAlarmStatus && !alarmStatusData) ||
406 (hasAlarmSeverity && !alarmSeverityData) || (hasDescription && !descriptionData) ||
407 (hasRelatedControlName && !relatedControlNameData) ||
408 (hasRelatedValueString && !relatedValueStringData)) {
413 for (row = 0; row < rows; row++) {
415 int32_t controlIndex, statusIndex, severityIndex;
417 memset(&event, 0,
sizeof(event));
418 event.previousRow = hasPreviousRow ? (int32_t)previousRowData[row] : -1;
419 event.timeOfDay = hasTimeOfDay ? (float)timeOfDayData[row] : 0;
420 event.timeOfDayWS = hasTimeOfDayWS ? (float)timeOfDayWSData[row] : 0;
421 event.duration = hasDuration ? (float)durationData[row] : 0;
422 event.time = hasTime ? timeData[row] : ComputeEpochTime(timeOfDayData[row], pageStartTime, pageStartHour);
424 if (filterTime && (event.time < startTime || event.time > endTime))
427 if (hasIndexedData) {
428 controlIndex = controlNameIndexData[row];
429 statusIndex = alarmStatusIndexData[row];
430 severityIndex = alarmSeverityIndexData[row];
431 event.controlName = ArrayString(controlNameArray, controlIndex);
432 event.alarmStatus = ArrayString(alarmStatusArray, statusIndex);
433 event.alarmSeverity = ArrayString(alarmSeverityArray, severityIndex);
434 event.description = hasDescription ? StringColumnValue(descriptionData, row) : ArrayString(descriptionArray, controlIndex);
435 event.relatedControlName = hasRelatedControlName ? StringColumnValue(relatedControlNameData, row) : ArrayString(relatedControlNameArray, controlIndex);
437 event.controlName = StringColumnValue(controlNameData, row);
438 event.alarmStatus = StringColumnValue(alarmStatusData, row);
439 event.alarmSeverity = StringColumnValue(alarmSeverityData, row);
440 event.description = StringColumnValue(descriptionData, row);
441 event.relatedControlName = StringColumnValue(relatedControlNameData, row);
443 event.relatedValueString = StringColumnValue(relatedValueStringData, row);
445 if (!event.controlName || !event.alarmStatus || !event.alarmSeverity)
449 if (event.time <= snapshotTime && !SaveSnapshotEvent(&snapshotEvent, &snapshotEvents, &event)) {
454 if (minimumInterval > 0 && event.time - previousOutputTime <= minimumInterval)
456 if (!EnsureRows(&SDDS_output, &allocatedRows, outputRows + 1) ||
457 !WriteAlarmEvent(&SDDS_output, outIndex, outputRows, &event)) {
461 previousOutputTime =
event.time;
471 free(timeOfDayWSData);
475 free(previousRowData);
476 if (controlNameIndexData)
477 free(controlNameIndexData);
478 if (alarmStatusIndexData)
479 free(alarmStatusIndexData);
480 if (alarmSeverityIndexData)
481 free(alarmSeverityIndexData);
486 if (alarmSeverityData)
490 if (relatedControlNameData)
492 if (relatedValueStringData)
494 if (controlNameArray)
496 if (alarmStatusArray)
498 if (alarmSeverityArray)
500 if (descriptionArray)
502 if (relatedControlNameArray)
507 for (i = 0; i < snapshotEvents; i++) {
508 if (!snapshotEvent[i].used)
510 if (!EnsureRows(&SDDS_output, &allocatedRows, outputRows + 1) ||
511 !WriteAlarmEvent(&SDDS_output, outIndex, outputRows, snapshotEvent + i)) {
519 if (!SDDS_WriteTable(&SDDS_output) ||
527 for (i = 0; i < snapshotEvents; i++)
528 ClearAlarmEvent(snapshotEvent + i);
541static int NameMatchesList(
const char *name,
char **list,
long items) {
546 for (i = 0; i < items; i++) {
557static int NameSelected(
const char *name,
char **deleteName,
long deleteNames,
char **retainName,
long retainNames) {
561 if (deleteNames && NameMatchesList(name, deleteName, deleteNames))
566 if (NameMatchesList(name, retainName, retainNames))
572static int DefineOutputColumns(
SDDS_DATASET *outSet, int32_t *outIndex,
int *available,
long outputType) {
573 if (available[COL_TIME] &&
574 0 > (outIndex[COL_TIME] =
SDDS_DefineColumn(outSet,
"Time", NULL,
"s",
"Computed epoch time", NULL, outputType, 0)))
576 if (available[COL_PREVIOUS_ROW] &&
579 if (available[COL_TIME_OF_DAY_WS] &&
580 0 > (outIndex[COL_TIME_OF_DAY_WS] =
SDDS_DefineColumn(outSet,
"TimeOfDayWS", NULL,
"h",
"Time of day in hours per workstation",
"%8.5f",
SDDS_FLOAT, 0)))
582 if (available[COL_TIME_OF_DAY] &&
583 0 > (outIndex[COL_TIME_OF_DAY] =
SDDS_DefineColumn(outSet,
"TimeOfDay", NULL,
"h",
"Time of day in hours per IOC",
"%8.5f",
SDDS_FLOAT, 0)))
585 if (available[COL_CONTROL_NAME] &&
588 if (available[COL_ALARM_STATUS] &&
591 if (available[COL_ALARM_SEVERITY] &&
594 if (available[COL_DESCRIPTION] &&
597 if (available[COL_RELATED_CONTROL_NAME] &&
600 if (available[COL_DURATION] &&
603 if (available[COL_RELATED_VALUE_STRING] &&
609static int EnsureRows(
SDDS_DATASET *outSet, int64_t *allocatedRows, int64_t neededRows) {
612 if (neededRows <= *allocatedRows)
614 increment = neededRows - *allocatedRows;
619 *allocatedRows += increment;
624 if (outIndex[COL_TIME] >= 0 &&
625 !
SDDS_SetRowValues(outSet, SDDS_PASS_BY_VALUE | SDDS_SET_BY_INDEX, row, outIndex[COL_TIME], event->time, -1))
627 if (outIndex[COL_PREVIOUS_ROW] >= 0 &&
628 !
SDDS_SetRowValues(outSet, SDDS_PASS_BY_VALUE | SDDS_SET_BY_INDEX, row, outIndex[COL_PREVIOUS_ROW], event->previousRow, -1))
630 if (outIndex[COL_TIME_OF_DAY_WS] >= 0 &&
631 !
SDDS_SetRowValues(outSet, SDDS_PASS_BY_VALUE | SDDS_SET_BY_INDEX, row, outIndex[COL_TIME_OF_DAY_WS], event->timeOfDayWS, -1))
633 if (outIndex[COL_TIME_OF_DAY] >= 0 &&
634 !
SDDS_SetRowValues(outSet, SDDS_PASS_BY_VALUE | SDDS_SET_BY_INDEX, row, outIndex[COL_TIME_OF_DAY], event->timeOfDay, -1))
636 if (outIndex[COL_CONTROL_NAME] >= 0 &&
637 !
SDDS_SetRowValues(outSet, SDDS_PASS_BY_VALUE | SDDS_SET_BY_INDEX, row, outIndex[COL_CONTROL_NAME], event->controlName ? event->controlName :
"", -1))
639 if (outIndex[COL_ALARM_STATUS] >= 0 &&
640 !
SDDS_SetRowValues(outSet, SDDS_PASS_BY_VALUE | SDDS_SET_BY_INDEX, row, outIndex[COL_ALARM_STATUS], event->alarmStatus ? event->alarmStatus :
"", -1))
642 if (outIndex[COL_ALARM_SEVERITY] >= 0 &&
643 !
SDDS_SetRowValues(outSet, SDDS_PASS_BY_VALUE | SDDS_SET_BY_INDEX, row, outIndex[COL_ALARM_SEVERITY], event->alarmSeverity ? event->alarmSeverity :
"", -1))
645 if (outIndex[COL_DESCRIPTION] >= 0 &&
646 !
SDDS_SetRowValues(outSet, SDDS_PASS_BY_VALUE | SDDS_SET_BY_INDEX, row, outIndex[COL_DESCRIPTION], event->description ? event->description :
"", -1))
648 if (outIndex[COL_RELATED_CONTROL_NAME] >= 0 &&
649 !
SDDS_SetRowValues(outSet, SDDS_PASS_BY_VALUE | SDDS_SET_BY_INDEX, row, outIndex[COL_RELATED_CONTROL_NAME], event->relatedControlName ? event->relatedControlName :
"", -1))
651 if (outIndex[COL_DURATION] >= 0 &&
652 !
SDDS_SetRowValues(outSet, SDDS_PASS_BY_VALUE | SDDS_SET_BY_INDEX, row, outIndex[COL_DURATION], event->duration, -1))
654 if (outIndex[COL_RELATED_VALUE_STRING] >= 0 &&
655 !
SDDS_SetRowValues(outSet, SDDS_PASS_BY_VALUE | SDDS_SET_BY_INDEX, row, outIndex[COL_RELATED_VALUE_STRING], event->relatedValueString ? event->relatedValueString :
"", -1))
660static double ComputeEpochTime(
double timeOfDay,
double startTime,
double startHour) {
663 deltaHours = timeOfDay - startHour;
664 if (deltaHours < -12)
666 return startTime + 3600 * deltaHours;
669static char *ArrayString(
SDDS_ARRAY *array, int32_t index) {
670 if (!array || index < 0 || index >= array->elements)
672 return ((
char **)array->data)[index];
675static char *StringColumnValue(
char **column, int64_t row) {
684 if (event->controlName)
685 free(event->controlName);
686 if (event->alarmStatus)
687 free(event->alarmStatus);
688 if (event->alarmSeverity)
689 free(event->alarmSeverity);
690 if (event->description)
691 free(event->description);
692 if (event->relatedControlName)
693 free(event->relatedControlName);
694 if (event->relatedValueString)
695 free(event->relatedValueString);
696 memset(event, 0,
sizeof(*event));
699static int CopyStringOrBlank(
char **target,
const char *source) {
709 for (i = 0; i < *snapshotEvents; i++) {
710 if ((*snapshotEvent)[i].used && strcmp((*snapshotEvent)[i].controlName, event->controlName) == 0)
713 if (i == *snapshotEvents) {
714 *snapshotEvent =
trealloc(*snapshotEvent,
sizeof(**snapshotEvent) * (*snapshotEvents + 1));
715 memset(*snapshotEvent + *snapshotEvents, 0,
sizeof(**snapshotEvent));
718 ClearAlarmEvent(*snapshotEvent + i);
721 item = *snapshotEvent + i;
723 item->time =
event->time;
724 item->previousRow =
event->previousRow;
725 item->timeOfDayWS =
event->timeOfDayWS;
726 item->timeOfDay =
event->timeOfDay;
727 item->duration =
event->duration;
728 if (!CopyStringOrBlank(&item->controlName, event->controlName) ||
729 !CopyStringOrBlank(&item->alarmStatus, event->alarmStatus) ||
730 !CopyStringOrBlank(&item->alarmSeverity, event->alarmSeverity) ||
731 !CopyStringOrBlank(&item->description, event->description) ||
732 !CopyStringOrBlank(&item->relatedControlName, event->relatedControlName) ||
733 !CopyStringOrBlank(&item->relatedValueString, event->relatedValueString))
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_CopyParameters(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
int32_t SDDS_LengthenTable(SDDS_DATASET *SDDS_dataset, int64_t n_additional_rows)
int32_t SDDS_SetRowValues(SDDS_DATASET *SDDS_dataset, int32_t mode, int64_t row,...)
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_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_TransferAllParameterDefinitions(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, uint32_t mode)
Transfers all parameter definitions from a source dataset to a target dataset.
void SDDS_FreeArray(SDDS_ARRAY *array)
Frees memory allocated for an SDDS array structure.
int32_t SDDS_CheckArray(SDDS_DATASET *SDDS_dataset, char *name, char *units, int32_t type, FILE *fp_message)
Checks if an array exists in the SDDS dataset with the specified name, units, and type.
int32_t SDDS_FreeStringArray(char **string, int64_t strings)
Frees an array of strings by deallocating each individual string.
int32_t SDDS_CheckColumn(SDDS_DATASET *SDDS_dataset, char *name, char *units, int32_t type, FILE *fp_message)
Checks if a column exists in the SDDS dataset with the specified name, units, and type.
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_CopyString(char **target, const char *source)
Copies a source string to a target string with memory allocation.
#define SDDS_FLOAT
Identifier for the float data type.
#define SDDS_STRING
Identifier for the string data type.
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
#define SDDS_ANY_NUMERIC_TYPE
Special identifier used by SDDS_Check*() routines to accept any numeric type.
#define SDDS_DOUBLE
Identifier for the double data type.
#define SDDS_ANY_INTEGER_TYPE
Special identifier used by SDDS_Check*() routines to accept any integer type.
void * trealloc(void *old_ptr, uint64_t size_of_block)
Reallocates a memory block to a new size.
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.