SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
citi2sdds.c
Go to the documentation of this file.
1/**
2 * @file citi2sdds.c
3 * @brief Converts a data file from Hewlett-Packard/Keysight Technologies' CITI format to SDDS format.
4 *
5 * @details
6 * This program reads a waveform data file in Hewlett-Packard/Keysight Technologies' CITI format
7 * (Common Instrumentation Transfer and Interchange file) and converts it into the SDDS
8 * (Self Describing Data Sets) format. It supports various options to customize the output,
9 * including setting descriptions, MPL labels, and specifying the major order of data.
10 *
11 * @section Usage
12 * ```
13 * citi2sdds <inputfile> <outputfile>
14 * [-description=<text>,<contents>]
15 * [-mpllabels=<title>,<topline>]
16 * [-majorOrder=row|column]
17 * ```
18 *
19 * @section Options
20 * | Optional | Description |
21 * |---------------------------------------|---------------------------------------------------------------------------------------|
22 * | `-description` | Adds a description text and content to the SDDS output file. |
23 * | `-mpllabels` | Sets MPL (Matplotlib) title and top-line labels for the SDDS output. |
24 * | `-majorOrder` | Specifies the major order of data in the SDDS output. Defaults to row-major order. |
25 *
26 * @subsection Incompatibilities
27 * - Only one of the following options may be specified:
28 * - `-description`
29 * - `-mpllabels`
30 *
31 * @copyright
32 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
33 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
34 *
35 * @license
36 * This file is distributed under the terms of the Software License Agreement
37 * found in the file LICENSE included with this distribution.
38 *
39 * @author
40 * M. Borland, C. Saunders, R. Soliday, H. Shang
41 */
42
43#include "mdb.h"
44#include "SDDS.h"
45#include "scan.h"
46#include "match_string.h"
47
48/* Enumeration for option types */
49enum option_type {
50 SET_DESCRIPTION,
51 SET_MPL_LABELS,
52 SET_MAJOR_ORDER,
53 N_OPTIONS
54};
55
56static char *option[N_OPTIONS] = {
57 "description",
58 "mpllabels",
59 "majorOrder"
60};
61
62char *USAGE =
63 "Usage:\n"
64 " citi2sdds <inputfile> <outputfile>\n"
65 " [-description=<text>,<contents>]\n"
66 " [-mpllabels=<title>,<topline>] \n"
67 " [-majorOrder=row|column]\n"
68 "Options:\n"
69 " -description=<text>,<contents> Add a description to the SDDS output.\n"
70 " -mpllabels=<title>,<topline> Set MPL title and top line labels.\n"
71 " -majorOrder=row|column Specify the major order of data.\n\n"
72 "This program converts HP CITI format waveforms to SDDS format.\n\n"
73 "Program by Michael Borland (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")\n";
74
75#define BUFSIZE 256
76
77#define CITIFILE_TAG "CITIFILE"
78#define CITIFILE_VERSION "A.01.00"
79
80#define CITI_NA_KEYWORD 0
81#define CITI_NAME_KEYWORD 1
82#define CITI_VAR_KEYWORD 2
83#define CITI_DATA_KEYWORD 3
84#define CITI_VAR_LIST_KEYWORD 4
85#define CITI_BEGIN_KEYWORD 5
86#define CITI_SEG_LIST_BEGIN 6
87#define CITI_COMMENT_KEYWORD 7
88#define CITI_CONSTANT_KEYWORD 8
89#define N_CITI_KEYWORDS 9
90static char *citi_keyword[N_CITI_KEYWORDS] = {
91 "#NA", "NAME", "VAR", "DATA", "VAR_LIST_BEGIN", "BEGIN",
92 "SEG_LIST_BEGIN", "COMMENT", "CONSTANT"};
93
94long read_CITI_var_list(FILE *fpi, double *var_list, long points);
95long read_CITI_data(FILE *fpi, double *real_data, double *imag_data, long points);
96long read_CITI_seg_list(FILE *fpi, double *seg_list, long points);
97void alter_data_name(char *name);
98
99int main(int argc, char **argv) {
100 SDDS_TABLE SDDS_table;
101 SCANNED_ARG *scanned;
102 long i, i_arg, points;
103 char *input, *output, *name, *indep_var, *var_list_format;
104 char *mpl_title, *mpl_topline, *descrip_text, *descrip_contents;
105 FILE *fpi;
106 char buffer[BUFSIZE], buffer0[BUFSIZE], buffer1[BUFSIZE];
107 char *ptr, *ptr1, *ptr2;
108 char **data_name, *package_name, *data_format;
109 long data_names, data_sets_seen, data_sets_expected, realIndex, imagIndex;
110 double **real_data, **imag_data, *var_list;
111 unsigned long majorOrderFlag;
112 short columnMajorOrder = 0;
113
114 argc = scanargs(&scanned, argc, argv);
115 if (argc < 3) {
116 fprintf(stderr, "%s", USAGE);
117 return EXIT_FAILURE;
118 }
119
120 input = output = package_name = data_format = indep_var = var_list_format = ptr = NULL;
121 mpl_title = mpl_topline = descrip_text = descrip_contents = NULL;
122 data_names = realIndex = imagIndex = 0;
123 data_name = NULL;
124 real_data = imag_data = NULL;
125 var_list = NULL;
126 data_sets_expected = data_sets_seen = 0;
127 points = 0;
128
129 for (i_arg = 1; i_arg < argc; i_arg++) {
130 if (scanned[i_arg].arg_type == OPTION) {
131 delete_chars(scanned[i_arg].list[0], "_");
132 /* process options here */
133 switch (match_string(scanned[i_arg].list[0], option, N_OPTIONS, 0)) {
134 case SET_MAJOR_ORDER:
135 majorOrderFlag = 0;
136 scanned[i_arg].n_items--;
137 if (scanned[i_arg].n_items > 0 && (!scanItemList(&majorOrderFlag, scanned[i_arg].list + 1, &scanned[i_arg].n_items, 0, "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER, "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
138 SDDS_Bomb("invalid -majorOrder syntax/values");
139 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
140 columnMajorOrder = 1;
141 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
142 columnMajorOrder = 0;
143 break;
144 case SET_DESCRIPTION:
145 if (scanned[i_arg].n_items != 3) {
146 SDDS_Bomb("invalid -description syntax");
147 }
148 descrip_text = scanned[i_arg].list[1];
149 descrip_contents = scanned[i_arg].list[2];
150 break;
151 case SET_MPL_LABELS:
152 if (scanned[i_arg].n_items != 3) {
153 SDDS_Bomb("invalid -mpllabels syntax");
154 }
155 mpl_title = scanned[i_arg].list[1];
156 mpl_topline = scanned[i_arg].list[2];
157 break;
158 default:
159 SDDS_Bomb("invalid option seen");
160 break;
161 }
162 } else {
163 if (!input)
164 input = scanned[i_arg].list[0];
165 else if (!output)
166 output = scanned[i_arg].list[0];
167 else {
168 SDDS_Bomb("too many filenames");
169 }
170 }
171 }
172 if (!input) {
173 SDDS_Bomb("input file not seen");
174 }
175 if (!output) {
176 SDDS_Bomb("output file not seen");
177 }
178
179 fpi = fopen_e(input, "r", 0);
180 if (!fgets(buffer, BUFSIZE, fpi) || strncmp(buffer, CITIFILE_TAG, strlen(CITIFILE_TAG)) != 0 || !(ptr = strchr(buffer, ' '))) {
181 SDDS_Bomb("valid CITIFILE version line not found");
182 }
183 *ptr++ = 0;
184 ptr[strlen(ptr) - 1] = 0;
185 if (strncmp(ptr, CITIFILE_VERSION, strlen(CITIFILE_VERSION)) != 0)
186 fprintf(stderr, "warning: the CITIFILE version is %s--this program is only designed for version %s\n", ptr, CITIFILE_VERSION);
187
188 if (!SDDS_InitializeOutput(&SDDS_table, SDDS_BINARY, 0, descrip_text, descrip_contents, output))
189 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
190 SDDS_table.layout.data_mode.column_major = columnMajorOrder;
191 if ((mpl_title && SDDS_DefineParameter(&SDDS_table, "mplTitle", NULL, NULL, NULL, NULL, SDDS_STRING, mpl_title) < 0) ||
192 (mpl_topline && SDDS_DefineParameter(&SDDS_table, "mplTopline", NULL, NULL, NULL, NULL, SDDS_STRING, mpl_topline) < 0))
193 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
194
195 while (fgets(buffer, BUFSIZE, fpi)) {
196#if DEBUG
197 fputs(buffer, stderr);
198#endif
199 buffer[strlen(buffer) - 1] = 0;
200 strcpy(buffer0, buffer);
201 ptr1 = NULL;
202 if ((ptr1 = strchr(buffer, ' ')))
203 *ptr1++ = 0;
204 switch (match_string(buffer, citi_keyword, N_CITI_KEYWORDS, EXACT_MATCH)) {
205 case CITI_NA_KEYWORD:
206 name = buffer + 1;
207 if (!*ptr1 || !(ptr2 = strchr(ptr1, ' '))) {
208 fprintf(stderr, "The following line contains an apparently invalid #NA keyword:\n%s\n", buffer0);
209 return EXIT_FAILURE;
210 }
211 *(ptr1 - 1) = '_';
212 *ptr2++ = 0;
213 if (SDDS_DefineParameter(&SDDS_table, name, NULL, NULL, NULL, NULL, SDDS_STRING, ptr2) < 0) {
214 SDDS_SetError(buffer0);
215 SDDS_SetError("Problem creating parameter for #NA keyword in the following line:");
216 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
217 }
218 break;
219 case CITI_NAME_KEYWORD:
220 if (!ptr1 || SDDS_StringIsBlank(ptr1)) {
221 fprintf(stderr, "The following line contains erroneous input:\n%s\n", buffer0);
222 return EXIT_FAILURE;
223 }
224#if DEBUG
225 fprintf(stderr, "NAME: %s\n", ptr1);
226#endif
227 cp_str(&package_name, ptr1);
228 if (SDDS_DefineParameter(&SDDS_table, "CITIPackageName", NULL, NULL, NULL, NULL, SDDS_STRING, package_name) < 0) {
229 SDDS_SetError(buffer0);
230 SDDS_SetError("Problem creating parameter for NAME keyword in the following line:");
231 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
232 }
233 break;
234 case CITI_VAR_KEYWORD:
235 if (!ptr1 || SDDS_StringIsBlank(ptr1)) {
236 fprintf(stderr, "The following line contains erroneous input:\n%s\n", buffer0);
237 return EXIT_FAILURE;
238 }
239#if DEBUG
240 fprintf(stderr, "VAR: %s\n", ptr1);
241#endif
242 if (!(indep_var = get_token(ptr1)) || !(var_list_format = get_token(ptr1)) || !get_long(&points, ptr1) || points <= 0) {
243 fprintf(stderr, "The following line contains erroneous input:\n%s\n", buffer0);
244 return EXIT_FAILURE;
245 }
246 if (SDDS_DefineColumn(&SDDS_table, indep_var, NULL, NULL, NULL, NULL, SDDS_DOUBLE, 0) < 0) {
247 SDDS_SetError(buffer0);
248 SDDS_SetError("Problem creating column for data element in the following line:");
249 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
250 }
251 break;
252 case CITI_CONSTANT_KEYWORD:
253 if (!ptr1 || !(ptr2 = strchr(ptr1, ' '))) {
254 fprintf(stderr, "The following line contains erroneous input:\n%s\n", buffer0);
255 return EXIT_FAILURE;
256 }
257#if DEBUG
258 fprintf(stderr, "CONSTANT: %s\n", ptr1);
259#endif
260 *ptr2++ = 0;
261 if (SDDS_DefineParameter(&SDDS_table, ptr1, NULL, NULL, NULL, NULL, SDDS_STRING, ptr2) < 0) {
262 SDDS_SetError(buffer0);
263 SDDS_SetError("Problem creating parameter for CONSTANT keyword in the following line:");
264 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
265 }
266 break;
267 case CITI_COMMENT_KEYWORD:
268 if (!ptr1 || SDDS_StringIsBlank(ptr1)) {
269 fprintf(stderr, "The following line contains erroneous input:\n%s\n", buffer0);
270 return EXIT_FAILURE;
271 }
272#if DEBUG
273 fprintf(stderr, "COMMENT: %s\n", ptr1);
274#endif
275 break;
276 case CITI_DATA_KEYWORD:
277 if (!ptr1 || !(ptr2 = strchr(ptr1, ' '))) {
278 fprintf(stderr, "The following line contains erroneous input:\n%s\n", buffer0);
279 return EXIT_FAILURE;
280 }
281#if DEBUG
282 fprintf(stderr, "DATA: %s\n", ptr1);
283#endif
284 *ptr2++ = 0;
285 cp_str(&data_format, ptr2);
286 data_name = trealloc(data_name, sizeof(*data_name) * (data_names + 1));
287 cp_str(data_name + data_names, ptr1);
288 alter_data_name(data_name[data_names]);
289 real_data = trealloc(real_data, sizeof(*real_data) * (data_names + 1));
290 imag_data = trealloc(imag_data, sizeof(*imag_data) * (data_names + 1));
291 sprintf(buffer, "%sReal", data_name[data_names]);
292 sprintf(buffer1, "%sImag", data_name[data_names]);
293 if ((realIndex = SDDS_DefineColumn(&SDDS_table, buffer, NULL, NULL, NULL, NULL, SDDS_DOUBLE, 0)) < 0 ||
294 (imagIndex = SDDS_DefineColumn(&SDDS_table, buffer1, NULL, NULL, NULL, NULL, SDDS_DOUBLE, 0)) < 0) {
295 SDDS_SetError(buffer0);
296 SDDS_SetError("Problem creating column for data element in the following line:");
297 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
298 }
299 data_names++;
300 break;
301 case CITI_VAR_LIST_KEYWORD:
302 if (ptr1 && !SDDS_StringIsBlank(ptr1)) {
303 fprintf(stderr, "The following line contains erroneous input:\n%s\n", buffer0);
304 return EXIT_FAILURE;
305 }
306#if DEBUG
307 fprintf(stderr, "VAR_LIST_BEGIN seen\n");
308#endif
309 if (points == 0)
310 SDDS_Bomb("VAR_LIST_BEGIN statement seen without prior VAR statement");
311 var_list = tmalloc(sizeof(*var_list) * points);
312 if (!read_CITI_var_list(fpi, var_list, points))
313 SDDS_Bomb("unable to read VAR_LIST");
314 break;
315 case CITI_BEGIN_KEYWORD:
316 if (ptr1 && !SDDS_StringIsBlank(ptr1)) {
317 fprintf(stderr, "The following line contains erroneous input:\n%s\n", buffer0);
318 return EXIT_FAILURE;
319 }
320#if DEBUG
321 fprintf(stderr, "BEGIN seen\n");
322#endif
323 if (points == 0)
324 SDDS_Bomb("BEGIN statement seen without prior VAR statement");
325 real_data[data_sets_seen] = tmalloc(sizeof(**real_data) * points);
326 imag_data[data_sets_seen] = tmalloc(sizeof(**imag_data) * points);
327 if (!read_CITI_data(fpi, real_data[data_sets_seen], imag_data[data_sets_seen], points))
328 SDDS_Bomb("problem reading data section");
329 data_sets_seen++;
330 break;
331 case CITI_SEG_LIST_BEGIN:
332 if (ptr1 && !SDDS_StringIsBlank(ptr1)) {
333 fprintf(stderr, "The following line contains erroneous input:\n%s\n", buffer0);
334 return EXIT_FAILURE;
335 }
336#if DEBUG
337 fprintf(stderr, "SEG_LIST_BEGIN seen\n");
338#endif
339 if (points == 0)
340 SDDS_Bomb("SEG_LIST_BEGIN statement seen without prior SEG statement");
341 var_list = tmalloc(sizeof(*var_list) * points);
342 if (!read_CITI_seg_list(fpi, var_list, points))
343 SDDS_Bomb("unable to read SEG_LIST");
344 break;
345 default:
346 fprintf(stderr, "Unidentifiable line in file--not CITI format:\n\"%s\"\n", buffer0);
347 return EXIT_FAILURE;
348 break;
349 }
350 }
351 if (!points)
352 SDDS_Bomb("no data in file");
353 if (data_sets_seen != (data_sets_expected = data_names))
354 SDDS_Bomb("fewer data sets than expected were actually present");
355 if (!var_list) {
356 fprintf(stderr, "warning: no independent variable data---supplying index\n");
357 var_list = tmalloc(sizeof(*var_list) * points);
358 for (i = 0; i < points; i++)
359 var_list[i] = i;
360 }
361 if (!SDDS_WriteLayout(&SDDS_table) || !SDDS_StartTable(&SDDS_table, points))
362 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
363 if (!SDDS_SetColumn(&SDDS_table, SDDS_SET_BY_NAME, (void *)var_list, points, indep_var))
364 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
365 for (i = 0; i < data_sets_expected; i++) {
366 if (!SDDS_SetColumn(&SDDS_table, SDDS_SET_BY_INDEX, (void *)real_data[i], points, realIndex) ||
367 !SDDS_SetColumn(&SDDS_table, SDDS_SET_BY_INDEX, (void *)imag_data[i], points, imagIndex)) {
368 fprintf(stderr, "Problem setting data for column(s) %s\n", data_name[i]);
369 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
370 }
371 }
372 if (!SDDS_WriteTable(&SDDS_table) || !SDDS_Terminate(&SDDS_table))
373 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
374
375 return EXIT_SUCCESS;
376}
377
378char *process_column_definition(char **argv, long argc) {
379 char buffer[SDDS_MAXLINE], *ptr;
380 long i;
381
382 if (argc < 1)
383 return (NULL);
384 sprintf(buffer, "&column name=%s, ", argv[0]);
385 for (i = 1; i < argc; i++) {
386 if (!strchr(argv[i], '='))
387 return (NULL);
388 strcat(buffer, argv[i]);
389 strcat(buffer, ", ");
390 }
391 if (!strstr(buffer, "type="))
392 strcat(buffer, "type=character ");
393 strcat(buffer, "&end");
394 cp_str(&ptr, buffer);
395 return (ptr);
396}
397
398long read_CITI_var_list(FILE *fpi, double *var_list, long points) {
399 long i;
400 char buffer[BUFSIZE];
401
402 i = 0;
403 while (fgets(buffer, BUFSIZE, fpi) && i < points) {
404 buffer[strlen(buffer) - 1] = 0;
405 if (strcmp(buffer, "VAR_LIST_END") == 0)
406 break;
407 if (!get_double(var_list + i, buffer))
408 return (0);
409 i++;
410 }
411 if (i != points)
412 return (0);
413 return (1);
414}
415
416long read_CITI_data(FILE *fpi, double *real_data, double *imag_data, long points) {
417 long i;
418 char buffer[BUFSIZE];
419
420 i = 0;
421 while (fgets(buffer, BUFSIZE, fpi) && i < points) {
422 buffer[strlen(buffer) - 1] = 0;
423 if (strcmp(buffer, "END") == 0)
424 break;
425 if (!get_double(real_data + i, buffer) || !get_double(imag_data + i, buffer))
426 return (0);
427 i++;
428 }
429 if (i != points)
430 return (0);
431 return (1);
432}
433
434long read_CITI_seg_list(FILE *fpi, double *seg_list, long points) {
435 char buffer[BUFSIZE];
436 long i;
437 double start, end, delta;
438
439 if (!fgets(buffer, BUFSIZE, fpi) || !get_double(&start, buffer) || !get_double(&end, buffer) || !get_long(&i, buffer))
440 return (0);
441 if (i != points)
442 return (0);
443 delta = (end - start) / (points - 1);
444
445 if (!fgets(buffer, BUFSIZE, fpi))
446 return (0);
447 buffer[strlen(buffer) - 1] = 0;
448 if (strcmp(buffer, "SEG_LIST_END") != 0)
449 return (0);
450
451 for (i = 0; i < points; i++)
452 seg_list[i] = start + i * delta;
453 return (1);
454}
455
456void alter_data_name(char *name) {
457 char *ptr;
458 if ((ptr = strchr(name, '[')))
459 strcpy_ss(ptr, ptr + 1);
460 if ((ptr = strchr(name, ']')))
461 strcpy_ss(ptr, ptr + 1);
462 if ((ptr = strchr(name, ',')))
463 strcpy_ss(ptr, ptr + 1);
464}
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_SetColumn(SDDS_DATASET *SDDS_dataset, int32_t mode, void *data, int64_t rows,...)
Sets the values for one data column in the current data table of an SDDS dataset.
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
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_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_SetError(char *error_text)
Records an error message in the SDDS error stack.
Definition SDDS_utils.c:379
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:432
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.
Definition SDDS_utils.c:342
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
#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:181
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:59
char * cp_str(char **s, char *t)
Copies a string, allocating memory for storage.
Definition cp_str.c:28
int get_long(long *iptr, char *s)
Parses a long integer value from the given string.
Definition data_scan.c:255
int get_double(double *dptr, char *s)
Parses a double value from the given string.
Definition data_scan.c:40
char * get_token(char *s)
Extracts the next token from the input string.
Definition data_scan.c:413
char * delete_chars(char *s, char *t)
Removes all occurrences of characters found in string t from string s.
FILE * fopen_e(char *file, char *open_mode, long mode)
Opens a file with error checking, messages, and aborts.
Definition fopen_e.c:30
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 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 * strcpy_ss(char *dest, const char *src)
Safely copies a string, handling memory overlap.
Definition str_copy.c:34