263 {
265 long i, i_arg, pageNumber, width;
266 SCANNED_ARG *s_arg;
267 char *input, *output, **name, *format, *title, *label, *editLabel, *schFile;
271 long printColumns, printParameters, printArrays, firstPage, bufferLines;
272 long fromPage, toPage, names, pageAdvance, noTitle, noLabels, noWarnings;
273 int32_t blankLines;
274 unsigned long latexFormat, htmlFormat;
275 FILE *fpOut;
276 unsigned long flags, pipeFlags, spreadsheetFlags, dummyFlags, postPageLines, CSV = 0;
277 char *spreadsheetDelimiter, *spreadsheetQuoteMark;
279 char **formatDefaultArg;
280 long formatDefaultArgs;
281 static char formatbuffer[100], formatbuffer2[100];
282 char *latexLabel, *latexCaption = NULL, *latexGroup, *latexTranslationFile, *latexComment = NULL;
283 char *latexCaptionBuffer = NULL, *latexLabelBuffer = NULL;
284 htab *TranslationTable;
285 char *htmlCaption = NULL, *htmlTranslationFile;
286 double factor;
287
289 argc =
scanargs(&s_arg, argc, argv);
290 if (argc < 3)
292
293 input = output = NULL;
294 fromPage = toPage = 0;
295 printColumn = NULL;
296 printParameter = NULL;
297 printArray = NULL;
298 width = 130;
299 setDefaultFormats();
300 printColumns = printParameters = printArrays = pipeFlags = flags = 0;
301 postPageLines = pageAdvance = noTitle = noLabels = 0;
302 title = NULL;
303 spreadsheetFlags = 0;
304 pagination.flags = pagination.currentLine = 0;
305 noWarnings = 0;
306 formatDefaultArgs = 0;
307 schFile = NULL;
308 formatDefaultArg = NULL;
309 bufferLines = 0;
310 latexFormat = 0;
311 TranslationTable = NULL;
312 htmlFormat = 0;
313
314 for (i_arg = 1; i_arg < argc; i_arg++) {
315 if (s_arg[i_arg].arg_type == OPTION) {
316 switch (
match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
317 case SET_COLUMNS:
318 if (s_arg[i_arg].n_items < 2) {
319 s_arg[i_arg].n_items = 2;
320 s_arg[i_arg].list =
SDDS_Realloc(s_arg[i_arg].list,
sizeof(*s_arg[i_arg].list) * 2);
322 }
323 name = makeListOfNames(s_arg[i_arg].list[1], &names);
324 printColumn =
SDDS_Realloc(printColumn,
sizeof(*printColumn) * (names + printColumns));
325 s_arg[i_arg].n_items -= 2;
326 format = NULL;
327 blankLines = 0;
328 factor = 1;
329 if (!
scanItemList(&flags, s_arg[i_arg].list + 2, &s_arg[i_arg].n_items, 0,
331 "endsline", -1, NULL, 0, ENDSLINE,
332 "usedefaultformat", -1, NULL, 0, USEDEFAULTFORMAT,
333 "blanklines",
SDDS_LONG, &blankLines, 1, 0,
334 "editlabel",
SDDS_STRING, &editLabel, 1, EDITLABEL_GIVEN,
336 "nounits", -1, NULL, 0, NO_UNITS,
337 "factor",
SDDS_DOUBLE, &factor, 1, FACTOR_GIVEN, NULL))
339 for (i = 0; i < names; i++) {
341 printColumn[i + printColumns].name = name[i];
342 if (format) {
344 replaceString(formatbuffer2, formatbuffer,
"lu", PRIu32, -1, 0);
346 }
347 if (flags & ENDSLINE && (i == names - 1))
348 printColumn[i + printColumns].endsLine = 1;
349 if (flags & USEDEFAULTFORMAT)
350 printColumn[i + printColumns].useDefaultFormat = 1;
351 printColumn[i + printColumns].label = printColumn[i + printColumns].editLabel = NULL;
352 if (flags & LABEL_GIVEN)
353 printColumn[i + printColumns].label = label;
354 if (flags & EDITLABEL_GIVEN)
355 printColumn[i + printColumns].editLabel = editLabel;
356 printColumn[i + printColumns].noUnits = flags & NO_UNITS ? 1 : 0;
357 printColumn[i + printColumns].factor = factor;
358 printColumn[i + printColumns].blankLines = blankLines;
359 }
360 free(name);
361 printColumns += names;
362 break;
363 case SET_PARAMETERS:
364 if (s_arg[i_arg].n_items < 2) {
365 s_arg[i_arg].n_items = 2;
366 s_arg[i_arg].list =
SDDS_Realloc(s_arg[i_arg].list,
sizeof(*s_arg[i_arg].list) * 2);
368 }
369 name = makeListOfNames(s_arg[i_arg].list[1], &names);
370 printParameter =
SDDS_Realloc(printParameter,
sizeof(*printParameter) * (names + printParameters));
371 s_arg[i_arg].n_items -= 2;
372 format = NULL;
373 blankLines = 0;
374 factor = 1;
375 if (!
scanItemList(&flags, s_arg[i_arg].list + 2, &s_arg[i_arg].n_items, 0,
377 "endsline", -1, NULL, 0, ENDSLINE,
378 "usedefaultformat", -1, NULL, 0, USEDEFAULTFORMAT,
379 "blanklines",
SDDS_LONG, &blankLines, 1, 0,
380 "editlabel",
SDDS_STRING, &editLabel, 1, EDITLABEL_GIVEN,
382 "factor",
SDDS_DOUBLE, &factor, 1, FACTOR_GIVEN, NULL))
384 for (i = 0; i < names; i++) {
385 SDDS_ZeroMemory(printParameter + i + printParameters,
sizeof(*printParameter));
386 printParameter[i + printParameters].name = name[i];
387 if (format) {
389 replaceString(formatbuffer2, formatbuffer,
"lu", PRIu32, -1, 0);
390 SDDS_CopyString(&printParameter[i + printParameters].format, formatbuffer2);
391 }
392 if (flags & ENDSLINE && (i == names - 1))
393 printParameter[i + printParameters].endsLine = 1;
394 if (flags & USEDEFAULTFORMAT)
395 printParameter[i + printParameters].useDefaultFormat = 1;
396 printParameter[i + printParameters].label = printParameter[i + printParameters].editLabel = NULL;
397 if (flags & LABEL_GIVEN)
398 printParameter[i + printParameters].label = label;
399 if (flags & EDITLABEL_GIVEN)
400 printParameter[i + printParameters].editLabel = editLabel;
401 printParameter[i + printParameters].factor = factor;
402 printParameter[i + printParameters].blankLines = blankLines;
403 }
404 free(name);
405 printParameters += names;
406 break;
407 case SET_ARRAYS:
408 if (s_arg[i_arg].n_items < 2) {
409 s_arg[i_arg].n_items = 2;
410 s_arg[i_arg].list =
SDDS_Realloc(s_arg[i_arg].list,
sizeof(*s_arg[i_arg].list) * 2);
412 }
413 name = makeListOfNames(s_arg[i_arg].list[1], &names);
414 printArray =
SDDS_Realloc(printArray,
sizeof(*printArray) * (names + printArrays));
415 s_arg[i_arg].n_items -= 2;
416 format = NULL;
417 if (!
scanItemList(&flags, s_arg[i_arg].list + 2, &s_arg[i_arg].n_items, 0,
420 for (i = 0; i < names; i++) {
421 printArray[i + printArrays].name = name[i];
422 if (format) {
424 replaceString(formatbuffer2, formatbuffer,
"lu", PRIu32, -1, 0);
426 }
427 }
428 free(name);
429 printArrays += names;
430 break;
431 case SET_FROMPAGE:
432 if (s_arg[i_arg].n_items < 2)
434 if (fromPage != 0)
435 SDDS_Bomb(
"invalid syntax: specify -fromPage once only");
436 if (sscanf(s_arg[i_arg].list[1], "%ld", &fromPage) != 1 || fromPage <= 0)
437 SDDS_Bomb(
"invalid -fromPage syntax or value");
438 break;
439 case SET_TOPAGE:
440 if (s_arg[i_arg].n_items < 2)
442 if (toPage != 0)
443 SDDS_Bomb(
"invalid syntax: specify -toPage once only");
444 if (sscanf(s_arg[i_arg].list[1], "%ld", &toPage) != 1 || toPage <= 0)
445 SDDS_Bomb(
"invalid -toPage syntax or value");
446 break;
447 case SET_FORMATDEFAULTS:
448 formatDefaultArg = s_arg[i_arg].list + 1;
449 formatDefaultArgs = s_arg[i_arg].n_items - 1;
450 break;
451 case SET_WIDTH:
452 if (s_arg[i_arg].n_items != 2 || sscanf(s_arg[i_arg].list[1], "%ld", &width) != 1 || (width < 40 && width))
453 SDDS_Bomb(
"invalid -width syntax or value");
454 break;
455 case SET_PIPE:
456 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
458 break;
459 case SET_PAGEADVANCE:
460 pageAdvance = 1;
461 break;
462 case SET_NOTITLE:
463 noTitle = 1;
464 break;
465 case SET_TITLE:
466 if (s_arg[i_arg].n_items != 2)
468 title = s_arg[i_arg].list[1];
469 break;
470 case SET_SPREADSHEET:
471 s_arg[i_arg].n_items--;
472 spreadsheetDelimiter = NULL;
473 spreadsheetQuoteMark = "";
474 if (!
scanItemList(&spreadsheetFlags, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
475 "delimiter",
SDDS_STRING, &spreadsheetDelimiter, 1, SPREADSHEET_DELIMITER,
476 "quotemark",
SDDS_STRING, &spreadsheetQuoteMark, 1, SPREADSHEET_QUOTEMARK,
477 "nolabels", -1, NULL, 0, SPREADSHEET_NOLABELS, "csv", -1, NULL, 0, SPREADSHEET_CSV,
479 SDDS_Bomb(
"invalid -spreadsheet syntax");
480 if (!spreadsheetDelimiter || !(spreadsheetFlags & SPREADSHEET_DELIMITER))
481 spreadsheetDelimiter = "\t";
482 if (spreadsheetFlags & SPREADSHEET_CSV) {
483 spreadsheetDelimiter = ",";
484 spreadsheetFlags |= SPREADSHEET_DELIMITER;
485 spreadsheetFlags |= SPREADSHEET_QUOTEMARK;
486 spreadsheetQuoteMark = "\"";
487 noTitle = 1;
488 CSV = 1;
489 }
490 spreadsheetFlags |= SPREADSHEET_ON;
491 width = 0;
492 break;
493 case SET_PAGINATE:
494 s_arg[i_arg].n_items--;
495 pagination.lines = 66;
496 if (!
scanItemList(&dummyFlags, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
497 "lines",
SDDS_LONG, &pagination.lines, 1, 0,
498 "notitle", -1, NULL, 0, PAGINATION_NOTITLE,
499 "nolabels", -1, NULL, 0, PAGINATION_NOLABELS, NULL) ||
500 pagination.lines <= 3)
501 SDDS_Bomb(
"invalid -paginate syntax/values");
502 pagination.flags |= PAGINATION_ON;
503 break;
504 case SET_NOWARNINGS:
505 noWarnings = 1;
506 break;
507 case SET_POSTPAGELINES:
508 if (s_arg[i_arg].n_items != 2 || sscanf(s_arg[i_arg].list[1], "%ld", &postPageLines) != 1)
509 SDDS_Bomb(
"invalid -postPageLines syntax/values");
510 break;
511 case SET_NOLABELS:
512 noLabels = 1;
513 break;
514 case SET_BUFFERLINES:
515 if (s_arg[i_arg].n_items < 2)
516 SDDS_Bomb(
"invalid -bufferLines syntax");
517 if (sscanf(s_arg[i_arg].list[1], "%ld", &bufferLines) != 1 || bufferLines < 0)
518 SDDS_Bomb(
"invalid -bufferLines syntax or value");
519 break;
520 case SET_LATEXFORMAT:
521 s_arg[i_arg].n_items--;
522 latexLabel = NULL;
523 latexCaption = NULL;
524 latexComment = NULL;
525 if (!
scanItemList(&latexFormat, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
526 "longtable", -1, NULL, 0, LATEX_LONGTABLE,
527 "booktable", -1, NULL, 0, LATEX_BOOKTABLE,
528 "sideways", -1, NULL, 0, LATEX_SIDEWAYS,
530 "caption",
SDDS_STRING, &latexCaption, 1, LATEX_CAPTION,
531 "comment",
SDDS_STRING, &latexComment, 1, LATEX_COMMENT,
533 "translate",
SDDS_STRING, &latexTranslationFile, 1, LATEX_TRANSLATE,
534 "justify",
SDDS_STRING, &latexJustify, 1, LATEX_JUSTIFY,
535 "complete", -1, NULL, 0, LATEX_COMPLETE, NULL))
536 SDDS_Bomb(
"invalid -latexFormat syntax/values");
537 latexFormat |= LATEX_FORMAT;
538 if (latexFormat & LATEX_LONGTABLE && latexFormat & LATEX_SIDEWAYS)
539 SDDS_Bomb(
"invalid -latexFormat syntax/values: give only one of longtable and sideways");
540 break;
541 case SET_HTMLFORMAT:
542 s_arg[i_arg].n_items--;
543 htmlCaption = NULL;
544 if (!
scanItemList(&htmlFormat, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
545 "caption",
SDDS_STRING, &htmlCaption, 1, HTML_CAPTION,
546 "translate",
SDDS_STRING, &htmlTranslationFile, 1, HTML_TRANSLATE, NULL))
547 SDDS_Bomb(
"invalid -htmlFormat syntax/values");
548 htmlFormat |= HTML_FORMAT;
549 break;
550 default:
551 fprintf(stderr, "error: unknown switch: %s\n", s_arg[i_arg].list[0]);
553 break;
554 }
555 } else {
556 if (!input)
557 input = s_arg[i_arg].list[0];
558 else if (!output)
559 output = s_arg[i_arg].list[0];
560 else
562 }
563 }
564
565 pipeFlags |= DEFAULT_STDOUT;
566 processFilenames(
"sddsprintout", &input, &output, pipeFlags, noWarnings, NULL);
567
568 if (formatDefaultArgs)
569 changeDefaultFormats(formatDefaultArg, formatDefaultArgs, noWarnings);
570
571 if (pageAdvance) {
572 if (postPageLines)
573 SDDS_Bomb(
"-pageAdvance and -postPageLines are incompatible");
574 if (pagination.flags & PAGINATION_ON)
575 SDDS_Bomb(
"-pageAdvance and -paginate are incompatible");
576 }
577 if (pagination.flags & PAGINATION_ON && postPageLines)
578 SDDS_Bomb(
"-postPageLines and -paginate are incompatible");
579
580 if (!printColumns && !printParameters && !printArrays)
581 SDDS_Bomb(
"you must specify at least one of -columns, -parameters, or -arrays");
582 if (fromPage && toPage && fromPage > toPage)
583 SDDS_Bomb(
"invalid -fromPage and -toPage");
584 if (latexFormat && htmlFormat)
585 SDDS_Bomb(
"-latexFormat and -htmlFormat are incompatible");
586
587 if (latexFormat & LATEX_TRANSLATE)
588 TranslationTable = readTranslationTable(latexTranslationFile);
589 if (htmlFormat & HTML_TRANSLATE)
590 TranslationTable = readTranslationTable(htmlTranslationFile);
591
594 exit(EXIT_FAILURE);
595 }
596
597 fpOut = stdout;
598 if (output && !(fpOut = fopen(output, "w")))
600
601 printColumns = processPrintColumns(&printColumn, printColumns, &SDDS_dataset, noWarnings,
602 spreadsheetFlags, CSV, latexFormat, TranslationTable, htmlFormat);
603 printParameters = processPrintParameters(&printParameter, printParameters, &SDDS_dataset, noWarnings, noLabels, CSV);
604
605
607
608 firstPage = 1;
609 pagination.flags |= noTitle ? PAGINATION_NOTITLE : 0;
610 if (!title) {
611 title =
tmalloc(
sizeof(*title) * ((input ? strlen(input) : 10) + 100));
612 if (htmlFormat)
613 sprintf(title, "Printout for SDDS file %s", input ? input : "stdin");
614 else
615 sprintf(title, "Printout for SDDS file %s%s", input ? input : "stdin", latexFormat ? "" : "\n");
616 }
617
618 if (schFile) {
619 if (printArrays || printParameters || !printColumns)
620 SDDS_Bomb(
"Can't create schFile except for pure column printout.");
621 CreateSCHFile(schFile, input, spreadsheetFlags, spreadsheetDelimiter, spreadsheetQuoteMark, printColumn, printColumns);
622 }
623 if (latexFormat) {
624 noTitle = 1;
625 if (latexFormat & LATEX_LABEL && latexLabel[0] == '@') {
626 memmove(latexLabel, latexLabel + 1, strlen(latexLabel));
628 fprintf(stderr, "sddsprintout: error: parameter %s not found in input file\n", latexLabel);
629 exit(EXIT_FAILURE);
630 }
631 latexFormat |= LATEX_LABEL_PARAM;
632 }
633 if (latexFormat & LATEX_CAPTION && latexCaption[0] == '@') {
634 memmove(latexCaption, latexCaption + 1, strlen(latexCaption));
636 fprintf(stderr, "sddsprintout: error: parameter %s not found in input file\n", latexCaption);
637 exit(EXIT_FAILURE);
638 }
639 latexFormat |= LATEX_CAPTION_PARAM;
640 }
641 if (latexFormat & LATEX_COMPLETE) {
642 fprintf(fpOut, "\\documentclass{report}\n\\pagestyle{empty}\n");
643 if (latexFormat & LATEX_BOOKTABLE)
644 fprintf(fpOut, "\\usepackage{booktabs}\n");
645 if (latexFormat & LATEX_SIDEWAYS)
646 fprintf(fpOut, "\\usepackage{rotating}\n");
647 fprintf(fpOut, "\\begin{document}\n");
648 }
649 if (latexComment)
650 fprintf(fpOut, "%% %s\n", latexComment);
651 }
652 if (htmlFormat) {
653 noTitle = 1;
654 }
655
656 while ((pageNumber =
SDDS_ReadPageSparse(&SDDS_dataset, 0, (printColumns || SDDS_dataset.layout.data_mode.column_major) ? 1 : 1000000, 0, 0)) > 0) {
657 if ((fromPage && pageNumber < fromPage) || (toPage && pageNumber > toPage))
658 continue;
659 if (pagination.flags & PAGINATION_ON) {
660 if (!firstPage) {
661 fputc('\014', fpOut);
662 pagination.currentLine = 1;
663 }
664 if (!noTitle)
665 pagination.currentLine += printPageTitle(fpOut, title);
666 } else {
667 if (firstPage) {
668 if (!noTitle)
669 printPageTitle(fpOut, title);
670 } else if (pageAdvance)
671 fputc('\014', fpOut);
672 else if (postPageLines > 0) {
673 long line = postPageLines;
674 while (line--)
675 fputc('\n', fpOut);
676 }
677 }
678 if (!latexFormat && !htmlFormat)
679 doPrintParameters(&SDDS_dataset, printParameter, printParameters, width, fpOut, spreadsheetFlags,
680 spreadsheetDelimiter, spreadsheetQuoteMark, &pagination, title, noLabels);
681
682 latexCaptionBuffer = latexLabelBuffer = NULL;
683 if (latexFormat & LATEX_CAPTION_PARAM && !(latexCaptionBuffer =
SDDS_GetParameterAsString(&SDDS_dataset, latexCaption, NULL))) {
684 char buffer[1024];
685 snprintf(buffer, 1024, "Error: can't read latex caption parameter %s\n", latexCaption);
687 }
688 if (latexFormat & LATEX_LABEL_PARAM && !(latexLabelBuffer =
SDDS_GetParameterAsString(&SDDS_dataset, latexLabel, NULL))) {
689 char buffer[1024];
690 snprintf(buffer, 1024, "Error: can't read latex label parameter %s\n", latexLabel);
692 }
693 doPrintColumns(&SDDS_dataset, printColumn, printColumns, width, fpOut, spreadsheetFlags, spreadsheetDelimiter,
694 spreadsheetQuoteMark, latexFormat,
695 latexFormat & LATEX_CAPTION_PARAM ? latexCaptionBuffer : latexCaption,
696 latexFormat & LATEX_LABEL_PARAM ? latexLabelBuffer : latexLabel,
697 latexGroup, htmlFormat, htmlCaption,
698 &pagination, title, noLabels);
699 if (latexFormat & LATEX_CAPTION_PARAM && latexCaptionBuffer)
700 free(latexCaptionBuffer);
701 if (latexFormat & LATEX_LABEL_PARAM && latexLabelBuffer)
702 free(latexLabelBuffer);
703 if (bufferLines) {
704 for (i = 0; i < bufferLines; i++)
705 fputc('\n', fpOut);
706 }
707 firstPage = 0;
708 }
709
712 for (i = 0; i < printColumns; i++) {
713 if (printColumn[i].headers) {
714 for (long j = 0; j < printColumn[i].headers; j++) {
715 free(printColumn[i].header[j]);
716 }
717 free(printColumn[i].header);
718 }
719 }
720 if (latexFormat & LATEX_COMPLETE)
721 fprintf(fpOut, "\\end{document}\n");
722
723 free(printColumn);
725 return EXIT_SUCCESS;
726}
int32_t SDDS_ZeroMemory(void *mem, int64_t n_bytes)
Sets a block of memory to zero.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
int32_t SDDS_CheckParameter(SDDS_DATASET *SDDS_dataset, char *name, char *units, int32_t type, FILE *fp_message)
Checks if a parameter exists in the SDDS dataset with the specified name, units, and type.
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
#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 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 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.