46#include "match_string.h"
56static char *option[N_OPTIONS] = {
64 " citi2sdds <inputfile> <outputfile>\n"
65 " [-description=<text>,<contents>]\n"
66 " [-mpllabels=<title>,<topline>] \n"
67 " [-majorOrder=row|column]\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";
77#define CITIFILE_TAG "CITIFILE"
78#define CITIFILE_VERSION "A.01.00"
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"};
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);
99int main(
int argc,
char **argv) {
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;
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;
114 argc =
scanargs(&scanned, argc, argv);
116 fprintf(stderr,
"%s", USAGE);
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;
124 real_data = imag_data = NULL;
126 data_sets_expected = data_sets_seen = 0;
129 for (i_arg = 1; i_arg < argc; i_arg++) {
130 if (scanned[i_arg].arg_type == OPTION) {
133 switch (
match_string(scanned[i_arg].list[0], option, N_OPTIONS, 0)) {
134 case SET_MAJOR_ORDER:
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;
144 case SET_DESCRIPTION:
145 if (scanned[i_arg].n_items != 3) {
146 SDDS_Bomb(
"invalid -description syntax");
148 descrip_text = scanned[i_arg].list[1];
149 descrip_contents = scanned[i_arg].list[2];
152 if (scanned[i_arg].n_items != 3) {
155 mpl_title = scanned[i_arg].list[1];
156 mpl_topline = scanned[i_arg].list[2];
164 input = scanned[i_arg].list[0];
166 output = scanned[i_arg].list[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");
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);
190 SDDS_table.layout.data_mode.column_major = columnMajorOrder;
195 while (fgets(buffer, BUFSIZE, fpi)) {
197 fputs(buffer, stderr);
199 buffer[strlen(buffer) - 1] = 0;
200 strcpy(buffer0, buffer);
202 if ((ptr1 = strchr(buffer,
' ')))
204 switch (
match_string(buffer, citi_keyword, N_CITI_KEYWORDS, EXACT_MATCH)) {
205 case CITI_NA_KEYWORD:
207 if (!*ptr1 || !(ptr2 = strchr(ptr1,
' '))) {
208 fprintf(stderr,
"The following line contains an apparently invalid #NA keyword:\n%s\n", buffer0);
215 SDDS_SetError(
"Problem creating parameter for #NA keyword in the following line:");
219 case CITI_NAME_KEYWORD:
221 fprintf(stderr,
"The following line contains erroneous input:\n%s\n", buffer0);
225 fprintf(stderr,
"NAME: %s\n", ptr1);
227 cp_str(&package_name, ptr1);
230 SDDS_SetError(
"Problem creating parameter for NAME keyword in the following line:");
234 case CITI_VAR_KEYWORD:
236 fprintf(stderr,
"The following line contains erroneous input:\n%s\n", buffer0);
240 fprintf(stderr,
"VAR: %s\n", ptr1);
243 fprintf(stderr,
"The following line contains erroneous input:\n%s\n", buffer0);
248 SDDS_SetError(
"Problem creating column for data element in the following line:");
252 case CITI_CONSTANT_KEYWORD:
253 if (!ptr1 || !(ptr2 = strchr(ptr1,
' '))) {
254 fprintf(stderr,
"The following line contains erroneous input:\n%s\n", buffer0);
258 fprintf(stderr,
"CONSTANT: %s\n", ptr1);
263 SDDS_SetError(
"Problem creating parameter for CONSTANT keyword in the following line:");
267 case CITI_COMMENT_KEYWORD:
269 fprintf(stderr,
"The following line contains erroneous input:\n%s\n", buffer0);
273 fprintf(stderr,
"COMMENT: %s\n", ptr1);
276 case CITI_DATA_KEYWORD:
277 if (!ptr1 || !(ptr2 = strchr(ptr1,
' '))) {
278 fprintf(stderr,
"The following line contains erroneous input:\n%s\n", buffer0);
282 fprintf(stderr,
"DATA: %s\n", ptr1);
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]);
296 SDDS_SetError(
"Problem creating column for data element in the following line:");
301 case CITI_VAR_LIST_KEYWORD:
303 fprintf(stderr,
"The following line contains erroneous input:\n%s\n", buffer0);
307 fprintf(stderr,
"VAR_LIST_BEGIN seen\n");
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))
315 case CITI_BEGIN_KEYWORD:
317 fprintf(stderr,
"The following line contains erroneous input:\n%s\n", buffer0);
321 fprintf(stderr,
"BEGIN seen\n");
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");
331 case CITI_SEG_LIST_BEGIN:
333 fprintf(stderr,
"The following line contains erroneous input:\n%s\n", buffer0);
337 fprintf(stderr,
"SEG_LIST_BEGIN seen\n");
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))
346 fprintf(stderr,
"Unidentifiable line in file--not CITI format:\n\"%s\"\n", buffer0);
353 if (data_sets_seen != (data_sets_expected = data_names))
354 SDDS_Bomb(
"fewer data sets than expected were actually present");
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++)
361 if (!
SDDS_WriteLayout(&SDDS_table) || !SDDS_StartTable(&SDDS_table, points))
363 if (!
SDDS_SetColumn(&SDDS_table, SDDS_SET_BY_NAME, (
void *)var_list, points, indep_var))
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]);
372 if (!SDDS_WriteTable(&SDDS_table) || !
SDDS_Terminate(&SDDS_table))
378char *process_column_definition(
char **argv,
long argc) {
379 char buffer[SDDS_MAXLINE], *ptr;
384 sprintf(buffer,
"&column name=%s, ", argv[0]);
385 for (i = 1; i < argc; i++) {
386 if (!strchr(argv[i],
'='))
388 strcat(buffer, argv[i]);
389 strcat(buffer,
", ");
391 if (!strstr(buffer,
"type="))
392 strcat(buffer,
"type=character ");
393 strcat(buffer,
"&end");
398long read_CITI_var_list(FILE *fpi,
double *var_list,
long points) {
400 char buffer[BUFSIZE];
403 while (fgets(buffer, BUFSIZE, fpi) && i < points) {
404 buffer[strlen(buffer) - 1] = 0;
405 if (strcmp(buffer,
"VAR_LIST_END") == 0)
416long read_CITI_data(FILE *fpi,
double *real_data,
double *imag_data,
long points) {
418 char buffer[BUFSIZE];
421 while (fgets(buffer, BUFSIZE, fpi) && i < points) {
422 buffer[strlen(buffer) - 1] = 0;
423 if (strcmp(buffer,
"END") == 0)
434long read_CITI_seg_list(FILE *fpi,
double *seg_list,
long points) {
435 char buffer[BUFSIZE];
437 double start, end, delta;
443 delta = (end - start) / (points - 1);
445 if (!fgets(buffer, BUFSIZE, fpi))
447 buffer[strlen(buffer) - 1] = 0;
448 if (strcmp(buffer,
"SEG_LIST_END") != 0)
451 for (i = 0; i < points; i++)
452 seg_list[i] = start + i * delta;
456void alter_data_name(
char *name) {
458 if ((ptr = strchr(name,
'[')))
460 if ((ptr = strchr(name,
']')))
462 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.
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.