SDDS ToolKit Programs and Libraries for C and Python
Loading...
Searching...
No Matches
sddscombinelogfiles.c File Reference

Detailed Description

Combines multiple SDDS log files into a single file, retaining only common timestamps.

This program processes SDDS log files in the one-PV-per-file format, merging them into a single SDDS file. It retains only the timestamps common across all input files and supports flexible input-output configurations such as pipe-based I/O and overwriting existing output files.

Usage

sddscombinelogfiles [<SDDSinputfilelist>] [<SDDSoutputfile>]
[-pipe=[output]]
[-overwrite]
[-threads=<number>]

Options

Option Description
-pipe Use pipe output for the SDDS file instead of writing to a file.
-overwrite Overwrite the output file if it already exists.
-threads Number of input files to load concurrently.
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
R. Soliday, L. Emery

Definition in file sddscombinelogfiles.c.

#include "mdb.h"
#include "scan.h"
#include "SDDS.h"

Go to the source code of this file.

Functions

static int LoadLogFile (const char *filename, LOG_FILE_DATA *logFile)
 
static void FreeLogFileData (LOG_FILE_DATA *logFile)
 
int main (int argc, char **argv)
 

Function Documentation

◆ FreeLogFileData()

static void FreeLogFileData ( LOG_FILE_DATA * logFile)
static

Definition at line 621 of file sddscombinelogfiles.c.

621 {
622 int page;
623 if (!logFile)
624 return;
625 for (page = 0; page < logFile->pages; page++) {
626 free(logFile->page[page].timeValues);
627 free(logFile->page[page].dataValues);
628 free(logFile->page[page].dataName);
629 }
630 free(logFile->page);
631 logFile->page = NULL;
632 logFile->pages = 0;
633}

◆ LoadLogFile()

static int LoadLogFile ( const char * filename,
LOG_FILE_DATA * logFile )
static

Definition at line 480 of file sddscombinelogfiles.c.

