SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
sddsconvertalarmlog.c
Go to the documentation of this file.
1/**
2 * @file sddsconvertalarmlog.c
3 * @brief Convert and process SDDS alarm log files with flexible options.
4 *
5 * This program processes SDDS alarm log files, allowing various filtering, formatting,
6 * and data manipulation operations. The output can be formatted in ASCII or binary, and
7 * supports advanced filtering by time, interval, and specific data column manipulation.
8 *
9 * @section Usage
10 * ```
11 * sddsconvertalarmlog [<input-file>] [<output-file>]
12 * [-pipe=[input][,output]]
13 * [-binary]
14 * [-ascii]
15 * [-float]
16 * [-double]
17 * [-minimumInterval=<seconds>]
18 * [-snapshot=<epochtime>]
19 * [-time=[start=<epochtime>,end=<epochtime>]]
20 * [-delete=<column-names>]
21 * [-retain=<column-names>]
22 * ```
23 *
24 * @section Options
25 * | Option | Description |
26 * |---------------------------------------|---------------------------------------------------------------------------------------|
27 * | `-pipe` | Use pipes for input and/or output. |
28 * | `-binary` | Output in binary format. |
29 * | `-ascii` | Output in ASCII format. |
30 * | `-float` | Use float precision for numerical output. |
31 * | `-double` | Use double precision for numerical output. |
32 * | `-minimumInterval` | Set the minimum interval between data points. |
33 * | `-snapshot` | Take a snapshot at the specified epoch time. |
34 * | `-time` | Filter data within the specified time range. |
35 * | `-delete` | Delete specified columns by name. |
36 * | `-retain` | Retain only the specified columns. |
37 *
38 * @subsection Incompatibilities
39 * - `-snapshot` is incompatible with:
40 * - `-minimumInterval`
41 * - `-time`
42 * - `-ascii` and `-binary` are mutually exclusive.
43 * - Only one of the following may be specified:
44 * - `-float`
45 * - `-double`
46 *
47 * @copyright
48 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
49 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
50 *
51 * @license
52 * This file is distributed under the terms of the Software License Agreement
53 * found in the file LICENSE included with this distribution.
54 *
55 * @author
56 * R. Soliday
57 */
58
59#include "mdb.h"
60#include "SDDS.h"
61#include "scan.h"
62
63/* Enumeration for option types */
64enum option_type {
65 SET_BINARY,
66 SET_ASCII,
67 SET_FLOAT,
68 SET_DOUBLE,
69 SET_SNAPSHOT,
70 SET_PIPE,
71 SET_MININTERVAL,
72 SET_TIME,
73 SET_DELETE,
74 SET_RETAIN,
75 N_OPTIONS
76};
77
78#if !defined(MAXDOUBLE)
79# define MAXDOUBLE 1.79769313486231570e+308
80#endif
81
82char *option[N_OPTIONS] = {
83 "binary",
84 "ascii",
85 "float",
86 "double",
87 "snapshot",
88 "pipe",
89 "minimuminterval",
90 "time",
91 "delete",
92 "retain"
93};
94
95char *USAGE =
96 "Usage: sddsconvertalarmlog [<input-file>] [<output-file>]\n"
97 " [-pipe=[input][,output]]\n"
98 " [-binary]\n"
99 " [-ascii]\n"
100 " [-float]\n"
101 " [-double]\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"
107 "\nOptions:\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";
120
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);
123
124int main(int argc, char **argv) {
125 SDDS_DATASET SDDS_input, SDDS_output;
126 long i, i_arg;
127 SCANNED_ARG *s_arg;
128 long tmpfile_used, noWarnings;
129 char *input, *output;
130 long ascii_output, binary_output;
131 unsigned long pipeFlags;
132 long output_type = SDDS_DOUBLE;
133 long snapshot = 0;
134 double epochtime;
135
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;
140 SDDS_ARRAY *readbackNameArray = NULL;
141 SDDS_ARRAY *readbackNameArray2 = NULL;
142 long page = 0;
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;
152 unsigned long flags;
153 char **ColumnName = NULL;
154 long ColumnNames;
155 char **retain_name = NULL;
156 long retain_names = 0;
157 char **delete_name = NULL;
158 long delete_names = 0;
159
161 argc = scanargs(&s_arg, argc, argv);
162 if (argc < 3) {
163 fprintf(stderr, "%s", USAGE);
164 exit(EXIT_FAILURE);
165 }
166 input = output = NULL;
167 ascii_output = binary_output = noWarnings = 0;
168
169 tmpfile_used = 0;
170 pipeFlags = 0;
171
172 for (i_arg = 1; i_arg < argc; i_arg++) {
173 if (s_arg[i_arg].arg_type == OPTION) {
174 delete_chars(s_arg[i_arg].list[0], "_");
175 switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
176 case SET_BINARY:
177 binary_output = 1;
178 ascii_output = 0;
179 break;
180 case SET_ASCII:
181 ascii_output = 1;
182 binary_output = 0;
183 break;
184 case SET_FLOAT:
185 output_type = SDDS_FLOAT;
186 break;
187 case SET_DOUBLE:
188 output_type = SDDS_DOUBLE;
189 break;
190 case SET_SNAPSHOT:
191 if (s_arg[i_arg].n_items < 2) {
192 fprintf(stderr, "invalid -snapshot syntax\n");
193 exit(EXIT_FAILURE);
194 }
195 snapshot = 1;
196 if (sscanf(s_arg[i_arg].list[1], "%lf", &epochtime) != 1) {
197 fprintf(stderr, "invalid -snapshot syntax or value\n");
198 exit(EXIT_FAILURE);
199 }
200 break;
201 case SET_PIPE:
202 if (!processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags)) {
203 fprintf(stderr, "invalid -pipe syntax\n");
204 exit(EXIT_FAILURE);
205 }
206 break;
207 case SET_MININTERVAL:
208 if (s_arg[i_arg].n_items < 2) {
209 fprintf(stderr, "invalid -minimumInterval syntax\n");
210 exit(EXIT_FAILURE);
211 }
212 if (sscanf(s_arg[i_arg].list[1], "%lf", &minimumInterval) != 1) {
213 fprintf(stderr, "invalid -minimumInterval syntax or value\n");
214 exit(EXIT_FAILURE);
215 }
216 break;
217 case SET_TIME:
218 s_arg[i_arg].n_items -= 1;
219 filterTime = 1;
220 if (!scanItemList(&flags, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
221 "start", SDDS_DOUBLE, &startTime, 1, 0,
222 "end", SDDS_DOUBLE, &endTime, 1, 0, NULL)) {
223 fprintf(stderr, "invalid -time syntax\n");
224 exit(EXIT_FAILURE);
225 }
226 s_arg[i_arg].n_items += 1;
227 break;
228 case SET_RETAIN:
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;
233 break;
234 case SET_DELETE:
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;
239 break;
240 default:
241 fprintf(stderr, "Error (%s): unknown switch: %s\n", argv[0], s_arg[i_arg].list[0]);
242 exit(EXIT_FAILURE);
243 break;
244 }
245 } else {
246 if (input == NULL)
247 input = s_arg[i_arg].list[0];
248 else if (output == NULL)
249 output = s_arg[i_arg].list[0];
250 else {
251 fprintf(stderr, "too many filenames\n");
252 exit(EXIT_FAILURE);
253 }
254 }
255 }
256
257 if ((snapshot == 1) && (minimumInterval >= 0)) {
258 fprintf(stderr, "-snapshot and -minimumInterval options cannot be used together\n");
259 exit(EXIT_FAILURE);
260 }
261 if ((snapshot == 1) && (filterTime == 1)) {
262 fprintf(stderr, "-snapshot and -time options cannot be used together\n");
263 exit(EXIT_FAILURE);
264 }
265
266 processFilenames("sddsconvertalarmlog", &input, &output, pipeFlags, noWarnings, &tmpfile_used);
267
268 if (!SDDS_InitializeInput(&SDDS_input, input)) {
269 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
270 exit(EXIT_FAILURE);
271 }
272
273 readbackNameIndex = SDDS_VerifyArrayExists(&SDDS_input, FIND_SPECIFIED_TYPE, SDDS_STRING, "ReadbackName");
274 controlNameIndex = SDDS_VerifyArrayExists(&SDDS_input, FIND_SPECIFIED_TYPE, SDDS_STRING, "ControlName");
275 previousRowIndex = SDDS_VerifyColumnExists(&SDDS_input, FIND_NUMERIC_TYPE, "PreviousRow");
276 timeIndex = SDDS_VerifyColumnExists(&SDDS_input, FIND_NUMERIC_TYPE, "Time");
277 valueIndex = SDDS_VerifyColumnExists(&SDDS_input, FIND_NUMERIC_TYPE, "Value");
278 controlNameIndexIndex = SDDS_VerifyColumnExists(&SDDS_input, FIND_INTEGER_TYPE, "ControlNameIndex");
279 if ((readbackNameIndex == -1) && (controlNameIndex == -1)) {
280 fprintf(stderr, "Error: ReadbackName and ControlName arrays are both missing from the input file.\n");
281 exit(EXIT_FAILURE);
282 }
283 if (timeIndex == -1) {
284 fprintf(stderr, "Error: Time column is missing\n");
285 exit(EXIT_FAILURE);
286 }
287 if (valueIndex == -1) {
288 fprintf(stderr, "Error: Value column is missing\n");
289 exit(EXIT_FAILURE);
290 }
291 if (controlNameIndexIndex == -1) {
292 fprintf(stderr, "Error: ControlNameIndex column is missing\n");
293 exit(EXIT_FAILURE);
294 }
295
296 if (!SDDS_InitializeOutput(&SDDS_output, ascii_output ? SDDS_ASCII : (binary_output ? SDDS_BINARY : SDDS_input.layout.data_mode.mode), 1, NULL, NULL, output)) {
297 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
298 exit(EXIT_FAILURE);
299 }
300
301 outrow = 0;
302 while (SDDS_ReadTable(&SDDS_input) > 0) {
303 page++;
304 rows = SDDS_RowCount(&SDDS_input);
305 if (page == 1) {
306 if (readbackNameIndex != -1) {
307 readbackNameArray = SDDS_GetArray(&SDDS_input, "ReadbackName", NULL);
308 } else {
309 readbackNameArray = SDDS_GetArray(&SDDS_input, "ControlName", NULL);
310 }
311 if (readbackNameArray == NULL) {
312 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
313 exit(EXIT_FAILURE);
314 }
315
316 origToNewIndex = malloc(sizeof(long) * readbackNameArray->elements);
317 for (i = 0; i < readbackNameArray->elements; i++) {
318 origToNewIndex[i] = -1;
319 }
320
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++) {
324 rowdata[i] = 0;
325 }
326
327 if (SDDS_DefineSimpleColumn(&SDDS_output, "Time", NULL, SDDS_DOUBLE) == 0) {
328 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
329 exit(EXIT_FAILURE);
330 }
331 if (SDDS_DefineSimpleColumns(&SDDS_output, ColumnNames, ColumnName, NULL, output_type) == 0) {
332 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
333 exit(EXIT_FAILURE);
334 }
335 if (SDDS_WriteLayout(&SDDS_output) == 0) {
336 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
337 exit(EXIT_FAILURE);
338 }
339 if (snapshot) {
340 if (SDDS_StartTable(&SDDS_output, 1) == 0) {
341 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
342 exit(EXIT_FAILURE);
343 }
344 } else {
345 if (SDDS_StartTable(&SDDS_output, 100) == 0) {
346 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
347 exit(EXIT_FAILURE);
348 }
349 totalRows = 100;
350 }
351 } else {
352 if (readbackNameIndex != -1) {
353 readbackNameArray2 = SDDS_GetArray(&SDDS_input, "ReadbackName", NULL);
354 } else {
355 readbackNameArray2 = SDDS_GetArray(&SDDS_input, "ControlName", NULL);
356 }
357 if (readbackNameArray2 == NULL) {
358 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
359 exit(EXIT_FAILURE);
360 }
361 if (readbackNameArray->elements != readbackNameArray2->elements) {
362 fprintf(stderr, "Error: Unable to process multiple pages with different ReadbackName and/or ControlName columns\n");
363 exit(EXIT_FAILURE);
364 }
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");
368 exit(EXIT_FAILURE);
369 }
370 }
371 SDDS_FreeArray(readbackNameArray2);
372 }
373 if ((timeData = SDDS_GetColumnInDoubles(&SDDS_input, "Time")) == NULL) {
374 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
375 exit(EXIT_FAILURE);
376 }
377 if ((valueData = SDDS_GetColumnInDoubles(&SDDS_input, "Value")) == NULL) {
378 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
379 exit(EXIT_FAILURE);
380 }
381 if ((controlNameIndexData = SDDS_GetColumnInLong(&SDDS_input, "ControlNameIndex")) == NULL) {
382 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
383 exit(EXIT_FAILURE);
384 }
385 if (snapshot) {
386 snapshotrow = 0;
387 for (row = 0; row < rows; row++) {
388 if (timeData[row] <= epochtime) {
389 snapshotrow = row;
390 } else {
391 break;
392 }
393 }
394 }
395 if (filterTime) {
396 for (row = 0; row < rows; row++) {
397 if (timeData[row] <= startTime) {
398 startTimeRow = row;
399 } else {
400 break;
401 }
402 }
403 for (row = 0; row < rows; row++) {
404 if (timeData[row] <= endTime) {
405 endTimeRow = row;
406 } else {
407 break;
408 }
409 }
410 }
411 if (previousRowIndex != -1) {
412 if ((previousRowData = SDDS_GetColumnInDoubles(&SDDS_input, "PreviousRow")) == NULL) {
413 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
414 exit(EXIT_FAILURE);
415 }
416 for (row = rows - 1; row >= 0; row--) {
417 if (previousRowData[row] == -2) {
418 if (origToNewIndex[controlNameIndexData[row]] == -1) {
419 continue;
420 }
421 initRow = row;
422 break;
423 }
424 }
425 free(previousRowData);
426 }
427
428 if (minimumInterval > 0) {
429 previousTime = timeData[0] - minimumInterval - 1;
430 }
431 for (row = 0; row < rows; row++) {
432 if ((readbackNameArray->elements < controlNameIndexData[row]) ||
433 (controlNameIndexData[row] < 0)) {
434 /*sometimes there is invalid data in the original file */
435 continue;
436 }
437 if (origToNewIndex[controlNameIndexData[row]] == -1) {
438 continue;
439 }
440 rowdata[origToNewIndex[controlNameIndexData[row]]] = valueData[row];
441 if (previousRowIndex != -1) {
442 if (row < initRow) {
443 continue;
444 }
445 }
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) {
452 continue;
453 } else {
454 previousTime = timeData[row];
455 }
456 }
457 if ((snapshot == 0) && (totalRows == currentRows)) {
458 if (SDDS_LengthenTable(&SDDS_output, 100) == 0) {
459 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
460 exit(EXIT_FAILURE);
461 }
462 totalRows += 100;
463 }
464 currentRows++;
465 if (SDDS_SetRowValuesMod(&SDDS_output, SDDS_SET_BY_INDEX | SDDS_PASS_BY_REFERENCE, outrow, 0, &timeData[row], -1) == 0) {
466 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
467 exit(EXIT_FAILURE);
468 }
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) {
471 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
472 exit(EXIT_FAILURE);
473 }
474 }
475 if (snapshot)
476 break;
477 outrow++;
478 }
479 }
480 if (timeData)
481 free(timeData);
482 if (valueData)
483 free(valueData);
484 if (controlNameIndexData)
485 free(controlNameIndexData);
486 }
487 if (rowdata)
488 free(rowdata);
489 if (origToNewIndex)
490 free(origToNewIndex);
491
492 if (ColumnName) {
493 for (i = 0; i < ColumnNames; i++) {
494 if (ColumnName[i])
495 free(ColumnName[i]);
496 }
497 free(ColumnName);
498 }
499
500 SDDS_FreeArray(readbackNameArray);
501 if (SDDS_WriteTable(&SDDS_output) == 0) {
502 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
503 exit(EXIT_FAILURE);
504 }
505
506 if (!SDDS_Terminate(&SDDS_input) || !SDDS_Terminate(&SDDS_output)) {
507 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
508 exit(EXIT_FAILURE);
509 }
510
511 if (tmpfile_used && !replaceFileAndBackUp(input, output))
512 exit(EXIT_FAILURE);
513
514 free_scanargs(&s_arg, argc);
515 return EXIT_SUCCESS;
516}
517
518long SDDS_SetRowValuesMod(SDDS_DATASET *SDDS_dataset, long mode, int64_t row, ...) {
519 va_list argptr;
520 int32_t index;
521 long retval;
522 SDDS_LAYOUT *layout;
523 char *name;
524 char buffer[200];
525
526 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_SetRowValues"))
527 return (0);
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)");
531 return (0);
532 }
533 /*
534 if (!SDDS_CheckTabularData(SDDS_dataset, "SDDS_SetRowValues"))
535 return(0);
536 */
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);
540 SDDS_SetError(buffer);
541 return (0);
542 }
543 if (row > SDDS_dataset->n_rows - 1)
544 SDDS_dataset->n_rows = row + 1;
545
546 va_start(argptr, row);
547 layout = &SDDS_dataset->layout;
548
549 /* variable arguments are pairs of (index, value), where index is a long integer */
550 retval = -1;
551#ifdef DEBUG
552 fprintf(stderr, "setting row %" PRId64 " (mem slot %" PRId64 ")\n", row + SDDS_dataset->first_row_in_mem, row);
553#endif
554 do {
555 if (mode & SDDS_SET_BY_INDEX) {
556 if ((index = va_arg(argptr, int32_t)) == -1) {
557 retval = 1;
558 break;
559 }
560 if (index < 0 || index >= layout->n_columns) {
561 SDDS_SetError("Unable to set column values--index out of range (SDDS_SetRowValues)");
562 retval = 0;
563 break;
564 }
565#ifdef DEBUG
566 fprintf(stderr, "Setting values for column #%ld\n", index);
567#endif
568 } else {
569 if ((name = va_arg(argptr, char *)) == NULL) {
570 retval = 1;
571 break;
572 }
573#ifdef DEBUG
574 fprintf(stderr, "Setting values for column %s\n", name);
575#endif
576 if ((index = SDDS_GetColumnIndex(SDDS_dataset, name)) < 0) {
577 SDDS_SetError("Unable to set column values--name not recognized (SDDS_SetRowValues)");
578 retval = 0;
579 break;
580 }
581 }
582 switch (layout->column_definition[index].type) {
583 case SDDS_SHORT:
584 if (mode & SDDS_PASS_BY_VALUE)
585 *(((short *)SDDS_dataset->data[index]) + row) = (short)va_arg(argptr, int);
586 else
587 *(((short *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr, short *));
588 break;
589 case SDDS_USHORT:
590 if (mode & SDDS_PASS_BY_VALUE)
591 *(((unsigned short *)SDDS_dataset->data[index]) + row) = (unsigned short)va_arg(argptr, unsigned int);
592 else
593 *(((unsigned short *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr, unsigned short *));
594 break;
595 case SDDS_LONG:
596 if (mode & SDDS_PASS_BY_VALUE)
597 *(((int32_t *)SDDS_dataset->data[index]) + row) = va_arg(argptr, int32_t);
598 else
599 *(((int32_t *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr, int32_t *));
600 break;
601 case SDDS_ULONG:
602 if (mode & SDDS_PASS_BY_VALUE)
603 *(((uint32_t *)SDDS_dataset->data[index]) + row) = va_arg(argptr, uint32_t);
604 else
605 *(((uint32_t *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr, uint32_t *));
606 break;
607 case SDDS_LONG64:
608 if (mode & SDDS_PASS_BY_VALUE)
609 *(((int64_t *)SDDS_dataset->data[index]) + row) = va_arg(argptr, int64_t);
610 else
611 *(((int64_t *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr, int64_t *));
612 break;
613 case SDDS_ULONG64:
614 if (mode & SDDS_PASS_BY_VALUE)
615 *(((uint64_t *)SDDS_dataset->data[index]) + row) = va_arg(argptr, uint64_t);
616 else
617 *(((uint64_t *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr, uint64_t *));
618 break;
619 case SDDS_FLOAT:
620 if (mode & SDDS_PASS_BY_VALUE)
621 *(((float *)SDDS_dataset->data[index]) + row) = (float)va_arg(argptr, double);
622 else
623 *(((float *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr, double *));
624 break;
625 case SDDS_DOUBLE:
626 if (mode & SDDS_PASS_BY_VALUE)
627 *(((double *)SDDS_dataset->data[index]) + row) = va_arg(argptr, double);
628 else
629 *(((double *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr, double *));
630 break;
631 case SDDS_LONGDOUBLE:
632 if (mode & SDDS_PASS_BY_VALUE)
633 *(((long double *)SDDS_dataset->data[index]) + row) = va_arg(argptr, long double);
634 else
635 *(((long double *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr, long double *));
636 break;
637 case SDDS_STRING:
638 if (((char **)SDDS_dataset->data[index])[row]) {
639 free(((char **)SDDS_dataset->data[index])[row]);
640 ((char **)SDDS_dataset->data[index])[row] = NULL;
641 }
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)");
645 retval = 0;
646 }
647 } else {
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)");
650 retval = 0;
651 }
652 }
653 break;
654 case SDDS_CHARACTER:
655 if (mode & SDDS_PASS_BY_VALUE)
656 *(((char *)SDDS_dataset->data[index]) + row) = (char)va_arg(argptr, int);
657 else
658 *(((char *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr, char *));
659 break;
660 default:
661 SDDS_SetError("Unknown data type encountered (SDDS_SetRowValues");
662 retval = 0;
663 break;
664 }
665 } while (retval == -1);
666 va_end(argptr);
667 return (retval);
668}
669
670char **process_name_options(char **orig_name, long orig_names, char **delete, long deletes, char **retain, long retains, long *num_matched, long **origToNewIndex) {
671 long i, j;
672 char **new_name;
673 char *ptr = NULL;
674 long *orig_flag = NULL;
675
676 orig_flag = tmalloc(sizeof(*orig_flag) * orig_names);
677 for (i = 0; i < orig_names; i++)
678 (orig_flag)[i] = 1;
679
680 if (deletes) {
681 for (i = 0; i < deletes; i++) {
682 ptr = expand_ranges(delete[i]);
683 /*free(delete[i]); */ /* freed by free_scanargs */
684 delete[i] = ptr;
685 }
686 for (j = 0; j < orig_names; j++) {
687 for (i = 0; i < deletes; i++) {
688 if (wild_match(orig_name[j], delete[i])) {
689 (orig_flag)[j] = 0;
690 break;
691 }
692 }
693 }
694 for (i = 0; i < deletes; i++) {
695 if (delete[i])
696 free(delete[i]);
697 }
698 }
699
700 if (retains) {
701 for (i = 0; i < retains; i++) {
702 ptr = expand_ranges(retain[i]);
703 /*free(retain[i]); */ /* freed by free_scanargs */
704 retain[i] = ptr;
705 }
706 if (!deletes)
707 for (j = 0; j < orig_names; j++)
708 (orig_flag)[j] = 0;
709 for (j = 0; j < orig_names; j++) {
710 if ((orig_flag)[j])
711 continue;
712 for (i = 0; i < retains; i++) {
713 if (wild_match(orig_name[j], retain[i])) {
714 (orig_flag)[j] = 1;
715 break;
716 }
717 }
718 }
719 for (i = 0; i < retains; i++) {
720 if (retain[i])
721 free(retain[i]);
722 }
723 }
724
725 *num_matched = 0;
726 for (j = 0; j < orig_names; j++) {
727 if (orig_flag[j])
728 (*num_matched)++;
729 }
730 new_name = tmalloc(sizeof(*new_name) * (*num_matched));
731 i = 0;
732 for (j = 0; j < orig_names; j++) {
733 if (orig_flag[j]) {
734 (*origToNewIndex)[j] = i;
735 SDDS_CopyString(new_name + i, orig_name[j]);
736 i++;
737 }
738 }
739 free(orig_flag);
740
741 return (new_name);
742}
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_LengthenTable(SDDS_DATASET *SDDS_dataset, int64_t n_additional_rows)
SDDS_ARRAY * SDDS_GetArray(SDDS_DATASET *SDDS_dataset, char *array_name, SDDS_ARRAY *memory)
Retrieves an array from the current data table of an SDDS dataset.
int32_t * SDDS_GetColumnInLong(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves the data of a specified numerical column as an array of 32-bit integers,...
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:49
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_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.
Definition SDDS_utils.c:379
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.
Definition SDDS_utils.c:552
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:432
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
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.
Definition SDDS_utils.c:856
#define SDDS_ULONG
Identifier for the unsigned 32-bit integer data type.
Definition SDDStypes.h:67
#define SDDS_FLOAT
Identifier for the float data type.
Definition SDDStypes.h:43
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
#define SDDS_ULONG64
Identifier for the unsigned 64-bit integer data type.
Definition SDDStypes.h:55
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61
#define SDDS_SHORT
Identifier for the signed short integer data type.
Definition SDDStypes.h:73
#define SDDS_CHARACTER
Identifier for the character data type.
Definition SDDStypes.h:91
#define SDDS_USHORT
Identifier for the unsigned short integer data type.
Definition SDDStypes.h:79
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
#define SDDS_LONGDOUBLE
Identifier for the long double data type.
Definition SDDStypes.h:31
#define SDDS_LONG64
Identifier for the signed 64-bit integer data type.
Definition SDDStypes.h:49
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 * 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.
Definition replacefile.c:75
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:356
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
Definition scanargs.c:390
void free_scanargs(SCANNED_ARG **scanned, int argc)
Definition scanargs.c:584
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.
Definition wild_match.c:429
int wild_match(char *string, char *template)
Determine whether one string is a wildcard match for another.
Definition wild_match.c:49