SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
TFS2sdds.c
Go to the documentation of this file.
1/**
2 * @file TFS2sdds.c
3 * @brief Converts MAD (Methodical Accelerator Design) TFS (Twiss File Standard) data files to SDDS format.
4 *
5 * @details
6 * This program reads LEP TFS (Twiss File Standard) format files (used by MAD) and converts them to
7 * the SDDS (Self Describing Data Sets) format. It supports piping input and output
8 * through standard input and output streams. The program processes header and data
9 * lines in the input file to generate corresponding SDDS parameters, columns, and data.
10 *
11 * @section Usage
12 * ```
13 * TFS2sdds [<inputfile>] [<outputfile>]
14 * [-pipe[=input][,output]]
15 * ```
16 *
17 * @section Options
18 * | Optional | Description |
19 * |---------------------------------------|---------------------------------------------------------------------------------------|
20 * | `-pipe` | Enables piping mode. Allows input and/or output through streams. |
21 *
22 * @copyright
23 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
24 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
25 *
26 * @license
27 * This file is distributed under the terms of the Software License Agreement
28 * found in the file LICENSE included with this distribution.
29 *
30 * @author
31 * M. Borland, C. Saunders, R. Soliday
32 */
33
34#include "mdb.h"
35#include "scan.h"
36#include "SDDS.h"
37#include "match_string.h"
38
39/* Enumeration for option types */
40enum option_type {
41 SET_PIPE,
42 N_OPTIONS
43};
44
45static char *option[N_OPTIONS] = {
46 "pipe",
47};
48
49static const char *USAGE =
50 "Usage: TFS2sdds [<inputfile> <outputfile>] [-pipe[=input][,output]]\n"
51 "\n"
52 "Converts LEP TFS format files (used by MAD) to SDDS.\n"
53 "\n"
54 "Program by Michael Borland. (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ").";
55
56#define SHORT_TYPE 0
57#define LONG_TYPE 1
58#define DOUBLE_TYPE 2
59#define FLOAT_TYPE 3
60#define STRING_TYPE 4
61#define TYPENAMES 5
62
63static char *typeName[TYPENAMES] = {
64 "short",
65 "long",
66 "double",
67 "float",
68 "string",
69};
70
71#define SDDS_MAXLINE 1024
72
73long identifyType(char *format);
74
75int main(int argc, char **argv) {
76 SCANNED_ARG *scanned;
77 long i_arg, type, inHeader = 1;
78 char *input, *output;
79 unsigned long pipeFlags;
80 FILE *fpi, *fpo;
81 char s1[SDDS_MAXLINE], s2[SDDS_MAXLINE];
82 char *name, *format, *value;
83
85 argc = scanargs(&scanned, argc, argv);
86 if (argc < 3) {
87 fprintf(stderr, "%s\n", USAGE);
88 exit(EXIT_FAILURE);
89 }
90
91 input = output = format = value = NULL;
92 pipeFlags = 0;
93 for (i_arg = 1; i_arg < argc; i_arg++) {
94 if (scanned[i_arg].arg_type == OPTION) {
95 switch (match_string(scanned[i_arg].list[0], option, N_OPTIONS, 0)) {
96 case SET_PIPE:
97 if (!processPipeOption(scanned[i_arg].list + 1, scanned[i_arg].n_items - 1, &pipeFlags)) {
98 fprintf(stderr, "Error: Invalid -pipe syntax.\n");
99 exit(EXIT_FAILURE);
100 }
101 break;
102 default:
103 fprintf(stderr, "Error: Unknown option '%s'.\n", scanned[i_arg].list[0]);
104 exit(EXIT_FAILURE);
105 break;
106 }
107 } else {
108 if (!input) {
109 input = scanned[i_arg].list[0];
110 } else if (!output) {
111 output = scanned[i_arg].list[0];
112 } else {
113 fprintf(stderr, "Error: Too many filenames provided.\n");
114 exit(EXIT_FAILURE);
115 }
116 }
117 }
118
119 processFilenames("TFS2sdds", &input, &output, pipeFlags, 0, NULL);
120
121 if (!input)
122 fpi = stdin;
123 else if (!(fpi = fopen(input, "r"))) {
124 fprintf(stderr, "Error: Unable to open input file '%s'.\n", input);
125 exit(EXIT_FAILURE);
126 }
127
128 if (!output)
129 fpo = stdout;
130 else if (!(fpo = fopen(output, "w"))) {
131 fprintf(stderr, "Error: Unable to open output file '%s'.\n", output);
132 exit(EXIT_FAILURE);
133 }
134
135 fprintf(fpo, "SDDS1\n");
136 if (!fgets(s1, SDDS_MAXLINE, fpi)) {
137 SDDS_Bomb("Input file ends prematurely");
138 }
139
140 while (s1[0] == '@') {
141 strcpy_ss(s1, s1 + 1);
142 if (!(name = get_token(s1)) || !(format = get_token(s1)) || !(value = get_token(s1))) {
143 SDDS_Bomb("Missing data for parameter");
144 }
145 if ((type = identifyType(format)) < 0) {
146 fprintf(stderr, "Error (TFS2sdds): Unknown format string: %s\n", format);
147 exit(EXIT_FAILURE);
148 }
149 fprintf(fpo, "&parameter name=%s, type=%s, fixed_value=\"%s\" &end\n", name, typeName[type], value);
150
151 if (!fgets(s1, SDDS_MAXLINE, fpi)) {
152 SDDS_Bomb("Input file ends prematurely");
153 }
154 inHeader = 0;
155 }
156
157 if (!fgets(s2, SDDS_MAXLINE, fpi)) {
158 SDDS_Bomb("Input file ends prematurely");
159 }
160
161 if (s1[0] != '*') {
162 SDDS_Bomb("Column name line not seen");
163 }
164 if (s2[0] != '$') {
165 SDDS_Bomb("Column format line not seen");
166 }
167 strcpy_ss(s1, s1 + 1);
168 strcpy_ss(s2, s2 + 1);
169 while ((name = get_token(s1))) {
170 if (!(format = get_token(s2))) {
171 SDDS_Bomb("Missing format for column");
172 }
173 fprintf(fpo, "&column name=%s, type=", name);
174 if ((type = identifyType(format)) < 0) {
175 fprintf(stderr, "Error (TFS2sdds): Unknown format string: %s\n", format);
176 exit(EXIT_FAILURE);
177 }
178 fprintf(fpo, "%s &end\n", typeName[type]);
179 }
180
181 if (inHeader == 0) {
182 fputs("&data mode=ascii, no_row_counts=1 &end\n", fpo);
183 }
184
185 while (fgets(s1, SDDS_MAXLINE, fpi)) {
186 if (inHeader) {
187 if (s1[0] == '@') {
188 strcpy_ss(s1, s1 + 1);
189 if (!(name = get_token(s1)) || !(format = get_token(s1)) || !(value = get_token(s1))) {
190 SDDS_Bomb("Missing data for parameter");
191 }
192 if ((type = identifyType(format)) < 0) {
193 fprintf(stderr, "Error (TFS2sdds): Unknown format string: %s\n", format);
194 exit(EXIT_FAILURE);
195 }
196 fprintf(fpo, "&parameter name=%s, type=%s, fixed_value=\"%s\" &end\n", name, typeName[type], value);
197 continue;
198 }
199 inHeader = 0;
200 fputs("&data mode=ascii, no_row_counts=1 &end\n", fpo);
201 }
202 fputs(s1, fpo);
203 }
204 if (inHeader) {
205 fputs("&data mode=ascii, no_row_counts=1 &end\n\n", fpo);
206 }
207
208 return EXIT_SUCCESS;
209}
210
211long identifyType(char *format) {
212 long length;
213
214 if (!format) {
215 SDDS_Bomb("Bad format string seen");
216 }
217
218 length = strlen(format);
219 if (format[0] != '%') {
220 SDDS_Bomb("Bad format string seen");
221 }
222
223 if (length >= 2) {
224 if (strcmp(format + length - 2, "le") == 0 || strcmp(format + length - 2, "lf") == 0) {
225 return DOUBLE_TYPE;
226 }
227 if (strcmp(format + length - 2, "ld") == 0) {
228 return LONG_TYPE;
229 }
230 if (strcmp(format + length - 2, "hd") == 0) {
231 return SHORT_TYPE;
232 }
233 }
234
235 if (length >= 1) {
236 if (format[length - 1] == 'e' || format[length - 1] == 'f') {
237 return FLOAT_TYPE;
238 }
239 if (format[length - 1] == 'd') {
240 return LONG_TYPE;
241 }
242 if (format[length - 1] == 's') {
243 return STRING_TYPE;
244 }
245 }
246
247 return -1;
248}
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
char * get_token(char *s)
Extracts the next token from the input string.
Definition data_scan.c:413
long match_string(char *string, char **option, long n_options, long mode)
Matches a given string against an array of option strings based on specified modes.
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
Definition scanargs.c:36
long 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
char * strcpy_ss(char *dest, const char *src)
Safely copies a string, handling memory overlap.
Definition str_copy.c:34