480 {
481 SDDS_DATASET SDDS_input;
482 char **columnname = NULL;
483 int32_t columnnames = 0;
484 int dataIndex = -1;
485 int32_t readCode;
486 int64_t j;
487 int initialized = 0;
488
489 logFile->page = NULL;
490 logFile->pages = 0;
491 logFile->status = 0;
492 logFile->error[0] = 0;
493
494 if (!SDDS_InitializeInput(&SDDS_input, (char *)filename)) {
495 snprintf(logFile->error, sizeof(logFile->error), "Error: Unable to open '%s'.", filename);
496 return 0;
497 }
498 initialized = 1;
499
500 columnname = SDDS_GetColumnNames(&SDDS_input, &columnnames);
501 if (columnname == NULL) {
502 snprintf(logFile->error, sizeof(logFile->error), "Error: Unable to read column names from '%s'.", filename);
503 goto fail;
504 }
505
506 if (columnnames > 3 || columnnames < 2) {
507 snprintf(logFile->error, sizeof(logFile->error), "Error: Unexpected number of columns in '%s'.", filename);
508 goto fail;
509 }
510
511 if (columnnames == 2) {
512 if (strcmp("Time", columnname[0]) == 0) {
513 dataIndex = 1;
514 } else if (strcmp("Time", columnname[1]) == 0) {
515 dataIndex = 0;
516 } else {
517 snprintf(logFile->error, sizeof(logFile->error), "Error: 'Time' column is missing in '%s'.", filename);
518 goto fail;
519 }
520 }
521
522 if (columnnames == 3) {
523 if (strcmp("CAerrors", columnname[0]) == 0) {
524 if (strcmp("Time", columnname[1]) == 0) {
525 dataIndex = 2;
526 } else if (strcmp("Time", columnname[2]) == 0) {
527 dataIndex = 1;
528 } else {
529 snprintf(logFile->error, sizeof(logFile->error), "Error: 'Time' column is missing in '%s'.", filename);
530 goto fail;
531 }
532 } else if (strcmp("CAerrors", columnname[1]) == 0) {
533 if (strcmp("Time", columnname[0]) == 0) {
534 dataIndex = 2;
535 } else if (strcmp("Time", columnname[2]) == 0) {
536 dataIndex = 0;
537 } else {
538 snprintf(logFile->error, sizeof(logFile->error), "Error: 'Time' column is missing in '%s'.", filename);
539 goto fail;
540 }
541 } else if (strcmp("CAerrors", columnname[2]) == 0) {
542 if (strcmp("Time", columnname[0]) == 0) {
543 dataIndex = 1;
544 } else if (strcmp("Time", columnname[1]) == 0) {
545 dataIndex = 0;
546 } else {
547 snprintf(logFile->error, sizeof(logFile->error), "Error: 'Time' column is missing in '%s'.", filename);
548 goto fail;
549 }
550 } else {
551 snprintf(logFile->error, sizeof(logFile->error), "Error: 'CAerrors' column is missing in '%s'.", filename);
552 goto fail;
553 }
554 }
555
556 while ((readCode = SDDS_ReadTable(&SDDS_input)) > 0) {
557 int page = logFile->pages;
558 LOG_PAGE_DATA *pageData;
559 pageData = realloc(logFile->page, sizeof(*logFile->page) * (page + 1));
560 if (!pageData) {
561 snprintf(logFile->error, sizeof(logFile->error), "Error: Memory allocation failure.");
562 goto fail;
563 }
564 logFile->page = pageData;
565 logFile->page[page].timeValues = NULL;
566 logFile->page[page].dataValues = NULL;
567 logFile->page[page].dataName = NULL;
568 logFile->page[page].rows = SDDS_RowCount(&SDDS_input);
569 logFile->pages++;
570
571 if (!SDDS_CopyString(&logFile->page[page].dataName, columnname[dataIndex])) {
572 snprintf(logFile->error, sizeof(logFile->error), "Error: Memory allocation failure.");
573 goto fail;
574 }
575 if (logFile->page[page].rows > 0) {
576 logFile->page[page].timeValues = SDDS_GetColumnInDoubles(&SDDS_input, "Time");
577 if (logFile->page[page].timeValues == NULL) {
578 snprintf(logFile->error, sizeof(logFile->error), "Error: Unable to read 'Time' data from '%s'.", filename);
579 goto fail;
580 }
581
582 logFile->page[page].dataValues = SDDS_GetColumnInDoubles(&SDDS_input, columnname[dataIndex]);
583 if (logFile->page[page].dataValues == NULL) {
584 snprintf(logFile->error, sizeof(logFile->error), "Error: Unable to read '%s' data from '%s'.", columnname[dataIndex], filename);
585 goto fail;
586 }
587 }
588 }
589 if (readCode == 0) {
590 snprintf(logFile->error, sizeof(logFile->error), "Error: Unable to read data from '%s'.", filename);
591 goto fail;
592 }
593
594 for (j = 0; j < columnnames; j++)
595 free(columnname[j]);
596 free(columnname);
597 columnname = NULL;
598
599 if (!SDDS_Terminate(&SDDS_input)) {
600 initialized = 0;
601 snprintf(logFile->error, sizeof(logFile->error), "Error: Unable to close '%s'.", filename);
602 goto fail;
603 }
604 initialized = 0;
605
606 logFile->status = 1;
607 return 1;
608
609fail:
610 if (columnname) {
611 for (j = 0; j < columnnames; j++)
612 free(columnname[j]);
613 free(columnname);
614 }
615 if (initialized)
616 SDDS_Terminate(&SDDS_input);
617 FreeLogFileData(logFile);
618 return 0;
619}
double * SDDS_GetColumnInDoubles(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves the data of a specified numerical column as an array of doubles, considering only rows mark...
int32_t SDDS_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:50
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
char ** SDDS_GetColumnNames(SDDS_DATASET *SDDS_dataset, int32_t *number)
Retrieves the names of all columns in the SDDS dataset.
int32_t SDDS_CopyString(char **target, const char *source)
Copies a source string to a target string with memory allocation.
Definition SDDS_utils.c:922

◆ main()

int main ( int argc,
char ** argv )

Definition at line 85 of file sddscombinelogfiles.c.

85 {
86 SDDS_DATASET SDDS_output;
87 SCANNED_ARG *s_arg;
88 KEYED_EQUIVALENT **keyGroup = NULL;
89 long keyGroups = 0;
90 char **inputfile = NULL;
91 int inputfiles = 0;
92 char *outputfile = NULL;
93 int i_arg, n, row, z;
94 int threads = 1;
95 int64_t i, j, m, r, s;
96 unsigned long pipeFlags = 0;
97 int overwrite = 0;
98 double **timeValues = NULL;
99 double **dataValues = NULL;
100 short **flag = NULL;
101 int64_t *rows = NULL;
102 char **dataNames = NULL;
103 char **uniqueDataName = NULL;
104 int uniqueDataNames = 0;
105 int page = 0;
106 int pages;
107 int found;
108 double *outputTimeValues = NULL;
109 double **outputDataValues = NULL;
110 int64_t allocated_rows = 0;
111 int **array = NULL;
112 int *arrayCount;
113 LOG_FILE_DATA *logFile = NULL;
114
116 argc = scanargs(&s_arg, argc, argv);
117
118 if (argc < 3) {
119 fprintf(stderr, "%s", USAGE);
120 return EXIT_FAILURE;
121 }
122
123 for (i_arg = 1; i_arg < argc; i_arg++) {
124 if (s_arg[i_arg].arg_type == OPTION) {
125 switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
126 case SET_OVERWRITE:
127 overwrite = 1;
128 break;
129 case SET_THREADS:
130 if (s_arg[i_arg].n_items != 2 ||
131 sscanf(s_arg[i_arg].list[1], "%d", &threads) != 1 ||
132 threads < 1) {
133 fprintf(stderr, "Error: Invalid -threads option syntax.\n");
134 return EXIT_FAILURE;
135 }
136 break;
137 case SET_PIPE:
138 if (!processPipeOption(s_arg[i_arg].list + 1,
139 s_arg[i_arg].n_items - 1,
140 &pipeFlags)) {
141 fprintf(stderr, "Error: Invalid -pipe option syntax.\n");
142 return EXIT_FAILURE;
143 }
144 if (pipeFlags & USE_STDIN) {
145 fprintf(stderr, "Error: -pipe=in is not supported.\n");
146 return EXIT_FAILURE;
147 }
148 break;
149 default:
150 fprintf(stderr, "Error: Unrecognized option.\n%s", USAGE);
151 return EXIT_FAILURE;
152 }
153 } else {
154 inputfile = trealloc(inputfile, sizeof(*inputfile) * (inputfiles + 1));
155 inputfile[inputfiles++] = s_arg[i_arg].list[0];
156 }
157 }
158
159 if (inputfiles > 1) {
160 if (!(pipeFlags & USE_STDOUT)) {
161 outputfile = inputfile[--inputfiles];
162 if (fexists(outputfile) && !overwrite) {
163 fprintf(stderr, "Error: Output file '%s' already exists. Use -overwrite to replace it.\n", outputfile);
164 return EXIT_FAILURE;
165 }
166 }
167 } else if (inputfiles == 1) {
168 if ((pipeFlags & USE_STDOUT) && outputfile) {
169 fprintf(stderr, "Error: Too many filenames provided with -pipe=output.\n");
170 return EXIT_FAILURE;
171 }
172 } else {
173 fprintf(stderr, "Error: No input filenames provided.\n%s", USAGE);
174 return EXIT_FAILURE;
175 }
176
177 if (threads > inputfiles)
178 threads = inputfiles;
179
180 logFile = calloc(inputfiles, sizeof(*logFile));
181 if (!logFile) {
182 fprintf(stderr, "Error: Memory allocation failure.\n");
183 return EXIT_FAILURE;
184 }
185
186#pragma omp parallel for if (threads > 1 && inputfiles > 1) num_threads(threads) schedule(dynamic)
187 for (i = 0; i < inputfiles; i++) {
188 LoadLogFile(inputfile[i], &logFile[i]);
189 }
190
191 pages = 0;
192 for (i = 0; i < inputfiles; i++) {
193 if (!logFile[i].status) {
194 fprintf(stderr, "%s\n", logFile[i].error);
195 for (j = 0; j < inputfiles; j++)
196 FreeLogFileData(&logFile[j]);
197 free(logFile);
198 return EXIT_FAILURE;
199 }
200 pages += logFile[i].pages;
201 }
202
203 timeValues = malloc(sizeof(*timeValues) * pages);
204 dataValues = malloc(sizeof(*dataValues) * pages);
205 dataNames = malloc(sizeof(*dataNames) * pages);
206 rows = malloc(sizeof(*rows) * pages);
207 if (!timeValues || !dataValues || !dataNames || !rows) {
208 fprintf(stderr, "Error: Memory allocation failure.\n");
209 for (i = 0; i < inputfiles; i++)
210 FreeLogFileData(&logFile[i]);
211 free(logFile);
212 return EXIT_FAILURE;
213 }
214
215 page = 0;
216 for (i = 0; i < inputfiles; i++) {
217 int filePage;
218 for (filePage = 0; filePage < logFile[i].pages; filePage++) {
219 timeValues[page] = logFile[i].page[filePage].timeValues;
220 dataValues[page] = logFile[i].page[filePage].dataValues;
221 dataNames[page] = logFile[i].page[filePage].dataName;
222 rows[page] = logFile[i].page[filePage].rows;
223 logFile[i].page[filePage].timeValues = NULL;
224 logFile[i].page[filePage].dataValues = NULL;
225 logFile[i].page[filePage].dataName = NULL;
226 page++;
227 }
228 FreeLogFileData(&logFile[i]);
229 }
230 free(logFile);
231
232 pages = page;
233
234 /* Identify unique data names */
235 for (page = 0; page < pages; page++) {
236 found = 0;
237 for (i = 0; i < uniqueDataNames; i++) {
238 if (strcmp(dataNames[page], uniqueDataName[i]) == 0) {
239 found = 1;
240 break;
241 }
242 }
243 if (!found) {
244 uniqueDataName = realloc(uniqueDataName, sizeof(*uniqueDataName) * (uniqueDataNames + 1));
245 SDDS_CopyString(&uniqueDataName[uniqueDataNames], dataNames[page]);
246 uniqueDataNames++;
247 }
248 }
249
250 /* Initialize output SDDS file */
251 if (!SDDS_InitializeOutput(&SDDS_output, SDDS_BINARY, 0, NULL, NULL, outputfile)) {
252 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
253 return EXIT_FAILURE;
254 }
255
256 if (!SDDS_DefineSimpleColumn(&SDDS_output, "Time", "s", SDDS_DOUBLE)) {
257 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
258 return EXIT_FAILURE;
259 }
260
261 for (i = 0; i < uniqueDataNames; i++) {
262 if (!SDDS_DefineSimpleColumn(&SDDS_output, uniqueDataName[i], NULL, SDDS_DOUBLE)) {
263 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
264 return EXIT_FAILURE;
265 }
266 }
267
268 outputDataValues = malloc(sizeof(*outputDataValues) * uniqueDataNames);
269 if (uniqueDataNames == 1) {
270 /* Single PV: Concatenate all data */
271 for (page = 0; page < pages; page++) {
272 allocated_rows += rows[page];
273 }
274
275 outputTimeValues = malloc(sizeof(*outputTimeValues) * allocated_rows);
276 outputDataValues[0] = malloc(sizeof(*(outputDataValues[0])) * allocated_rows);
277
278 i = 0;
279 for (page = 0; page < pages; page++) {
280 for (j = 0; j < rows[page]; j++) {
281 outputTimeValues[i] = timeValues[page][j];
282 outputDataValues[0][i] = dataValues[page][j];
283 i++;
284 }
285 }
286 } else {
287 /* Multiple PVs: Retain only common timestamps */
288 flag = malloc(sizeof(*flag) * pages);
289 for (page = 0; page < pages; page++) {
290 flag[page] = calloc(rows[page], sizeof(*(flag[page])));
291 }
292
293 array = malloc(sizeof(*array) * uniqueDataNames);
294 arrayCount = calloc(uniqueDataNames, sizeof(*arrayCount));
295
296 for (i = 0; i < uniqueDataNames; i++) {
297 for (page = 0; page < pages; page++) {
298 if (strcmp(dataNames[page], uniqueDataName[i]) == 0) {
299 arrayCount[i]++;
300 if (arrayCount[i] == 1) {
301 array[i] = malloc(sizeof(*(array[i])));
302 } else {
303 array[i] = realloc(array[i], sizeof(*(array[i])) * arrayCount[i]);
304 }
305 array[i][arrayCount[i] - 1] = page;
306 }
307 }
308 }
309
310 for (i = 0; i < arrayCount[0]; i++) {
311 keyGroup = MakeSortedKeyGroups(&keyGroups, SDDS_DOUBLE, timeValues[array[0][i]], rows[array[0][i]]);
312 for (n = 1; n < uniqueDataNames; n++) {
313 for (m = 0; m < arrayCount[n]; m++) {
314 if ((i == m) && (rows[array[0][i]] == rows[array[n][m]]) && (rows[array[0][i]] > 10)) {
315 if ((timeValues[array[0][i]][0] == timeValues[array[n][m]][0]) &&
316 (timeValues[array[0][i]][1] == timeValues[array[n][m]][1]) &&
317 (timeValues[array[0][i]][rows[array[0][i]] - 2] == timeValues[array[n][m]][rows[array[n][m]] - 2]) &&
318 (timeValues[array[0][i]][rows[array[0][i]] - 1] == timeValues[array[n][m]][rows[array[n][m]] - 1])) {
319 /* Assume the entire page matches because it has the same number of rows and key timestamps match */
320 for (r = 0; r < rows[array[n][m]]; r++) {
321 if (flag[array[n][m]][r]) {
322 continue;
323 }
324 flag[array[0][i]][r] += 1;
325 flag[array[n][m]][r] = 1;
326 }
327 }
328 }
329
330 for (r = 0; r < rows[array[n][m]]; r++) {
331 if (flag[array[n][m]][r]) {
332 continue;
333 }
334 row = FindMatchingKeyGroup(keyGroup, keyGroups, SDDS_DOUBLE, &(timeValues[array[n][m]][r]), 1);
335 if (row >= 0) {
336 flag[array[0][i]][row] += 1;
337 flag[array[n][m]][r] = 1;
338 }
339 }
340 }
341 }
342
343 for (j = 0; j < keyGroups; j++) {
344 free(keyGroup[j]->equivalent);
345 free(keyGroup[j]);
346 }
347 free(keyGroup);
348 }
349
350 z = uniqueDataNames - 1;
351 for (n = 0; n < arrayCount[0]; n++) {
352 for (m = 0; m < rows[array[0][n]]; m++) {
353 if (flag[array[0][n]][m] >= z) {
354 allocated_rows++;
355 }
356 }
357 }
358
359 outputTimeValues = malloc(sizeof(*outputTimeValues) * allocated_rows);
360 for (i = 0; i < uniqueDataNames; i++) {
361 outputDataValues[i] = malloc(sizeof(*(outputDataValues[i])) * allocated_rows);
362 }
363
364 s = 0;
365 for (i = 0; i < arrayCount[0]; i++) {
366 for (j = 0; j < rows[array[0][i]]; j++) {
367 if (flag[array[0][i]][j] >= z) {
368 outputTimeValues[s] = timeValues[array[0][i]][j];
369 outputDataValues[0][s] = dataValues[array[0][i]][j];
370 s++;
371 }
372 }
373 }
374
375 if (s == 0) {
376 fprintf(stderr, "Error: No matching 'Time' rows found in input files.\n");
377 return EXIT_FAILURE;
378 }
379
380 keyGroup = MakeSortedKeyGroups(&keyGroups, SDDS_DOUBLE, outputTimeValues, s);
381
382 for (n = 1; n < uniqueDataNames; n++) {
383 for (m = 0; m < arrayCount[n]; m++) {
384 for (r = 0; r < rows[array[n][m]]; r++) {
385 if (flag[array[n][m]][r]) {
386 row = FindMatchingKeyGroup(keyGroup, keyGroups, SDDS_DOUBLE, &(timeValues[array[n][m]][r]), 1);
387 if (row >= 0) {
388 outputDataValues[n][row] = dataValues[array[n][m]][r];
389 }
390 }
391 }
392 }
393 }
394
395 for (i = 0; i < uniqueDataNames; i++) {
396 free(array[i]);
397 }
398
399 for (j = 0; j < keyGroups; j++) {
400 if (keyGroup[j]->equivalent)
401 free(keyGroup[j]->equivalent);
402 if (keyGroup[j])
403 free(keyGroup[j]);
404 }
405
406 for (page = 0; page < pages; page++) {
407 free(flag[page]);
408 }
409
410 free(array);
411 free(keyGroup);
412 free(arrayCount);
413 free(flag);
414 }
415
416 /* Free allocated memory for input data */
417 for (page = 0; page < pages; page++) {
418 if (timeValues[page])
419 free(timeValues[page]);
420 if (dataValues[page])
421 free(dataValues[page]);
422 free(dataNames[page]);
423 }
424 free(timeValues);
425 free(dataValues);
426 free(dataNames);
427
428 /* Write the output SDDS file */
429 if (!SDDS_WriteLayout(&SDDS_output)) {
430 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
431 return EXIT_FAILURE;
432 }
433
434 if (!SDDS_StartPage(&SDDS_output, allocated_rows)) {
435 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
436 return EXIT_FAILURE;
437 }
438
439 if (!SDDS_SetColumnFromDoubles(&SDDS_output, SDDS_SET_BY_NAME, outputTimeValues, allocated_rows, "Time")) {
440 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
441 return EXIT_FAILURE;
442 }
443
444 for (i = 0; i < uniqueDataNames; i++) {
445 if (!SDDS_SetColumnFromDoubles(&SDDS_output, SDDS_SET_BY_NAME, outputDataValues[i], allocated_rows, uniqueDataName[i])) {
446 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
447 return EXIT_FAILURE;
448 }
449 }
450
451 if (!SDDS_WriteTable(&SDDS_output)) {
452 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
453 return EXIT_FAILURE;
454 }
455
456 if (!SDDS_Terminate(&SDDS_output)) {
457 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
458 return EXIT_FAILURE;
459 }
460
461 /* Free allocated memory for output data */
462 for (i = 0; i < uniqueDataNames; i++) {
463 free(uniqueDataName[i]);
464 free(outputDataValues[i]);
465 }
466 free(outputTimeValues);
467 free(outputDataValues);
468 free(uniqueDataName);
469 free(rows);
470
471 if (inputfiles > 0) {
472 free(inputfile);
473 }
474
475 free_scanargs(&s_arg, argc);
476
477 return EXIT_SUCCESS;
478}
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
int32_t SDDS_SetColumnFromDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode, double *data, int64_t rows,...)
Sets the values for a single data column using double-precision floating-point numbers.
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_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:474
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:318
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
void * trealloc(void *old_ptr, uint64_t size_of_block)
Reallocates a memory block to a new size.
Definition array.c:190
long fexists(const char *filename)
Checks if a file exists.
Definition fexists.c:27
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)
Definition scanargs.c:36
long processPipeOption(char **item, long items, unsigned long *flags)
Definition scanargs.c:357
void free_scanargs(SCANNED_ARG **scanned, int argc)
Definition scanargs.c:588
KEYED_EQUIVALENT ** MakeSortedKeyGroups(long *keyGroups, long keyType, void *data, long points)
Create sorted key groups from data.
long FindMatchingKeyGroup(KEYED_EQUIVALENT **keyGroup, long keyGroups, long keyType, void *searchKeyData, long reuse)
Find a matching key group for a search key.