Skip to content

Commit

Permalink
APREPRO: Add option to output floating point data at full precision
Browse files Browse the repository at this point in the history
Add optional support (enabled if the lib::fmt library is linked in)
for printing floating point data using the number of digits required
for full precision of the value.  The output for {1/4} would be '0.25'
The output for {1/3} would be '1.333333..' with enough '3' to fully
represent the value.  Another way of describing is that if VAL
is the internal value of an aprepro variable, then printing VAL
and then assigning the variable to VALs printed output would result
in no change.

This behavior can either be enabled using the `--full_precision` or `-p`
option, or by setting the value of the aprepro varible `_FORMAT` to the
empty string: {_FORMAT=""}

Since this capability is only enabled if the optional lib::fmt library
is linked to aprepro, a warning/informational/error message is printed
if you try to use the option when it is not supported.
  • Loading branch information
gsjaardema committed Jun 19, 2023
1 parent c583b52 commit 3a258ce
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 140 deletions.
4 changes: 4 additions & 0 deletions packages/seacas/libraries/aprepro_lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ IF (${CMAKE_PROJECT_NAME}_ENABLE_SEACASExodus)
ADD_DEFINITIONS(-DEXODUS_SUPPORT)
ENDIF()

IF (${TPL_ENABLE_fmt})
ADD_DEFINITIONS(-DFMT_SUPPORT)
ENDIF()

TRIBITS_INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_SOURCE_DIR}
)
Expand Down
14 changes: 13 additions & 1 deletion packages/seacas/libraries/aprepro_lib/apr_aprepro.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
#endif

namespace {
const std::string version_string{"6.12 (2023/05/03)"};
const std::string version_string{"6.13 (2023/06/19)"};

void output_copyright();

Expand Down Expand Up @@ -541,6 +541,12 @@ namespace SEAMS {
ptr->value.svar = comment;
}
}
else if (option.find("--full_precision") != std::string::npos || (option[1] == 'p')) {
symrec *ptr = getsym("_FORMAT");
if (ptr != nullptr) {
ptr->value.svar = "";
}
}

