32#include "match_string.h"
34#define SET_DESCRIPTION 0
35#define SET_MPL_LABELS 1
36#define SET_MAJOR_ORDER 2
39static char *option[N_OPTIONS] = {
40 "description",
"mpllabels"};
42char *USAGE =
"citi2sdds <inputfile> <outputfile>\n\
43 [-description=<text>,<contents>]\n\
44 [-mpllabels=<title>,<topline>] [-majorOrder=row|column]\n\n\
45This program converts HP CITI format waveforms to SDDS format.\n\n\
46Program by Michael Borland (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")\n";
50#define CITIFILE_TAG "CITIFILE"
51#define CITIFILE_VERSION "A.01.00"
53#define CITI_NA_KEYWORD 0
54#define CITI_NAME_KEYWORD 1
55#define CITI_VAR_KEYWORD 2
56#define CITI_DATA_KEYWORD 3
57#define CITI_VAR_LIST_KEYWORD 4
58#define CITI_BEGIN_KEYWORD 5
59#define CITI_SEG_LIST_BEGIN 6
60#define CITI_COMMENT_KEYWORD 7
61#define CITI_CONSTANT_KEYWORD 8
62#define N_CITI_KEYWORDS 9
63static char *citi_keyword[N_CITI_KEYWORDS] = {
64 "#NA",
"NAME",
"VAR",
"DATA",
"VAR_LIST_BEGIN",
"BEGIN",
65 "SEG_LIST_BEGIN",
"COMMENT",
"CONSTANT"};
67long read_CITI_var_list(FILE *fpi,
double *var_list,
long points);
68long read_CITI_data(FILE *fpi,
double *real_data,
double *imag_data,
long points);
69long read_CITI_seg_list(FILE *fpi,
double *seg_list,
long points);
70void alter_data_name(
char *name);
72int main(
int argc,
char **argv) {
75 long i, i_arg, points;
76 char *input, *output, *name, *indep_var, *var_list_format;
77 char *mpl_title, *mpl_topline, *descrip_text, *descrip_contents;
79 char buffer[BUFSIZE], buffer0[BUFSIZE], buffer1[BUFSIZE];
80 char *ptr, *ptr1, *ptr2;
81 char **data_name, *package_name, *data_format;
82 long data_names, data_sets_seen, data_sets_expected, realIndex, imagIndex;
83 double **real_data, **imag_data, *var_list;
84 unsigned long majorOrderFlag;
85 short columnMajorOrder = 0;
87 argc =
scanargs(&scanned, argc, argv);
91 input = output = package_name = data_format = indep_var = var_list_format = ptr = NULL;
92 mpl_title = mpl_topline = descrip_text = descrip_contents = NULL;
93 data_names = realIndex = imagIndex = 0;
95 real_data = imag_data = NULL;
97 data_sets_expected = data_sets_seen = 0;
100 for (i_arg = 1; i_arg < argc; i_arg++) {
101 if (scanned[i_arg].arg_type == OPTION) {
104 switch (
match_string(scanned[i_arg].list[0], option, N_OPTIONS, 0)) {
105 case SET_MAJOR_ORDER:
107 scanned[i_arg].n_items--;
108 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)))
109 SDDS_Bomb(
"invalid -majorOrder syntax/values");
110 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
111 columnMajorOrder = 1;
112 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
113 columnMajorOrder = 0;
115 case SET_DESCRIPTION:
116 if (scanned[i_arg].n_items != 3)
117 SDDS_Bomb(
"invalid -description syntax");
118 descrip_text = scanned[i_arg].list[1];
119 descrip_contents = scanned[i_arg].list[2];
122 if (scanned[i_arg].n_items != 3)
124 mpl_title = scanned[i_arg].list[1];
125 mpl_topline = scanned[i_arg].list[2];
133 input = scanned[i_arg].list[0];
135 output = scanned[i_arg].list[0];
146 if (!fgets(buffer, BUFSIZE, fpi) || strncmp(buffer, CITIFILE_TAG, strlen(CITIFILE_TAG)) != 0 || !(ptr = strchr(buffer,
' ')))
147 SDDS_Bomb(
"valid CITIFILE version line not found");
149 ptr[strlen(ptr) - 1] = 0;
150 if (strncmp(ptr, CITIFILE_VERSION, strlen(CITIFILE_VERSION)) != 0)
151 fprintf(stderr,
"warning: the CITIFILE version is %s--this program is only designed for version %s\n", ptr, CITIFILE_VERSION);
155 SDDS_table.layout.data_mode.column_major = columnMajorOrder;
156 if ((mpl_title &&
SDDS_DefineParameter(&SDDS_table,
"mplTitle", NULL, NULL, NULL, NULL,
SDDS_STRING, mpl_title) < 0) || (mpl_topline &&
SDDS_DefineParameter(&SDDS_table,
"mplTopline", NULL, NULL, NULL, NULL,
SDDS_STRING, mpl_topline) < 0))
159 while (fgets(buffer, BUFSIZE, fpi)) {
161 fputs(buffer, stderr);
163 buffer[strlen(buffer) - 1] = 0;
164 strcpy(buffer0, buffer);
166 if ((ptr1 = strchr(buffer,
' ')))
168 switch (
match_string(buffer, citi_keyword, N_CITI_KEYWORDS, EXACT_MATCH)) {
169 case CITI_NA_KEYWORD:
171 if (!*ptr1 || !(ptr2 = strchr(ptr1,
' '))) {
172 fprintf(stderr,
"The following line contains an apparently invalid #NA keyword:\n%s\n", buffer0);
179 SDDS_SetError(
"Problem creating parameter for #NA keyword in the following line:");
183 case CITI_NAME_KEYWORD:
185 fprintf(stderr,
"The following line contains erroneous input:\n%s\n", buffer0);
189 fprintf(stderr,
"NAME: %s\n", ptr1);
191 cp_str(&package_name, ptr1);
194 SDDS_SetError(
"Problem creating parameter for NAME keyword in the following line:");
198 case CITI_VAR_KEYWORD:
200 fprintf(stderr,
"The following line contains erroneous input:\n%s\n", buffer0);
204 fprintf(stderr,
"VAR: %s\n", ptr1);
207 fprintf(stderr,
"The following line contains erroneous input:\n%s\n", buffer0);
212 SDDS_SetError(
"Problem creating column for data element in the following line:");
216 case CITI_CONSTANT_KEYWORD:
217 if (!ptr1 || !(ptr2 = strchr(ptr1,
' '))) {
218 fprintf(stderr,
"The following line contains erroneous input:\n%s\n", buffer0);
222 fprintf(stderr,
"CONSTANT: %s\n", ptr1);
227 SDDS_SetError(
"Problem creating parameter for CONSTANT keyword in the following line:");
231 case CITI_COMMENT_KEYWORD:
233 fprintf(stderr,
"The following line contains erroneous input:\n%s\n", buffer0);
237 fprintf(stderr,
"COMMENT: %s\n", ptr1);
240 case CITI_DATA_KEYWORD:
241 if (!ptr1 || !(ptr2 = strchr(ptr1,
' '))) {
242 fprintf(stderr,
"The following line contains erroneous input:\n%s\n", buffer0);
246 fprintf(stderr,
"DATA: %s\n", ptr1);
249 cp_str(&data_format, ptr2);
250 data_name =
trealloc(data_name,
sizeof(*data_name) * (data_names + 1));
251 cp_str(data_name + data_names, ptr1);
252 alter_data_name(data_name[data_names]);
253 real_data =
trealloc(real_data,
sizeof(*real_data) * (data_names + 1));
254 imag_data =
trealloc(imag_data,
sizeof(*imag_data) * (data_names + 1));
255 sprintf(buffer,
"%sReal", data_name[data_names]);
256 sprintf(buffer1,
"%sImag", data_name[data_names]);
257 if ((realIndex =
SDDS_DefineColumn(&SDDS_table, buffer, NULL, NULL, NULL, NULL,
SDDS_DOUBLE, 0)) < 0 || (imagIndex =
SDDS_DefineColumn(&SDDS_table, buffer1, NULL, NULL, NULL, NULL,
SDDS_DOUBLE, 0)) < 0) {
259 SDDS_SetError(
"Problem creating column for data element in the following line:");
264 case CITI_VAR_LIST_KEYWORD:
266 fprintf(stderr,
"The following line contains erroneous input:\n%s\n", buffer0);
268 fprintf(stderr,
"VAR_LIST_BEGIN seen\n");
271 SDDS_Bomb(
"VAR_LIST_BEGIN statement seen without prior VAR statement");
272 var_list =
tmalloc(
sizeof(*var_list) * points);
273 if (!read_CITI_var_list(fpi, var_list, points))
276 case CITI_BEGIN_KEYWORD:
278 fprintf(stderr,
"The following line contains erroneous input:\n%s\n", buffer0);
280 fprintf(stderr,
"BEGIN seen\n");
283 SDDS_Bomb(
"BEGIN statement seen without prior VAR statement");
284 real_data[data_sets_seen] =
tmalloc(
sizeof(**real_data) * points);
285 imag_data[data_sets_seen] =
tmalloc(
sizeof(**imag_data) * points);
286 if (!read_CITI_data(fpi, real_data[data_sets_seen], imag_data[data_sets_seen], points))
287 SDDS_Bomb(
"problem reading data section");
290 case CITI_SEG_LIST_BEGIN:
292 fprintf(stderr,
"The following line contains erroneous input:\n%s\n", buffer0);
294 fprintf(stderr,
"SEG_LIST_BEGIN seen\n");
297 SDDS_Bomb(
"SEG_LIST_BEGIN statement seen without prior SEG statement");
298 var_list =
tmalloc(
sizeof(*var_list) * points);
299 if (!read_CITI_seg_list(fpi, var_list, points))
303 fprintf(stderr,
"unidentifiable line in file--not CITI format:\n\"%s\"\n", buffer0);
310 if (data_sets_seen != (data_sets_expected = data_names))
311 SDDS_Bomb(
"fewer data sets than expected were actually present");
313 fprintf(stderr,
"warning: no independent variable data---supplying index\n");
314 var_list =
tmalloc(
sizeof(*var_list) * points);
315 for (i = 0; i < points; i++)
318 if (!
SDDS_WriteLayout(&SDDS_table) || !SDDS_StartTable(&SDDS_table, points))
320 if (!
SDDS_SetColumn(&SDDS_table, SDDS_SET_BY_NAME, (
void *)var_list, points, indep_var))
322 for (i = 0; i < data_sets_expected; i++) {
323 if (!
SDDS_SetColumn(&SDDS_table, SDDS_SET_BY_INDEX, (
void *)real_data[i], points, realIndex) || !
SDDS_SetColumn(&SDDS_table, SDDS_SET_BY_INDEX, (
void *)imag_data[i], points, imagIndex)) {
324 fprintf(stderr,
"problem setting data for column(s) %s\n", data_name[i]);
328 if (!SDDS_WriteTable(&SDDS_table) || !
SDDS_Terminate(&SDDS_table))
333char *process_column_definition(
char **argv,
long argc) {
334 char buffer[SDDS_MAXLINE], *ptr;
339 sprintf(buffer,
"&column name=%s, ", argv[0]);
340 for (i = 1; i < argc; i++) {
341 if (!strchr(argv[i],
'='))
343 strcat(buffer, argv[i]);
344 strcat(buffer,
", ");
346 if (!strstr(buffer,
"type="))
347 strcat(buffer,
"type=character ");
348 strcat(buffer,
"&end");
353long read_CITI_var_list(FILE *fpi,
double *var_list,
long points) {
355 char buffer[BUFSIZE];
358 while (fgets(buffer, BUFSIZE, fpi) && i < points) {
359 buffer[strlen(buffer) - 1] = 0;
360 if (strcmp(buffer,
"VAR_LIST_END") == 0)
371long read_CITI_data(FILE *fpi,
double *real_data,
double *imag_data,
long points) {
373 char buffer[BUFSIZE];
376 while (fgets(buffer, BUFSIZE, fpi) && i < points) {
377 buffer[strlen(buffer) - 1] = 0;
378 if (strcmp(buffer,
"END") == 0)
389long read_CITI_seg_list(FILE *fpi,
double *seg_list,
long points) {
390 char buffer[BUFSIZE];
392 double start, end, delta;
398 delta = (end - start) / (points - 1);
400 if (!fgets(buffer, BUFSIZE, fpi))
402 buffer[strlen(buffer) - 1] = 0;
403 if (strcmp(buffer,
"SEG_LIST_END") != 0)
406 for (i = 0; i < points; i++)
407 seg_list[i] = start + i * delta;
411void alter_data_name(
char *name) {
413 if ((ptr = strchr(name,
'[')))
415 if ((ptr = strchr(name,
']')))
417 if ((ptr = strchr(name,
',')))
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_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.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
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.
#define SDDS_STRING
Identifier for the string data type.
#define SDDS_DOUBLE
Identifier for the double data type.
void * trealloc(void *old_ptr, uint64_t size_of_block)
Reallocates a memory block to a new size.
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
char * cp_str(char **s, char *t)
Copies a string, allocating memory for storage.
int get_long(long *iptr, char *s)
Parses a long integer value from the given string.
int get_double(double *dptr, char *s)
Parses a double value from the given string.
char * get_token(char *s)
Extracts the next token from the input string.
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.
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)
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.