SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
sddsmakedataset.c
Go to the documentation of this file.
1/**
2 * @file sddsmakedataset.c
3 * @brief Creates an SDDS file from input data provided via the command line.
4 *
5 * @details
6 * This program allows users to define parameters, columns, and arrays with associated data,
7 * and write them to an SDDS-formatted file. It supports various data types and provides options
8 * for customizing the output, including ASCII and binary formats.
9 *
10 * @section Usage
11 * ```
12 * sddsmakedataset [<outputFile> | -pipe=out]
13 * [-defaultType={double|float|long64|ulong64|long|ulong|short|ushort|string|character}]
14 * [-parameter=<name>[,type=<string>][,units=<string>][,symbol=<string>][,description=<string>]]
15 * [-data=<value>] -parameter=.... -data=...
16 * [-column=<name>[,type=<string>][,units=<string>][,symbol=<string>][,description=<string>]]
17 * [-data=<listOfCommaSeparatedValue>] -column=... -data=...
18 * [-array=<name>[,type=string][,units=string>][,symbol=<string>][,description=<string>]]
19 * [-data=<listOfCommaSeparatedValue>] -array=... -data=...
20 * [-noWarnings]
21 * [-ascii]
22 * [-description=<string>]
23 * [-contents=<string>]
24 * [-append[=merge]]
25 * [-majorOrder=row|column]
26 * ```
27 *
28 * @section Options
29 * | Option | Description |
30 * |-------------------------|---------------------------------------------------------------------------------------------|
31 * | `-pipe` | Outputs data to a pipe in SDDS format instead of to a file. |
32 * | `-defaultType` | Specifies the default data type for parameters and columns if not explicitly provided. |
33 * | `-parameter` | Defines a parameter with optional attributes (type, units, symbol, description). |
34 * | `-data` | Provides the data value for the preceding `-parameter`, `-column`, or `-array` option. |
35 * | `-column` | Defines a column with optional attributes (type, units, symbol, description). |
36 * | `-array` | Defines an array with optional attributes (type, units, symbol, description). |
37 * | `-noWarnings` | Suppresses warning messages. |
38 * | `-ascii` | Outputs the file in ASCII mode (default is binary). |
39 * | `-description` | Specifies a description for the output file. |
40 * | `-contents` | Specifies the contents of the description. |
41 * | `-append` | Appends data to an existing file; `merge` appends to the current page. |
42 * | `-majorOrder` | Specifies the major order of output: `row` or `column`. |
43 *
44 * @subsection Incompatibilities
45 * - `-data` must follow one of `-parameter`, `-column`, or `-array`.
46 *
47 * @subsection SR Specific Requirements
48 * - For `-defaultType`, valid values are: `double`, `float`, `long64`, `ulong64`, `long`, `ulong`, `short`, `ushort`, `string`, `character`.
49 * - The `-append` option allows `merge` as an optional value to merge data into the current page.
50 * - If `-contents` is specified, `-description` must also be provided.
51 *
52 * @copyright
53 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
54 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
55 *
56 * @license
57 * This file is distributed under the terms of the Software License Agreement
58 * found in the file LICENSE included with this distribution.
59 *
60 * @authors
61 * H. Shang, M. Borland, R. Soliday
62 */
63
64#include "mdb.h"
65#include "SDDS.h"
66#include "scan.h"
67
68/* Enumeration for option types */
69enum option_type {
70 CLO_PARAMETER,
71 CLO_COLUMN,
72 CLO_DATA,
73 CLO_PIPE,
74 CLO_DEFAULTTYPE,
75 CLO_NOWARNINGS,
76 CLO_DESCRIPTION,
77 CLO_CONTENTS,
78 CLO_ASCII,
79 CLO_MAJOR_ORDER,
80 CLO_APPEND,
81 CLO_ARRAY,
82 N_OPTIONS
83};
84
85/* Note: only -pipe=out is valid */
86char *option[N_OPTIONS] = {
87 "parameter",
88 "column",
89 "data",
90 "pipe",
91 "defaultType",
92 "noWarnings",
93 "description",
94 "contents",
95 "ascii",
96 "majorOrder",
97 "append",
98 "array",
99};
100
101char *USAGE =
102 "Usage: sddsmakedataset [<outputFile> | -pipe=out]\n"
103 " [-defaultType={double|float|long64|ulong64|long|ulong|short|ushort|string|character}]\n"
104 " [-parameter=<name>[,type=<string>][,units=<string>][,symbol=<string>][,description=<string>]]\n"
105 " [-data=<value>] -parameter=.... -data=...\n"
106 " [-column=<name>[,type=<string>][,units=<string>][,symbol=<string>][,description=<string>]]\n"
107 " [-data=<listOfCommaSeparatedValue>] -column=... -data=...\n"
108 " [-array=<name>[,type=string][,units=string>][,symbol=<string>][,description=<string>]]\n"
109 " [-data=<listOfCommaSeparatedValue>] -array=... -data=...\n"
110 " [-noWarnings]\n"
111 " [-ascii]\n"
112 " [-description=<string>]\n"
113 " [-contents=<string>]\n"
114 " [-append[=merge]]\n"
115 " [-majorOrder=row|column]\n"
116 "Options:\n"
117 " -defaultType=<type>\n"
118 " Specify the default data type for parameters and columns if not specified.\n"
119 " Available types: double, float, long64, ulong64, long, ulong, short, ushort, string, character.\n\n"
120 " -parameter=<name>[,type=<string>][,units=<string>][,symbol=<string>][,description=<string>]\n"
121 " Define a parameter with optional type, units, symbol, and description.\n"
122 " Must be followed by -data=<value> to provide the parameter's value.\n\n"
123 " -data=<value>\n"
124 " Provide the data value for the preceding -parameter, -column, or -array option.\n\n"
125 " -column=<name>[,type=<string>][,units=<string>][,symbol=<string>][,description=<string>]\n"
126 " Define a column with optional type, units, symbol, and description.\n"
127 " Must be followed by -data=<listOfCommaSeparatedValues> to provide the column's data.\n\n"
128 " -array=<name>[,type=<string>][,units=<string>][,symbol=<string>][,description=<string>]\n"
129 " Define an array with optional type, units, symbol, and description.\n"
130 " Must be followed by -data=<listOfCommaSeparatedValues> to provide the array's data.\n"
131 " Currently supports only one-dimensional arrays.\n\n"
132 " -noWarnings\n"
133 " Do not print out warning messages.\n\n"
134 " -ascii\n"
135 " Output file in ASCII mode. The default is binary.\n\n"
136 " -description=<string>\n"
137 " Provide a description of the output file.\n\n"
138 " -contents=<string>\n"
139 " Provide contents of the description.\n\n"
140 " -append[=merge]\n"
141 " Append data to an existing file. Use 'merge' to append to the current page.\n\n"
142 " -majorOrder=row|column\n"
143 " Specify output file in row or column major order.\n\n"
144 "<outputFile>\n"
145 " SDDS output file for writing the data.\n\n"
146 "-pipe=out\n"
147 " Output the data in SDDS format to the pipe instead of to a file.\n\n"
148 "Program by Hairong Shang. (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")\n";
149
150/* Structures for parameters and columns */
151typedef struct
152{
153 char *name, *dataString;
154 void *data;
155 char *description, *symbol, *unit, *typename;
156 long type;
158
159typedef struct
160{
161 char *name, **dataList;
162 void *data;
163 char *description, *symbol, *unit, *typename;
164 long type, rows;
166
167/* Function prototypes */
168COLUMN_INFO *InitializeColumnInfo();
169PARAMETER_INFO *InitializeParameteterInfo();
170void SetInfoData(PARAMETER_INFO **parameter, long parameters, COLUMN_INFO **column, long columns,
171 COLUMN_INFO **array, long arrays,
172 char *defaultType, long noWarnings, long maxrows);
173void FreeMemory(PARAMETER_INFO **parameter, long parameters, COLUMN_INFO **column, long columns,
174 COLUMN_INFO **array, long arrays, long maxrows);
175
176int main(int argc, char **argv) {
177 SCANNED_ARG *s_arg;
178 SDDS_DATASET outTable;
179 char *defaultType, *outputFile;
180 unsigned long pipeFlags, dummyFlags, majorOrderFlag;
181 PARAMETER_INFO **parameter;
182 COLUMN_INFO **column;
183 COLUMN_INFO **array;
184 long parameters, columns, arrays, previousOption, i, j, i_arg, currentOption, tmpfile_used, noWarnings, maxrows = 0, outputMode;
185 char *input = "obset";
186 char *description, *contents;
187 short columnMajorOrder = 0, append = 0;
188 int64_t rowsPresent;
189 int32_t colIndex, arrayIndex, dsize, startIndex;
190 SDDS_ARRAY *sdds_array = NULL;
191
192 description = contents = NULL;
193 parameter = NULL;
194 column = NULL;
195 array = NULL;
196 parameters = columns = arrays = 0;
197 outputFile = defaultType = NULL;
198 pipeFlags = 0;
199 tmpfile_used = noWarnings = 0;
200 outputMode = SDDS_BINARY;
201
204
205 argc = scanargs(&s_arg, argc, argv);
206 if (argc < 3) {
207 fprintf(stderr, "Error: Insufficient arguments provided.\n\n%s", USAGE);
208 exit(EXIT_FAILURE);
209 }
210 previousOption = -1;
211
212 for (i_arg = 1; i_arg < argc; i_arg++) {
213 if (s_arg[i_arg].arg_type == OPTION) {
214 delete_chars(s_arg[i_arg].list[0], "_");
215 currentOption = match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0);
216 if (currentOption == CLO_DATA && previousOption != CLO_PARAMETER && previousOption != CLO_COLUMN && previousOption != CLO_ARRAY) {
217 SDDS_Bomb("-data option must follow a -parameter, -column, or -array option.");
218 }
219 switch (currentOption) {
220 case CLO_MAJOR_ORDER:
221 majorOrderFlag = 0;
222 s_arg[i_arg].n_items -= 1;
223 if (s_arg[i_arg].n_items > 0 &&
224 (!scanItemList(&majorOrderFlag, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
225 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
226 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
227 SDDS_Bomb("Invalid -majorOrder syntax or value.");
228 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
229 columnMajorOrder = 1;
230 if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
231 columnMajorOrder = 0;
232 break;
233 case CLO_NOWARNINGS:
234 noWarnings = 1;
235 break;
236 case CLO_PARAMETER:
237 if (s_arg[i_arg].n_items < 2)
238 SDDS_Bomb("Invalid -parameter syntax.");
239 parameter = SDDS_Realloc(parameter, sizeof(*parameter) * (parameters + 1));
240 parameter[parameters] = InitializeParameteterInfo();
241 SDDS_CopyString(&(parameter[parameters]->name), s_arg[i_arg].list[1]);
242 s_arg[i_arg].list += 2;
243 s_arg[i_arg].n_items -= 2;
244 if (!(parameter[parameters]->name) || !strlen(parameter[parameters]->name))
245 SDDS_Bomb("Invalid -parameter syntax (no name).");
246 if (s_arg[i_arg].n_items > 0 &&
247 !scanItemList(&dummyFlags, s_arg[i_arg].list, &s_arg[i_arg].n_items, 0,
248 "type", SDDS_STRING, &(parameter[parameters]->typename), 1, 0,
249 "units", SDDS_STRING, &(parameter[parameters]->unit), 1, 0,
250 "symbol", SDDS_STRING, &(parameter[parameters]->symbol), 1, 0,
251 "description", SDDS_STRING, &(parameter[parameters]->description), 1, 0, NULL))
252 SDDS_Bomb("Invalid -parameter syntax.");
253 parameters++;
254 s_arg[i_arg].list -= 2;
255 s_arg[i_arg].n_items += 2;
256 break;
257 case CLO_COLUMN:
258 if (s_arg[i_arg].n_items < 2)
259 SDDS_Bomb("Invalid -column syntax.");
260 column = SDDS_Realloc(column, sizeof(*column) * (columns + 1));
261 column[columns] = InitializeColumnInfo();
262 SDDS_CopyString(&(column[columns]->name), s_arg[i_arg].list[1]);
263 s_arg[i_arg].list += 2;
264 s_arg[i_arg].n_items -= 2;
265 if (!(column[columns]->name) || !strlen(column[columns]->name))
266 SDDS_Bomb("Invalid -column syntax (no name).");
267 if (s_arg[i_arg].n_items > 0 &&
268 (!scanItemList(&dummyFlags, s_arg[i_arg].list, &s_arg[i_arg].n_items, 0,
269 "type", SDDS_STRING, &(column[columns]->typename), 1, 0,
270 "unit", SDDS_STRING, &(column[columns]->unit), 1, 0,
271 "symbol", SDDS_STRING, &(column[columns]->symbol), 1, 0,
272 "description", SDDS_STRING, &(column[columns]->description), 1, 0, NULL)))
273 SDDS_Bomb("Invalid -column syntax.");
274 columns++;
275 s_arg[i_arg].list -= 2;
276 s_arg[i_arg].n_items += 2;
277 break;
278 case CLO_ARRAY:
279 if (s_arg[i_arg].n_items < 2)
280 SDDS_Bomb("Invalid -array syntax.");
281 array = SDDS_Realloc(array, sizeof(*array) * (arrays + 1));
282 array[arrays] = InitializeColumnInfo();
283 SDDS_CopyString(&(array[arrays]->name), s_arg[i_arg].list[1]);
284 s_arg[i_arg].list += 2;
285 s_arg[i_arg].n_items -= 2;
286 if (!(array[arrays]->name) || !strlen(array[arrays]->name))
287 SDDS_Bomb("Invalid -array syntax (no name).");
288 if (s_arg[i_arg].n_items > 0 &&
289 (!scanItemList(&dummyFlags, s_arg[i_arg].list, &s_arg[i_arg].n_items, 0,
290 "type", SDDS_STRING, &(array[arrays]->typename), 1, 0,
291 "unit", SDDS_STRING, &(array[arrays]->unit), 1, 0,
292 "symbol", SDDS_STRING, &(array[arrays]->symbol), 1, 0,
293 "description", SDDS_STRING, &(array[arrays]->description), 1, 0, NULL)))
294 SDDS_Bomb("Invalid -array syntax.");
295 arrays++;
296 s_arg[i_arg].list -= 2;
297 s_arg[i_arg].n_items += 2;
298 break;
299 case CLO_DATA:
300 if (previousOption == CLO_PARAMETER) {
301 parameter[parameters - 1]->dataString = s_arg[i_arg].list[1];
302 }
303 if (previousOption == CLO_COLUMN) {
304 if (((s_arg[i_arg].n_items - 1) == 1) &&
305 (strlen(s_arg[i_arg].list[1]) > 1) &&
306 (((column[columns - 1]->typename) && (strcmp(column[columns - 1]->typename, "character") == 0)) ||
307 ((defaultType) && (strcmp(defaultType, "character") == 0)))) {
308 /* Assume each character is a separate data entry for character type */
309 column[columns - 1]->rows = strlen(s_arg[i_arg].list[1]);
310 column[columns - 1]->dataList = malloc(sizeof(*(column[columns - 1]->dataList)) * column[columns - 1]->rows);
311 for (j = 0; j < column[columns - 1]->rows; j++) {
312 char buffer[2] = {s_arg[i_arg].list[1][j], '\0'};
313 SDDS_CopyString(&column[columns - 1]->dataList[j], buffer);
314 }
315 } else {
316 column[columns - 1]->rows = s_arg[i_arg].n_items - 1;
317 column[columns - 1]->dataList = malloc(sizeof(*(column[columns - 1]->dataList)) * column[columns - 1]->rows);
318 for (j = 0; j < column[columns - 1]->rows; j++)
319 SDDS_CopyString(&column[columns - 1]->dataList[j], s_arg[i_arg].list[j + 1]);
320 }
321 }
322 if (previousOption == CLO_ARRAY) {
323 if (((s_arg[i_arg].n_items - 1) == 1) &&
324 (strlen(s_arg[i_arg].list[1]) > 1) &&
325 (((array[arrays - 1]->typename) && (strcmp(array[arrays - 1]->typename, "character") == 0)) ||
326 ((defaultType) && (strcmp(defaultType, "character") == 0)))) {
327 /* Assume each character is a separate data entry for character type */
328 array[arrays - 1]->rows = strlen(s_arg[i_arg].list[1]);
329 array[arrays - 1]->dataList = malloc(sizeof(*(array[arrays - 1]->dataList)) * array[arrays - 1]->rows);
330 for (j = 0; j < array[arrays - 1]->rows; j++) {
331 char buffer[2] = {s_arg[i_arg].list[1][j], '\0'};
332 SDDS_CopyString(&array[arrays - 1]->dataList[j], buffer);
333 }
334 } else {
335 array[arrays - 1]->rows = s_arg[i_arg].n_items - 1;
336 array[arrays - 1]->dataList = malloc(sizeof(*(array[arrays - 1]->dataList)) * array[arrays - 1]->rows);
337 for (j = 0; j < array[arrays - 1]->rows; j++)
338 SDDS_CopyString(&array[arrays - 1]->dataList[j], s_arg[i_arg].list[j + 1]);
339 }
340 }
341 break;
342 case CLO_DEFAULTTYPE:
343 if (s_arg[i_arg].n_items != 2)
344 SDDS_Bomb("Invalid -defaultType option.");
345 SDDS_CopyString(&defaultType, s_arg[i_arg].list[1]);
346 break;
347 case CLO_PIPE:
348 if (!processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
349 SDDS_Bomb("Invalid -pipe syntax.");
350 if (pipeFlags != USE_STDOUT)
351 SDDS_Bomb("Only -pipe=out syntax is valid.");
352 break;
353 case CLO_DESCRIPTION:
354 if (s_arg[i_arg].n_items != 2)
355 SDDS_Bomb("Invalid -description option.");
356 SDDS_CopyString(&description, s_arg[i_arg].list[1]);
357 break;
358 case CLO_CONTENTS:
359 if (s_arg[i_arg].n_items != 2)
360 SDDS_Bomb("Invalid -contents option.");
361 SDDS_CopyString(&contents, s_arg[i_arg].list[1]);
362 break;
363 case CLO_ASCII:
364 outputMode = SDDS_ASCII;
365 break;
366 case CLO_APPEND:
367 append = 1;
368 if (s_arg[i_arg].n_items != 1) {
369 append = 2;
370 if (s_arg[i_arg].n_items > 2 || strncmp(s_arg[i_arg].list[1], "merge", strlen(s_arg[i_arg].list[1])) != 0)
371 SDDS_Bomb("Invalid -append syntax.");
372 }
373 break;
374 default:
375 fprintf(stderr, "Error: Option %s is invalid.\n", s_arg[i_arg].list[0]);
376 exit(EXIT_FAILURE);
377 break;
378 }
379 previousOption = currentOption;
380 } else {
381 if (outputFile == NULL)
382 SDDS_CopyString(&outputFile, s_arg[i_arg].list[0]);
383 else {
384 fprintf(stderr, "Error: Too many filenames provided (%s).\n", s_arg[i_arg].list[0]);
385 exit(EXIT_FAILURE);
386 }
387 }
388 }
389
390 if (!outputFile && !pipeFlags) {
391 fprintf(stderr, "Error: Either an output file or -pipe=out must be specified.\n\n%s", USAGE);
392 exit(EXIT_FAILURE);
393 }
394 if (outputFile && pipeFlags) {
395 fprintf(stderr, "Error: Only one of output file and -pipe=out can be specified.\n\n%s", USAGE);
396 exit(EXIT_FAILURE);
397 }
398
399 processFilenames("sddsmakedataset", &input, &outputFile, pipeFlags, 1, &tmpfile_used);
400 if (!columns && !parameters && !arrays) {
401 fprintf(stderr, "Error: No data provided for writing.\n\n%s", USAGE);
402 exit(EXIT_FAILURE);
403 }
404 if (contents && !description) {
405 if (!noWarnings) {
406 fprintf(stderr, "Warning: Description text is provided for contents without a description. No description will be written.\n");
407 free(contents);
408 contents = NULL;
409 }
410 }
411 for (i = 0; i < columns; i++)
412 if (maxrows < column[i]->rows)
413 maxrows = column[i]->rows;
414 SetInfoData(parameter, parameters, column, columns, array, arrays, defaultType, noWarnings, maxrows);
415
416 if (append == 0) {
417 /* Write a new file */
418 if (!SDDS_InitializeOutput(&outTable, outputMode, 1, description, contents, outputFile))
419 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
420 outTable.layout.data_mode.column_major = columnMajorOrder;
421 for (i = 0; i < parameters; i++) {
422 if (parameter[i]->dataString) {
423 if (SDDS_DefineParameter(&outTable, parameter[i]->name, parameter[i]->symbol, parameter[i]->unit, parameter[i]->description, NULL, parameter[i]->type, NULL) < 0)
424 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
425 }
426 }
427
428 for (i = 0; i < columns; i++) {
429 if (column[i]->dataList) {
430 if (SDDS_DefineColumn(&outTable, column[i]->name, column[i]->symbol, column[i]->unit, column[i]->description, NULL, column[i]->type, 0) < 0)
431 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
432 }
433 }
434 for (i = 0; i < arrays; i++) {
435 if (array[i]->dataList) {
436 if (SDDS_DefineArray(&outTable, array[i]->name, array[i]->symbol, array[i]->unit, array[i]->description, NULL, array[i]->type, 0, 1, NULL) < 0)
437 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
438 }
439 }
440 if (!SDDS_WriteLayout(&outTable))
441 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
442 }
443 if (append == 1) {
444 /* Append */
445 if (!SDDS_InitializeAppend(&outTable, outputFile))
446 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
447 }
448 if (append == 2) {
449 /* Append to page, merge */
450 if (!SDDS_InitializeAppendToPage(&outTable, outputFile, maxrows, &rowsPresent))
451 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
452 }
453 if (append) {
454 /* Check the parameters, columns, and arrays */
455 for (i = 0; i < parameters; i++) {
456 if (parameter[i]->dataString) {
457 if (SDDS_GetParameterIndex(&outTable, parameter[i]->name) < 0) {
458 fprintf(stderr, "Error: Parameter '%s' does not exist in the existing file.\n", parameter[i]->name);
459 exit(EXIT_FAILURE);
460 }
461 }
462 }
463 if (SDDS_ParameterCount(&outTable) != parameters) {
464 fprintf(stderr, "Error: Parameter count does not match the existing file.\n");
465 exit(EXIT_FAILURE);
466 }
467 for (i = 0; i < columns; i++) {
468 if (column[i]->dataList) {
469 if (SDDS_GetColumnIndex(&outTable, column[i]->name) < 0) {
470 fprintf(stderr, "Error: Column '%s' does not exist in the existing file.\n", column[i]->name);
471 exit(EXIT_FAILURE);
472 }
473 }
474 }
475 if (SDDS_ColumnCount(&outTable) != columns) {
476 fprintf(stderr, "Error: Column count does not match the existing file.\n");
477 exit(EXIT_FAILURE);
478 }
479 for (i = 0; i < arrays; i++) {
480 if (array[i]->dataList) {
481 if (SDDS_GetArrayIndex(&outTable, array[i]->name) < 0) {
482 fprintf(stderr, "Error: Array '%s' does not exist in the existing file.\n", array[i]->name);
483 exit(EXIT_FAILURE);
484 }
485 }
486 }
487 if (SDDS_ArrayCount(&outTable) != arrays) {
488 fprintf(stderr, "Error: Array count does not match the existing file.\n");
489 exit(EXIT_FAILURE);
490 }
491 }
492
493 if (append == 0 || append == 1) {
494 if (!SDDS_StartPage(&outTable, maxrows))
495 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
496 for (i = 0; i < parameters; i++) {
497 if (parameter[i]->data) {
498 if (!SDDS_SetParameters(&outTable, SDDS_SET_BY_NAME | SDDS_PASS_BY_REFERENCE, parameter[i]->name, parameter[i]->data, NULL))
499 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
500 }
501 }
502 for (i = 0; i < columns; i++) {
503 if (column[i]->data) {
504 if (!SDDS_SetColumn(&outTable, SDDS_SET_BY_NAME, column[i]->data, maxrows, column[i]->name))
505 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
506 }
507 }
508 for (i = 0; i < arrays; i++) {
509 if (array[i]->data) {
510 if (!SDDS_SetArrayVararg(&outTable, array[i]->name, SDDS_CONTIGUOUS_DATA, array[i]->data, array[i]->rows))
511 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
512 }
513 }
514 }
515 if (append == 2) {
516 for (i = 0; i < columns; i++) {
517 if (column[i]->data) {
518 colIndex = SDDS_GetColumnIndex(&outTable, column[i]->name);
519 for (j = 0; j < maxrows; j++) {
520 switch (column[i]->type) {
521 case SDDS_LONGDOUBLE:
522 if (SDDS_SetRowValues(&outTable, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, rowsPresent + j,
523 colIndex, ((long double *)(column[i]->data))[j], -1) == 0)
524 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
525 break;
526 case SDDS_DOUBLE:
527 if (SDDS_SetRowValues(&outTable, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, rowsPresent + j,
528 colIndex, ((double *)(column[i]->data))[j], -1) == 0)
529 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
530 break;
531 case SDDS_FLOAT:
532 if (SDDS_SetRowValues(&outTable, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, rowsPresent + j,
533 colIndex, ((float *)(column[i]->data))[j], -1) == 0)
534 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
535 break;
536 case SDDS_LONG64:
537 if (SDDS_SetRowValues(&outTable, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, rowsPresent + j,
538 colIndex, ((int64_t *)(column[i]->data))[j], -1) == 0)
539 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
540 break;
541 case SDDS_ULONG64:
542 if (SDDS_SetRowValues(&outTable, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, rowsPresent + j,
543 colIndex, ((uint64_t *)(column[i]->data))[j], -1) == 0)
544 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
545 break;
546 case SDDS_LONG:
547 if (SDDS_SetRowValues(&outTable, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, rowsPresent + j,
548 colIndex, ((int32_t *)(column[i]->data))[j], -1) == 0)
549 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
550 break;
551 case SDDS_ULONG:
552 if (SDDS_SetRowValues(&outTable, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, rowsPresent + j,
553 colIndex, ((uint32_t *)(column[i]->data))[j], -1) == 0)
554 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
555 break;
556 case SDDS_SHORT:
557 if (SDDS_SetRowValues(&outTable, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, rowsPresent + j,
558 colIndex, ((short *)(column[i]->data))[j], -1) == 0)
559 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
560 break;
561 case SDDS_USHORT:
562 if (SDDS_SetRowValues(&outTable, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, rowsPresent + j,
563 colIndex, ((unsigned short *)(column[i]->data))[j], -1) == 0)
564 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
565 break;
566 case SDDS_CHARACTER:
567 if (SDDS_SetRowValues(&outTable, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, rowsPresent + j,
568 colIndex, ((char *)(column[i]->data))[j], -1) == 0)
569 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
570 break;
571 case SDDS_STRING:
572 if (SDDS_SetRowValues(&outTable, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, rowsPresent + j,
573 colIndex, ((char **)(column[i]->data))[j], -1) == 0)
574 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
575 break;
576 default:
577 SDDS_Bomb("Invalid data type provided.");
578 break;
579 }
580 }
581 }
582 }
583 for (i = 0; i < arrays; i++) {
584 if (array[i]->data) {
585 arrayIndex = SDDS_GetArrayIndex(&outTable, array[i]->name);
586 sdds_array = outTable.array + arrayIndex;
587 dsize = SDDS_type_size[sdds_array->definition->type - 1];
588 startIndex = sdds_array->elements;
589 sdds_array->elements += array[i]->rows;
590 sdds_array->data = SDDS_Realloc(sdds_array->data, dsize * sdds_array->elements);
591 if (array[i]->type == SDDS_STRING) {
592 if (!SDDS_CopyStringArray(((char **)sdds_array->data) + startIndex, array[i]->data, array[i]->rows))
593 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
594 } else {
595 memcpy((char *)sdds_array->data + dsize * startIndex, array[i]->data, dsize * array[i]->rows);
596 }
597 }
598 }
599 }
600
601 if (append == 2) {
602 if (!SDDS_UpdatePage(&outTable, FLUSH_TABLE) || !SDDS_Terminate(&outTable))
603 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
604 } else {
605 if (!SDDS_WritePage(&outTable) || !SDDS_Terminate(&outTable))
606 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
607 }
608
609 /* Free resources */
610 if (tmpfile_used && !replaceFileAndBackUp(input, outputFile))
611 exit(EXIT_FAILURE);
612 free_scanargs(&s_arg, argc);
613 FreeMemory(parameter, parameters, column, columns, array, arrays, maxrows);
614 if (defaultType)
615 free(defaultType);
616 if (outputFile)
617 free(outputFile);
618 if (description)
619 free(description);
620 if (contents)
621 free(contents);
622 return EXIT_SUCCESS;
623}
624
625COLUMN_INFO *InitializeColumnInfo() {
626 COLUMN_INFO *column = malloc(sizeof(*column));
627 if (!column) {
628 fprintf(stderr, "Error: Memory allocation failed for COLUMN_INFO.\n");
629 exit(EXIT_FAILURE);
630 }
631 column->name = column->unit = column->description = column->symbol = NULL;
632 column->data = NULL;
633 column->typename = NULL;
634 column->rows = 0;
635 column->type = -1;
636 column->dataList = NULL;
637 return column;
638}
639
640PARAMETER_INFO *InitializeParameteterInfo() {
641 PARAMETER_INFO *parameter = malloc(sizeof(*parameter));
642 if (!parameter) {
643 fprintf(stderr, "Error: Memory allocation failed for PARAMETER_INFO.\n");
644 exit(EXIT_FAILURE);
645 }
646 parameter->name = parameter->unit = parameter->description = parameter->symbol = NULL;
647 parameter->typename = NULL;
648 parameter->data = NULL;
649 parameter->type = -1;
650 parameter->dataString = NULL;
651 return parameter;
652}
653
654void SetInfoData(PARAMETER_INFO **parameter, long parameters, COLUMN_INFO **column, long columns, COLUMN_INFO **array, long arrays, char *defaultType,
655 long noWarnings, long maxrows) {
656 long i, j;
657 PARAMETER_INFO *par;
658 COLUMN_INFO *col;
659 char *type = NULL;
660
661 for (i = 0; i < parameters; i++) {
662 par = parameter[i];
663 if (!par->dataString) {
664 if (!noWarnings)
665 fprintf(stderr, "Warning: No data provided for parameter '%s'. It will not be written to the output file.\n", par->name);
666 continue;
667 }
668 if (par->typename)
669 SDDS_CopyString(&type, par->typename);
670 else {
671 if (defaultType)
672 SDDS_CopyString(&type, defaultType);
673 else
674 SDDS_CopyString(&type, "none");
675 }
676 if ((par->type = SDDS_IdentifyType(type)) <= 0) {
677 fprintf(stderr, "Error: Invalid data type '%s' for parameter '%s'.\n", type, par->name);
678 exit(EXIT_FAILURE);
679 }
680 par->data = malloc(sizeof(double)); /* Temporary allocation, actual type handled below */
681 if (!par->data) {
682 fprintf(stderr, "Error: Memory allocation failed for parameter data.\n");
683 exit(EXIT_FAILURE);
684 }
685 switch (par->type) {
686 case SDDS_LONGDOUBLE:
687 *((long double *)par->data) = strtold(par->dataString, NULL);
688 break;
689 case SDDS_DOUBLE:
690 *((double *)par->data) = atof(par->dataString);
691 break;
692 case SDDS_FLOAT:
693 *((float *)par->data) = (float)atof(par->dataString);
694 break;
695 case SDDS_LONG64:
696 *((int64_t *)par->data) = atoll(par->dataString);
697 break;
698 case SDDS_ULONG64:
699 *((uint64_t *)par->data) = strtoull(par->dataString, NULL, 10);
700 break;
701 case SDDS_LONG:
702 *((int32_t *)par->data) = atol(par->dataString);
703 break;
704 case SDDS_ULONG:
705 *((uint32_t *)par->data) = strtoul(par->dataString, NULL, 10);
706 break;
707 case SDDS_SHORT:
708 *((short *)par->data) = (short)atol(par->dataString);
709 break;
710 case SDDS_USHORT:
711 *((unsigned short *)par->data) = (unsigned short)atol(par->dataString);
712 break;
713 case SDDS_STRING:
714 cp_str((char **)par->data, par->dataString);
715 break;
716 case SDDS_CHARACTER:
717 *((char *)par->data) = par->dataString[0];
718 break;
719 default:
720 SDDS_Bomb("Invalid data type encountered while setting parameter data.");
721 break;
722 }
723 free(type);
724 }
725
726 for (i = 0; i < columns; i++) {
727 col = column[i];
728 if (!col->dataList) {
729 if (!noWarnings)
730 fprintf(stderr, "Warning: No data provided for column '%s'. It will not be written to the output file.\n", col->name);
731 continue;
732 }
733 if (col->typename)
734 SDDS_CopyString(&type, col->typename);
735 else {
736 if (defaultType)
737 SDDS_CopyString(&type, defaultType);
738 else
739 SDDS_CopyString(&type, "none");
740 }
741 if ((col->type = SDDS_IdentifyType(type)) <= 0) {
742 fprintf(stderr, "Error: Invalid data type '%s' for column '%s'.\n", type, col->name);
743 exit(EXIT_FAILURE);
744 }
745 if (col->rows < maxrows && !noWarnings)
746 fprintf(stderr, "Warning: Missing data for column '%s'. Filling with zeros.\n", col->name);
747 switch (col->type) {
748 case SDDS_LONGDOUBLE:
749 col->data = malloc(sizeof(long double) * maxrows);
750 if (!col->data) {
751 fprintf(stderr, "Error: Memory allocation failed for column '%s' data.\n", col->name);
752 exit(EXIT_FAILURE);
753 }
754 for (j = 0; j < col->rows; j++)
755 ((long double *)col->data)[j] = strtold(col->dataList[j], NULL);
756 for (j = col->rows; j < maxrows; j++)
757 ((long double *)col->data)[j] = 0.0L;
758 break;
759 case SDDS_DOUBLE:
760 col->data = malloc(sizeof(double) * maxrows);
761 if (!col->data) {
762 fprintf(stderr, "Error: Memory allocation failed for column '%s' data.\n", col->name);
763 exit(EXIT_FAILURE);
764 }
765 for (j = 0; j < col->rows; j++)
766 ((double *)col->data)[j] = atof(col->dataList[j]);
767 for (j = col->rows; j < maxrows; j++)
768 ((double *)col->data)[j] = 0.0;
769 break;
770 case SDDS_FLOAT:
771 col->data = malloc(sizeof(float) * maxrows);
772 if (!col->data) {
773 fprintf(stderr, "Error: Memory allocation failed for column '%s' data.\n", col->name);
774 exit(EXIT_FAILURE);
775 }
776 for (j = 0; j < col->rows; j++)
777 ((float *)col->data)[j] = (float)atof(col->dataList[j]);
778 for (j = col->rows; j < maxrows; j++)
779 ((float *)col->data)[j] = 0.0f;
780 break;
781 case SDDS_LONG64:
782 col->data = malloc(sizeof(int64_t) * maxrows);
783 if (!col->data) {
784 fprintf(stderr, "Error: Memory allocation failed for column '%s' data.\n", col->name);
785 exit(EXIT_FAILURE);
786 }
787 for (j = 0; j < col->rows; j++)
788 ((int64_t *)col->data)[j] = atoll(col->dataList[j]);
789 for (j = col->rows; j < maxrows; j++)
790 ((int64_t *)col->data)[j] = 0;
791 break;
792 case SDDS_ULONG64:
793 col->data = malloc(sizeof(uint64_t) * maxrows);
794 if (!col->data) {
795 fprintf(stderr, "Error: Memory allocation failed for column '%s' data.\n", col->name);
796 exit(EXIT_FAILURE);
797 }
798 for (j = 0; j < col->rows; j++)
799 ((uint64_t *)col->data)[j] = strtoull(col->dataList[j], NULL, 10);
800 for (j = col->rows; j < maxrows; j++)
801 ((uint64_t *)col->data)[j] = 0;
802 break;
803 case SDDS_LONG:
804 col->data = malloc(sizeof(int32_t) * maxrows);
805 if (!col->data) {
806 fprintf(stderr, "Error: Memory allocation failed for column '%s' data.\n", col->name);
807 exit(EXIT_FAILURE);
808 }
809 for (j = 0; j < col->rows; j++)
810 ((int32_t *)col->data)[j] = (int32_t)atol(col->dataList[j]);
811 for (j = col->rows; j < maxrows; j++)
812 ((int32_t *)col->data)[j] = 0;
813 break;
814 case SDDS_ULONG:
815 col->data = malloc(sizeof(uint32_t) * maxrows);
816 if (!col->data) {
817 fprintf(stderr, "Error: Memory allocation failed for column '%s' data.\n", col->name);
818 exit(EXIT_FAILURE);
819 }
820 for (j = 0; j < col->rows; j++)
821 ((uint32_t *)col->data)[j] = strtoul(col->dataList[j], NULL, 10);
822 for (j = col->rows; j < maxrows; j++)
823 ((uint32_t *)col->data)[j] = 0;
824 break;
825 case SDDS_SHORT:
826 col->data = malloc(sizeof(short) * maxrows);
827 if (!col->data) {
828 fprintf(stderr, "Error: Memory allocation failed for column '%s' data.\n", col->name);
829 exit(EXIT_FAILURE);
830 }
831 for (j = 0; j < col->rows; j++)
832 ((short *)col->data)[j] = (short)atol(col->dataList[j]);
833 for (j = col->rows; j < maxrows; j++)
834 ((short *)col->data)[j] = 0;
835 break;
836 case SDDS_USHORT:
837 col->data = malloc(sizeof(unsigned short) * maxrows);
838 if (!col->data) {
839 fprintf(stderr, "Error: Memory allocation failed for column '%s' data.\n", col->name);
840 exit(EXIT_FAILURE);
841 }
842 for (j = 0; j < col->rows; j++)
843 ((unsigned short *)col->data)[j] = (unsigned short)atol(col->dataList[j]);
844 for (j = col->rows; j < maxrows; j++)
845 ((unsigned short *)col->data)[j] = 0;
846 break;
847 case SDDS_CHARACTER:
848 col->data = malloc(sizeof(char) * maxrows);
849 if (!col->data) {
850 fprintf(stderr, "Error: Memory allocation failed for column '%s' data.\n", col->name);
851 exit(EXIT_FAILURE);
852 }
853 for (j = 0; j < col->rows; j++)
854 ((char *)col->data)[j] = col->dataList[j][0];
855 for (j = col->rows; j < maxrows; j++)
856 ((char *)col->data)[j] = '\0';
857 break;
858 case SDDS_STRING:
859 col->data = malloc(sizeof(char *) * maxrows);
860 if (!col->data) {
861 fprintf(stderr, "Error: Memory allocation failed for column '%s' data.\n", col->name);
862 exit(EXIT_FAILURE);
863 }
864 for (j = 0; j < col->rows; j++)
865 SDDS_CopyString(&((char **)col->data)[j], col->dataList[j]);
866 for (j = col->rows; j < maxrows; j++)
867 SDDS_CopyString(&((char **)col->data)[j], "");
868 break;
869 default:
870 SDDS_Bomb("Invalid data type encountered while setting column data.");
871 break;
872 }
873 free(type);
874 }
875
876 for (i = 0; i < arrays; i++) {
877 col = array[i];
878 if (!col->dataList) {
879 if (!noWarnings)
880 fprintf(stderr, "Warning: No data provided for array '%s'. It will not be written to the output file.\n", col->name);
881 continue;
882 }
883 if (col->typename)
884 SDDS_CopyString(&type, col->typename);
885 else {
886 if (defaultType)
887 SDDS_CopyString(&type, defaultType);
888 else
889 SDDS_CopyString(&type, "none");
890 }
891 if ((col->type = SDDS_IdentifyType(type)) <= 0) {
892 fprintf(stderr, "Error: Invalid data type '%s' for array '%s'.\n", type, col->name);
893 exit(EXIT_FAILURE);
894 }
895 switch (col->type) {
896 case SDDS_LONGDOUBLE:
897 col->data = malloc(sizeof(long double) * col->rows);
898 if (!col->data) {
899 fprintf(stderr, "Error: Memory allocation failed for array '%s' data.\n", col->name);
900 exit(EXIT_FAILURE);
901 }
902 for (j = 0; j < col->rows; j++)
903 ((long double *)col->data)[j] = strtold(col->dataList[j], NULL);
904 break;
905 case SDDS_DOUBLE:
906 col->data = malloc(sizeof(double) * col->rows);
907 if (!col->data) {
908 fprintf(stderr, "Error: Memory allocation failed for array '%s' data.\n", col->name);
909 exit(EXIT_FAILURE);
910 }
911 for (j = 0; j < col->rows; j++)
912 ((double *)col->data)[j] = atof(col->dataList[j]);
913 break;
914 case SDDS_FLOAT:
915 col->data = malloc(sizeof(float) * col->rows);
916 if (!col->data) {
917 fprintf(stderr, "Error: Memory allocation failed for array '%s' data.\n", col->name);
918 exit(EXIT_FAILURE);
919 }
920 for (j = 0; j < col->rows; j++)
921 ((float *)col->data)[j] = (float)atof(col->dataList[j]);
922 break;
923 case SDDS_LONG64:
924 col->data = malloc(sizeof(int64_t) * col->rows);
925 if (!col->data) {
926 fprintf(stderr, "Error: Memory allocation failed for array '%s' data.\n", col->name);
927 exit(EXIT_FAILURE);
928 }
929 for (j = 0; j < col->rows; j++)
930 ((int64_t *)col->data)[j] = atoll(col->dataList[j]);
931 break;
932 case SDDS_ULONG64:
933 col->data = malloc(sizeof(uint64_t) * col->rows);
934 if (!col->data) {
935 fprintf(stderr, "Error: Memory allocation failed for array '%s' data.\n", col->name);
936 exit(EXIT_FAILURE);
937 }
938 for (j = 0; j < col->rows; j++)
939 ((uint64_t *)col->data)[j] = strtoull(col->dataList[j], NULL, 10);
940 break;
941 case SDDS_LONG:
942 col->data = malloc(sizeof(int32_t) * col->rows);
943 if (!col->data) {
944 fprintf(stderr, "Error: Memory allocation failed for array '%s' data.\n", col->name);
945 exit(EXIT_FAILURE);
946 }
947 for (j = 0; j < col->rows; j++)
948 ((int32_t *)col->data)[j] = (int32_t)atol(col->dataList[j]);
949 break;
950 case SDDS_ULONG:
951 col->data = malloc(sizeof(uint32_t) * col->rows);
952 if (!col->data) {
953 fprintf(stderr, "Error: Memory allocation failed for array '%s' data.\n", col->name);
954 exit(EXIT_FAILURE);
955 }
956 for (j = 0; j < col->rows; j++)
957 ((uint32_t *)col->data)[j] = strtoul(col->dataList[j], NULL, 10);
958 break;
959 case SDDS_SHORT:
960 col->data = malloc(sizeof(short) * col->rows);
961 if (!col->data) {
962 fprintf(stderr, "Error: Memory allocation failed for array '%s' data.\n", col->name);
963 exit(EXIT_FAILURE);
964 }
965 for (j = 0; j < col->rows; j++)
966 ((short *)col->data)[j] = (short)atol(col->dataList[j]);
967 break;
968 case SDDS_USHORT:
969 col->data = malloc(sizeof(unsigned short) * col->rows);
970 if (!col->data) {
971 fprintf(stderr, "Error: Memory allocation failed for array '%s' data.\n", col->name);
972 exit(EXIT_FAILURE);
973 }
974 for (j = 0; j < col->rows; j++)
975 ((unsigned short *)col->data)[j] = (unsigned short)atol(col->dataList[j]);
976 break;
977 case SDDS_CHARACTER:
978 col->data = malloc(sizeof(char) * col->rows);
979 if (!col->data) {
980 fprintf(stderr, "Error: Memory allocation failed for array '%s' data.\n", col->name);
981 exit(EXIT_FAILURE);
982 }
983 for (j = 0; j < col->rows; j++)
984 ((char *)col->data)[j] = col->dataList[j][0];
985 break;
986 case SDDS_STRING:
987 col->data = malloc(sizeof(char *) * col->rows);
988 if (!col->data) {
989 fprintf(stderr, "Error: Memory allocation failed for array '%s' data.\n", col->name);
990 exit(EXIT_FAILURE);
991 }
992 for (j = 0; j < col->rows; j++)
993 SDDS_CopyString(&((char **)col->data)[j], col->dataList[j]);
994 break;
995 default:
996 SDDS_Bomb("Invalid data type encountered while setting array data.");
997 break;
998 }
999 free(type);
1000 }
1001}
1002
1003void FreeMemory(PARAMETER_INFO **parameter, long parameters, COLUMN_INFO **column, long columns, COLUMN_INFO **array, long arrays, long maxrows) {
1004 long i, j;
1005
1006 /* Free parameters */
1007 for (i = 0; i < parameters; i++) {
1008 if (parameter[i]->name)
1009 free(parameter[i]->name);
1010 if (parameter[i]->data)
1011 free(parameter[i]->data);
1012 if (parameter[i]->unit)
1013 free(parameter[i]->unit);
1014 if (parameter[i]->description)
1015 free(parameter[i]->description);
1016 if (parameter[i]->symbol)
1017 free(parameter[i]->symbol);
1018 if (parameter[i]->typename)
1019 free(parameter[i]->typename);
1020 free(parameter[i]);
1021 }
1022 if (parameters)
1023 free(parameter);
1024
1025 /* Free columns */
1026 for (i = 0; i < columns; i++) {
1027 if (column[i]->name)
1028 free(column[i]->name);
1029 if (column[i]->dataList) {
1030 for (j = 0; j < column[i]->rows; j++)
1031 free(column[i]->dataList[j]);
1032 free(column[i]->dataList);
1033 }
1034 if (column[i]->type != SDDS_STRING) {
1035 if (column[i]->data)
1036 free(column[i]->data);
1037 } else {
1038 if (column[i]->data) {
1039 for (j = 0; j < maxrows; j++)
1040 free(((char **)column[i]->data)[j]);
1041 free(column[i]->data);
1042 }
1043 }
1044 if (column[i]->unit)
1045 free(column[i]->unit);
1046 if (column[i]->symbol)
1047 free(column[i]->symbol);
1048 if (column[i]->description)
1049 free(column[i]->description);
1050 free(column[i]);
1051 }
1052 if (columns)
1053 free(column);
1054
1055 /* Free arrays */
1056 for (i = 0; i < arrays; i++) {
1057 if (array[i]->name)
1058 free(array[i]->name);
1059 if (array[i]->dataList) {
1060 for (j = 0; j < array[i]->rows; j++)
1061 free(array[i]->dataList[j]);
1062 free(array[i]->dataList);
1063 }
1064 if (array[i]->type != SDDS_STRING) {
1065 if (array[i]->data)
1066 free(array[i]->data);
1067 } else {
1068 if (array[i]->data) {
1069 for (j = 0; j < array[i]->rows; j++)
1070 free(((char **)array[i]->data)[j]);
1071 free(array[i]->data);
1072 }
1073 }
1074 if (array[i]->unit)
1075 free(array[i]->unit);
1076 if (array[i]->symbol)
1077 free(array[i]->symbol);
1078 if (array[i]->description)
1079 free(array[i]->description);
1080 free(array[i]);
1081 }
1082 if (arrays)
1083 free(array);
1084}
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_type_size[SDDS_NUM_TYPES]
Array of sizes for each supported data type.
Definition SDDS_data.c:62
int32_t SDDS_SetRowValues(SDDS_DATASET *SDDS_dataset, int32_t mode, int64_t row,...)
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
int32_t SDDS_SetArrayVararg(SDDS_DATASET *SDDS_dataset, char *array_name, int32_t mode, void *data_pointer,...)
Sets the values of an array variable in the SDDS dataset using variable arguments for dimensions.
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
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_InitializeAppend(SDDS_DATASET *SDDS_dataset, const char *filename)
Initializes the SDDS dataset for appending data by adding a new page to an existing file.
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_InitializeAppendToPage(SDDS_DATASET *SDDS_dataset, const char *filename, int64_t updateInterval, int64_t *rowsPresentReturn)
Initializes the SDDS dataset for appending data to the last page of an existing file.
int32_t SDDS_DefineArray(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, int32_t dimensions, const char *group_name)
Defines a data array within the SDDS dataset.
int32_t SDDS_UpdatePage(SDDS_DATASET *SDDS_dataset, uint32_t mode)
Updates the current page of the SDDS dataset.
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
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.
int32_t SDDS_GetArrayIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named array in the SDDS dataset.
int32_t SDDS_ParameterCount(SDDS_DATASET *page)
Retrieves the number of parameters in the SDDS dataset.
int32_t SDDS_GetParameterIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named parameter in the SDDS dataset.
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
int32_t SDDS_ColumnCount(SDDS_DATASET *page)
Retrieves the number of columns in the SDDS dataset.
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_CopyStringArray(char **target, char **source, int64_t n_strings)
Copies an array of strings from source to target.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
int32_t SDDS_IdentifyType(char *typeName)
Identifies the SDDS data type based on its string name.
int32_t SDDS_ArrayCount(SDDS_DATASET *page)
Retrieves the number of arrays in the SDDS dataset.
int32_t SDDS_CheckDatasetStructureSize(int32_t size)
Verifies that the size of the SDDS_DATASET structure matches the expected size.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
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
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
Definition SDDS_utils.c:677
#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
char * cp_str(char **s, char *t)
Copies a string, allocating memory for storage.
Definition cp_str.c:28
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.