151 {
152 FILE *fpi;
153 char *input, *output, *schFile;
155 SCANNED_ARG *scanned;
156 long i, iArg;
157 int64_t rows, maxRows;
158 long asciiOutput, columns, spanLines, skipLines = 0, lines;
159 short columnlabels = 0, unitlabels = 0, uselabels = 0;
161 char separator, startDelim, endDelim;
162 char s[10240], *ptr, *typeName, *unitsName;
163 unsigned long dummyFlags, pipeFlags, majorOrderFlag, fillInFlag;
164 short columnMajorOrder = 0, fillInZero = 1;
165
167 argc =
scanargs(&scanned, argc, argv);
168 if (argc < 3) {
170 }
171 input = output = schFile = NULL;
172 asciiOutput = spanLines = columns = 0;
173 pipeFlags = 0;
174 columnData = NULL;
175 separator = ',';
176 startDelim = '\"';
177 endDelim = '\"';
178 maxRows = 10000;
179
180 for (iArg = 1; iArg < argc; iArg++) {
181 if (scanned[iArg].arg_type == OPTION) {
182 switch (
match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
183 case SET_MAJOR_ORDER:
184 majorOrderFlag = 0;
185 scanned[iArg].n_items--;
186 if (scanned[iArg].n_items > 0 &&
187 (!
scanItemList(&majorOrderFlag, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
188 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
189 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
190 SDDS_Bomb(
"invalid -majorOrder syntax/values");
191 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
192 columnMajorOrder = 1;
193 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
194 columnMajorOrder = 0;
195 break;
196 case SET_ASCIIOUTPUT:
197 asciiOutput = 1;
198 break;
199 case SET_FILL_IN:
200 fillInFlag = 0;
201 scanned[iArg].n_items--;
202 if (scanned[iArg].n_items > 0 &&
203 (!
scanItemList(&fillInFlag, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
204 "zero", -1, NULL, 0, 0x0001UL,
205 "last", -1, NULL, 0, 0x0002UL, NULL)))
206 SDDS_Bomb(
"invalid -fillIn syntax/values");
207 if (fillInFlag & 0x0001UL)
208 fillInZero = 1;
209 else if (fillInFlag & 0x0002UL)
210 fillInZero = 0;
211 break;
212 case SET_DELIMITERS:
213 if (!(scanned[iArg].n_items -= 1) ||
214 !
scanItemList(&dummyFlags, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
218 }
219 scanned[iArg].n_items++;
220 break;
221 case SET_SEPARATOR:
222 if (scanned[iArg].n_items != 2 || strlen(scanned[iArg].list[1]) < 1)
225 separator = scanned[iArg].list[1][0];
226 break;
227 case SET_COLUMNDATA:
228 columnData =
SDDS_Realloc(columnData,
sizeof(*columnData) * (columns + 1));
229 columnData[columns].name = NULL;
230 columnData[columns].units = NULL;
231 unitsName = NULL;
232 typeName = "string";
233 if (!(scanned[iArg].n_items -= 1) ||
234 !
scanItemList(&dummyFlags, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
235 "name",
SDDS_STRING, &(columnData[columns].name), 1, 0,
238 !columnData[columns].name ||
239 !strlen(columnData[columns].name) ||
240 !typeName ||
243 scanned[iArg].n_items++;
244 columnData[columns].units = unitsName;
245 columns++;
246 break;
247 case SET_SCHFILE:
248 if (scanned[iArg].n_items != 2)
250 schFile = scanned[iArg].list[1];
252 fprintf(stderr, "File not found: %s (csv2sdds)\n", schFile);
253 exit(EXIT_FAILURE);
254 }
255 break;
256 case SET_PIPE:
257 if (!
processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags))
259 break;
260 case SET_SPANLINES:
261 spanLines = 1;
262 break;
263 case SET_MAXROWS:
264 if (scanned[iArg].n_items != 2 ||
265 strlen(scanned[iArg].list[1]) < 1 ||
266 sscanf(scanned[iArg].list[1], "%" SCNd64, &maxRows) != 1 ||
267 maxRows < 1)
269 break;
270 case SET_SKIPLINES:
271 if (scanned[iArg].n_items != 2 ||
272 strlen(scanned[iArg].list[1]) < 1 ||
273 sscanf(scanned[iArg].list[1], "%ld", &skipLines) != 1 ||
274 skipLines < 1)
276 break;
277 case SET_USELABELS:
278 if (scanned[iArg].n_items > 2)
280 uselabels = 1;
281 columnlabels = 1;
282 if (scanned[iArg].n_items == 2)
283 unitlabels = 1;
284 break;
285 default:
286 bomb(
"Invalid option encountered.", USAGE);
287 break;
288 }
289 } else {
290 if (!input)
291 input = scanned[iArg].list[0];
292 else if (!output)
293 output = scanned[iArg].list[0];
294 else {
295 bomb(
"Too many filenames provided.", USAGE);
296 }
297 }
298 }
299
300 if (!columns && !schFile && !columnlabels)
301 SDDS_Bomb(
"Specify at least one of -columnData, -schFile, or -uselabels options.");
302 if (columns && schFile)
303 SDDS_Bomb(
"Specify either -columnData options or -schFile option, not both.");
304 if (columns && columnlabels)
305 SDDS_Bomb(
"Specify either -columnData options or -uselabels option, not both.");
306 if (schFile && columnlabels)
307 SDDS_Bomb(
"Specify either -schFile option or -uselabels option, not both.");
308
310 if (input) {
313 if (!(fpi = fopen(input, "r")))
314 SDDS_Bomb(
"Problem opening input file.");
315 } else {
316 fpi = stdin;
317 }
318
319 if (!columnlabels) {
320 if (!columns && !(columns = ParseSchFile(schFile, &columnData, &separator, &startDelim, &endDelim)))
321 SDDS_Bomb(
"Problem reading or parsing SCH file.");
322
323 SetUpOutputFile(&SDDSout, input, output, columnData, columns, asciiOutput, columnMajorOrder);
324
327 }
328 rows = 0;
329 lines = 0;
330
331 while (fgets(s, sizeof(s), fpi)) {
332 lines++;
333
334 while ((i = strlen(s)) && s[i - 1] < 27)
335 s[i - 1] = 0;
336
337 if (strlen(s) == 0 && (skipLines && (lines > skipLines)))
338 break;
339 ptr = s;
340#if defined(DEBUG)
341 fprintf(stderr, "line: >%s<\n", ptr);
342#endif
343 if (columnlabels && (!skipLines || (lines > skipLines))) {
344 char t[10240];
345 t[0] = 0;
346 while (1) {
347 ptr = getToken(ptr, separator, startDelim, endDelim, t);
348 if (strlen(t) == 0)
349 break;
350 columnData =
SDDS_Realloc(columnData,
sizeof(*columnData) * (columns + 1));
351 columnData[columns].name = malloc(strlen(t) + 1);
353 sprintf(columnData[columns].name, "%s", t);
354 columnData[columns].units = NULL;
356 columns++;
357 }
358 columnlabels = 0;
359 continue;
360 } else if (unitlabels && (!skipLines || (lines > skipLines))) {
361 char t[10240];
362 t[0] = 0;
363 for (i = 0; i < columns; i++) {
364 ptr = getToken(ptr, separator, startDelim, endDelim, t);
365 if (strlen(t) == 0)
366 break;
367 columnData[i].units = malloc(strlen(t) + 1);
368 sprintf(columnData[i].units, "%s", t);
369 }
370 unitlabels = 0;
371 continue;
372 }
373 if (uselabels) {
374 char *tmpPtr;
375 char t[10240];
376 double tD;
377 t[0] = 0;
378 tmpPtr = ptr;
379 for (i = 0; i < columns; i++) {
380 tmpPtr = getToken(tmpPtr, separator, startDelim, endDelim, t);
381 if (strlen(t) == 0)
382 break;
383 if (sscanf(t, "%lf", &tD) == 1)
385 }
386 SetUpOutputFile(&SDDSout, input, output, columnData, columns, asciiOutput, columnMajorOrder);
389 uselabels = 0;
390 }
391 if (!skipLines || (lines > skipLines)) {
392 writeOneRowToOutputFile(&SDDSout, ptr, separator, startDelim, endDelim, spanLines, columnData, columns, rows, fillInZero);
393 rows++;
394 }
395 if (rows >= maxRows - 1) {
398 }
399 maxRows += 1000;
400 }
401 }
402
403 fclose(fpi);
406
408
409 return EXIT_SUCCESS;
410}
int32_t SDDS_LengthenTable(SDDS_DATASET *SDDS_dataset, int64_t n_additional_rows)
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
int32_t SDDS_IdentifyType(char *typeName)
Identifies the SDDS data type based on its string name.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
#define SDDS_STRING
Identifier for the string data type.
#define SDDS_CHARACTER
Identifier for the character data type.
#define SDDS_DOUBLE
Identifier for the double data type.
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
long fexists(const char *filename)
Checks if a file exists.
void interpret_escapes(char *s)
Interpret C escape sequences in a string.
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.
char * replace_chars(char *s, char *from, char *to)
Maps one set of characters to another in a given string.
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
long processPipeOption(char **item, long items, unsigned long *flags)
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
void free_scanargs(SCANNED_ARG **scanned, int argc)
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.