else if (option == "--help" || option == "-h") {
std::cerr
Expand Down Expand Up @@ -569,6 +575,12 @@ namespace SEAMS {
<< " --info=file: Output INFO messages (e.g. DUMP() output) to file.\n"
<< " --nowarning or -W: Do not print WARN messages \n"
<< " --comment=char or -c=char: Change comment character to 'char' \n"
#if defined(FMT_SUPPORT)
<< " --full_precision -p: Floating point output uses as many digits as needed.\n"
#else
<< " --full_precision -p: (Not supported in this build) Floating point output uses as "
"many digits as needed.\n"
#endif
<< " --copyright or -C: Print copyright message \n"
<< " --keep_history or -k: Keep a history of aprepro substitutions.\n"
<< " (not for general interactive use) \n"
Expand Down
21 changes: 18 additions & 3 deletions packages/seacas/libraries/aprepro_lib/apr_parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@
#include "apr_util.h"
#include "aprepro.h"

#if defined FMT_SUPPORT
#include <fmt/format.h>
#endif
#include <cerrno>
#include <cfenv>
#include <cmath>
Expand Down Expand Up @@ -529,10 +532,22 @@ namespace SEAMS {
#line 130 "/Users/gdsjaar/src/seacas/packages/seacas/libraries/aprepro_lib/aprepro.yy"
{
if (echo) {
static char tmpstr[512];
SEAMS::symrec *format = aprepro.getsym("_FORMAT");
int len = snprintf(tmpstr, 512, format->value.svar.c_str(), (yystack_[1].value.val));
aprepro.lexer->LexerOutput(tmpstr, len);
if (format->value.svar.empty()) {
#if defined FMT_SUPPORT
auto tmpstr = fmt::format("{}", (yystack_[1].value.val));
aprepro.lexer->LexerOutput(tmpstr.c_str(), tmpstr.size());
#else
yyerror(aprepro, "Empty _FORMAT string -- no output will be printed. Optional "
"Lib::FMT dependency is not enabled.");
#endif
}
else {
static char tmpstr[512];
int len =
snprintf(tmpstr, 512, format->value.svar.c_str(), (yystack_[1].value.val));
aprepro.lexer->LexerOutput(tmpstr, len);
}
}
}
#line 644 "apr_parser.cc"
Expand Down
140 changes: 4 additions & 136 deletions packages/seacas/libraries/aprepro_lib/aprepro.yy
Original file line number Diff line number Diff line change
@@ -1,138 +1,6 @@
// Copyright(C) 1999-2023 National Technology & Engineering Solutions
// of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with
// NTESS, the U.S. Government retains certain rights in this software.
//
// See packages/seacas/LICENSE for details
%{
#include "aprepro.h"
#include "apr_util.h"
#include "apr_array.h"

#include <iostream>
#include <stdlib.h>
#include <cmath>
#include <cerrno>
#include <cstring>
#include <cstdio>
#include <cfenv>

namespace {
void reset_error()
{
#if !defined(WIN32) && !defined(__WIN32__) && !defined(_WIN32) && !defined(_MSC_VER) && \
!defined(__MINGW32__) && !defined(_WIN64) && !defined(__MINGW64__)
#ifndef math_errhandling
#define math_errhandling MATH_ERRNO
#endif

if (math_errhandling & MATH_ERREXCEPT) {
std::feclearexcept(FE_ALL_EXCEPT);
}
if (math_errhandling & MATH_ERRNO) {
errno = 0;
}
#endif
}
}

namespace SEAMS {
extern bool echo;
}

%}

%require "3.2"

/* add debug output code to generated parser. disable this for release
* versions. */
%debug

/* write out a header file containing the token defines */
%defines

/* use newer C++ skeleton file */
%skeleton "lalr1.cc"

/* namespace to enclose parser in */
%define api.prefix {SEAMS}

/* set the parser's class identifier */
%define api.parser.class {Parser}

%define parse.error verbose

/* aprepro is passed by reference to the parser and to the scanner. This
* provides a simple but effective pure interface, not relying on global
* variables. */
%parse-param { class Aprepro& aprepro }

%union {
double val; /* For returning numbers. */
struct symrec *tptr; /* For returning symbol-table pointers */
char *string; /* For returning quoted strings */
struct array *arrval; /* For returning arrays */
}

%token <val> NUM /* Simple double precision number */
%token <string> QSTRING /* Quoted string */
%token <tptr> UNDVAR /* Variable and function */
%token <tptr> VAR
%token <tptr> SVAR /* String Variable */
%token <tptr> IMMVAR /* Immutable Variable */
%token <tptr> IMMSVAR /* Immutable String Variable */
%token <tptr> AVAR /* array data [i,j] */
%token <tptr> FNCT
%token <tptr> SFNCT
%token <tptr> AFNCT
%type <val> exp
%type <arrval> aexp
%type <val> bool
%type <string> sexp

%token END 0 "end of file"
%token COMMA LPAR RPAR LBRACK RBRACK LBRACE RBRACE SEMI
/* Precedence (Lowest to Highest) and associativity */
%right EQUAL
%right EQ_PLUS EQ_MINUS
%right EQ_TIME EQ_DIV
%right EQ_POW
%right QUEST COLON
%left LOR /* Logical OR */
%left LAND /* Logical AND */
%left LT GT LE GE EQ NE /* <=, >=, ==, != */
%left PLU SUB
%left DIV TIM MOD
%left UNARY NOT /* Negation--unary minus/plus */
%right POW /* Exponentiation */
%left INC DEC /* increment (++), decrement (--) */
%left CONCAT /* Concatenate Strings */

%{

#include "aprepro.h"
#include "apr_scanner.h"

/* this "connects" the bison parser in aprepro to the flex scanner class
* object. it defines the yylex() function call to pull the next token from the
* current lexer object of the aprepro context. */
#undef yylex
#define yylex aprepro.lexer->lex

%}

/* Grammar Rules: */
%%
input: /* empty rule */
| input line
;

line: '\n' { if (echo) aprepro.lexer->LexerOutput("\n", 1); }
| LBRACE exp RBRACE { if (echo) {
static char tmpstr[512];
SEAMS::symrec *format = aprepro.getsym("_FORMAT");
int len = snprintf(tmpstr, 512, format->value.svar.c_str(), $2);
aprepro.lexer->LexerOutput(tmpstr, len);
}
aprepro.lexer->LexerOutput(tmpstr, len);
}
}
}
| LBRACE sexp RBRACE { if (echo && $2 != NULL) {
aprepro.lexer->LexerOutput($2, strlen($2));
Expand Down Expand Up @@ -345,7 +213,7 @@ exp: NUM { $$ = $1; }
redefined_warning(aprepro, $1);
set_type(aprepro, $1, token::VAR); }
| AVAR EQUAL exp { $$ = $3;
aprepro.redefine_array($1->value.avar);
aprepro.redefine_array($1->value.avar);
$1->value.var= $3;
redefined_warning(aprepro, $1);
set_type(aprepro, $1, token::VAR); }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
TRIBITS_PACKAGE_DEFINE_DEPENDENCIES(
LIB_OPTIONAL_PACKAGES SEACASExodus
LIB_OPTIONAL_TPLS fmt
TEST_OPTIONAL_TPLS Pthread
)

0 comments on commit 3a258ce

Please sign in to comment.