125 {
127 SCANNED_ARG *s_arg;
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;
134 long snapshot;
135 double snapshotTime, minimumInterval, previousOutputTime, startTime, endTime;
136 short filterTime;
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;
147
149 argc =
scanargs(&s_arg, argc, argv);
150 if (argc < 3) {
151 fprintf(stderr, "%s", USAGE);
152 exit(EXIT_FAILURE);
153 }
154
155 input = output = NULL;
156 retainName = deleteName = NULL;
157 retainNames = deleteNames = 0;
158 noWarnings = tmpfile_used = 0;
159 pipeFlags = 0;
160 ascii_output = binary_output = 0;
162 snapshot = 0;
163 snapshotTime = 0;
164 minimumInterval = -1;
165 previousOutputTime = -MAXDOUBLE;
166 filterTime = 0;
167 startTime = -MAXDOUBLE;
168 endTime = MAXDOUBLE;
169
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)) {
174 case SET_BINARY:
175 binary_output = 1;
176 ascii_output = 0;
177 break;
178 case SET_ASCII:
179 ascii_output = 1;
180 binary_output = 0;
181 break;
182 case SET_FLOAT:
184 break;
185 case SET_DOUBLE:
187 break;
188 case SET_SNAPSHOT:
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");
192 exit(EXIT_FAILURE);
193 }
194 snapshot = 1;
195 break;
196 case SET_PIPE:
197 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags)) {
198 fprintf(stderr, "invalid -pipe syntax\n");
199 exit(EXIT_FAILURE);
200 }
201 break;
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");
206 exit(EXIT_FAILURE);
207 }
208 break;
209 case SET_TIME:
210 s_arg[i_arg].n_items -= 1;
211 filterTime = 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");
216 exit(EXIT_FAILURE);
217 }
218 s_arg[i_arg].n_items += 1;
219 break;
220 case SET_RETAIN:
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;
225 break;
226 case SET_DELETE:
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;
231 break;
232 default:
233 fprintf(stderr, "Error (%s): unknown switch: %s\n", argv[0], s_arg[i_arg].list[0]);
234 exit(EXIT_FAILURE);
235 }
236 } else {
237 if (input == NULL)
238 input = s_arg[i_arg].list[0];
239 else if (output == NULL)
240 output = s_arg[i_arg].list[0];
241 else {
242 fprintf(stderr, "too many filenames\n");
243 exit(EXIT_FAILURE);
244 }
245 }
246 }
247
248 if (snapshot && minimumInterval >= 0) {
249 fprintf(stderr, "-snapshot and -minimumInterval options cannot be used together\n");
250 exit(EXIT_FAILURE);
251 }
252 if (snapshot && filterTime) {
253 fprintf(stderr, "-snapshot and -time options cannot be used together\n");
254 exit(EXIT_FAILURE);
255 }
256
257 processFilenames(
"sddsconvertalarmlog", &input, &output, pipeFlags, noWarnings, &tmpfile_used);
258
261 exit(EXIT_FAILURE);
262 }
263
268 hasRelatedControlNameString =
SDDS_CheckArray(&SDDS_input,
"RelatedControlNameString", NULL,
SDDS_STRING, NULL) == SDDS_CHECK_OK;
280
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");
290 exit(EXIT_FAILURE);
291 }
292 if (!hasTime && !hasTimeOfDay) {
293 fprintf(stderr, "Error: TimeOfDay column is missing and no Time column is available.\n");
294 exit(EXIT_FAILURE);
295 }
296
297 for (i = 0; i < N_OUTPUT_COLUMNS; i++) {
298 available[i] = NameSelected(outputColumnName[i], deleteName, deleteNames, retainName, retainNames);
299 outIndex[i] = -1;
300 }
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;
308
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) ||
316 exit(EXIT_FAILURE);
317 }
318
319 allocatedRows = 0;
320 outputRows = 0;
321 copiedParameters = 0;
322 snapshotEvent = NULL;
323 snapshotEvents = 0;
324
325 if (!SDDS_StartTable(&SDDS_output, 0)) {
327 exit(EXIT_FAILURE);
328 }
329
330 while (SDDS_ReadTable(&SDDS_input) > 0) {
331 int64_t row, rows;
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;
339
340 rows = SDDS_RowCount(&SDDS_input);
341 if (!copiedParameters) {
344 exit(EXIT_FAILURE);
345 }
346 copiedParameters = 1;
347 }
348
349 pageStartTime = pageStartHour = 0;
350 if (!hasTime &&
353 fprintf(stderr, "Error: StartTime and StartHour parameters are required when Time is absent.\n");
354 exit(EXIT_FAILURE);
355 }
356
362 controlNameIndexData = alarmStatusIndexData = alarmSeverityIndexData = NULL;
363 controlNameData = alarmStatusData = alarmSeverityData = NULL;
364 descriptionData = relatedControlNameData = relatedValueStringData = NULL;
365 controlNameArray = alarmStatusArray = alarmSeverityArray = NULL;
366 descriptionArray = relatedControlNameArray = NULL;
367
368 if ((hasTime && !timeData) || (hasTimeOfDay && !timeOfDayData) ||
369 (hasTimeOfDayWS && !timeOfDayWSData) || (hasDuration && !durationData) ||
370 (hasPreviousRow && !previousRowData)) {
372 exit(EXIT_FAILURE);
373 }
374
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)) {
389 exit(EXIT_FAILURE);
390 }
391 }
392 if (hasControlName)
394 if (hasAlarmStatus)
396 if (hasAlarmSeverity)
398 if (hasDescription)
400 if (hasRelatedControlName)
401 relatedControlNameData =
SDDS_GetColumn(&SDDS_input,
"RelatedControlName");
402 if (hasRelatedValueString)
403 relatedValueStringData =
SDDS_GetColumn(&SDDS_input,
"RelatedValueString");
404
405 if ((hasControlName && !controlNameData) || (hasAlarmStatus && !alarmStatusData) ||
406 (hasAlarmSeverity && !alarmSeverityData) || (hasDescription && !descriptionData) ||
407 (hasRelatedControlName && !relatedControlNameData) ||
408 (hasRelatedValueString && !relatedValueStringData)) {
410 exit(EXIT_FAILURE);
411 }
412
413 for (row = 0; row < rows; row++) {
415 int32_t controlIndex, statusIndex, severityIndex;
416
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);
423
424 if (filterTime && (event.time < startTime || event.time > endTime))
425 continue;
426
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);
436 } else {
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);
442 }
443 event.relatedValueString = StringColumnValue(relatedValueStringData, row);
444
445 if (!event.controlName || !event.alarmStatus || !event.alarmSeverity)
446 continue;
447
448 if (snapshot) {
449 if (event.time <= snapshotTime && !SaveSnapshotEvent(&snapshotEvent, &snapshotEvents, &event)) {
451 exit(EXIT_FAILURE);
452 }
453 } else {
454 if (minimumInterval > 0 && event.time - previousOutputTime <= minimumInterval)
455 continue;
456 if (!EnsureRows(&SDDS_output, &allocatedRows, outputRows + 1) ||
457 !WriteAlarmEvent(&SDDS_output, outIndex, outputRows, &event)) {
459 exit(EXIT_FAILURE);
460 }
461 previousOutputTime = event.time;
462 outputRows++;
463 }
464 }
465
466 if (timeData)
467 free(timeData);
468 if (timeOfDayData)
469 free(timeOfDayData);
470 if (timeOfDayWSData)
471 free(timeOfDayWSData);
472 if (durationData)
473 free(durationData);
474 if (previousRowData)
475 free(previousRowData);
476 if (controlNameIndexData)
477 free(controlNameIndexData);
478 if (alarmStatusIndexData)
479 free(alarmStatusIndexData);
480 if (alarmSeverityIndexData)
481 free(alarmSeverityIndexData);
482 if (controlNameData)
484 if (alarmStatusData)
486 if (alarmSeverityData)
488 if (descriptionData)
490 if (relatedControlNameData)
492 if (relatedValueStringData)
494 if (controlNameArray)
496 if (alarmStatusArray)
498 if (alarmSeverityArray)
500 if (descriptionArray)
502 if (relatedControlNameArray)
504 }
505
506 if (snapshot) {
507 for (i = 0; i < snapshotEvents; i++) {
508 if (!snapshotEvent[i].used)
509 continue;
510 if (!EnsureRows(&SDDS_output, &allocatedRows, outputRows + 1) ||
511 !WriteAlarmEvent(&SDDS_output, outIndex, outputRows, snapshotEvent + i)) {
513 exit(EXIT_FAILURE);
514 }
515 outputRows++;
516 }
517 }
518
519 if (!SDDS_WriteTable(&SDDS_output) ||
523 exit(EXIT_FAILURE);
524 }
525
526 if (snapshotEvent) {
527 for (i = 0; i < snapshotEvents; i++)
528 ClearAlarmEvent(snapshotEvent + i);
529 free(snapshotEvent);
530 }
531 if (retainName)
532 free(retainName);
533 if (deleteName)
534 free(deleteName);
536 exit(EXIT_FAILURE);
538 return EXIT_SUCCESS;
539}
int32_t SDDS_CopyParameters(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
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_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.
#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.