1 #include <../../nrnconf.h>
22 #include "../mswin/extra/d2upath.h"
37 extern double fabs(
double);
39 extern void diag(
const char*,
const char*);
45 #define OUTTOLERANCE(arg1, arg2) (fabs(arg2 / arg1 - 1.) > 1.e-5)
50 #if defined(NEURON_DATA_DIR)
51 static char const*
const dfile = NEURON_DATA_DIR
"/lib/nrnunits.lib";
53 static char const*
const dfile =
"/usr/lib/units";
55 static char const*
const dfilealt =
"../../share/lib/nrnunits.lib";
64 int pu(
int,
int,
int);
86 }
prefix[] = {{1e-18,
"atto"},
108 static const char*
pc;
111 #include "embedded_nrnunits.lib"
126 char temp_path[MAX_PATH];
127 GetTempPath(MAX_PATH, temp_path);
128 char temp_file[MAX_PATH];
129 GetTempFileName(temp_path,
"nrn", 0, temp_file);
132 std::ofstream out(temp_file, std::ios::out | std::ios::binary);
137 return fopen(temp_file,
"r");
140 char temp_file[] =
"/tmp/nrnunitsXXXXXX";
141 int fd = mkstemp(temp_file);
147 std::ofstream out(temp_file, std::ios::out | std::ios::binary);
152 FILE* file = fdopen(fd,
"r");
164 }
else if (
pc && *
pc) {
165 return (
int) (*
pc++);
171 #define UNIT_STK_SIZE 20
176 std::string
buf(256,
'\0');
177 GetModuleFileName(
nullptr,
buf.data(), 256);
179 auto pos =
buf.find_last_of(
'\\');
182 pos =
buf.find_last_of(
'\\');
184 std::replace(
buf.begin(),
buf.end(),
'\\',
'/');
187 char*
buf = std::getenv(
"NEURONHOME");
188 return (
buf !=
nullptr) ? std::string(
buf) : std::string();
197 static char buf[256];
214 f |=
pu(
p->dim[
i],
i, f);
219 f |=
pu(-
p->dim[
i],
i, f);
335 printf(
"Redefinition of units (%s) to:", s1);
337 printf(
" is ignored.\nThey remain:");
340 diag(
"Units redefinition", (
char*) 0);
407 for (
i = 1;
i < val;
i++) {
422 if (up->
dim[0] == 9 ||
usp->
dim[0] == 9) {
464 fprintf(stderr,
"\nunits:");
466 fprintf(stderr,
"\nunits:");
468 diag(
"The units of the previous two expressions are not conformable", (
char*)
"\n");
474 "The previous primary expression with units: %s\n\
475 is missing a conversion factor and should read:\n (%g)*(",
478 diag(
")\n", (
char*) 0);
496 if (up->
dim[0] == 9 ||
usp->
dim[0] == 9) {
525 diag(
"underflow or overflow in units calculation", (
char*) 0);
541 diag(
"The previous expression is not dimensionless", (
char*) 0);
553 "The previous expression needs the conversion factor (%g)\n",
568 static int units_alloc_called = 0;
569 if (!units_alloc_called) {
570 units_alloc_called = 1;
573 names = (
char*) calloc(
NTAB * 10,
sizeof(
char));
581 static int first = 1;
596 s = getenv(
"MODLUNIT");
602 if ((
inpfile = fopen(
buf,
"r")) == (FILE*) 0) {
603 diag(
"Bad MODLUNIT environment variable. Cant open:",
buf);
606 #if defined(__MINGW32__)
610 std::string filename =
s +
"/lib/nrnunits.lib";
611 inpfile = fopen(filename.c_str(),
"r");
619 std::string filename =
s +
"/lib/nrnunits.lib";
620 inpfile = fopen(filename.c_str(),
"r");
632 fprintf(stderr,
"Set a MODLUNIT environment variable path to the units table file\n");
633 fprintf(stderr,
"Cant open units table in either of:\n%s\n",
buf);
645 int pu(
int u,
int i,
int f) {
677 if (
p->factor == 0.) {
729 p->factor /=
q->factor * e;
731 p->dim[
i] -=
q->dim[
i];
733 p->factor *=
q->factor * e;
735 p->dim[
i] +=
q->dim[
i];
737 if (
c >=
'2' &&
c <=
'9') {
747 while (*cp1 == *cp2++)
761 for (cp1 =
name; *cp1; cp1++)
763 if (cp1 >
name + 1 && *--cp1 ==
's') {
768 "Need declaration in UNITS block of the form:\n\
771 diag(
"Cannot recognize the units: ",
name);
776 static int equal(
const char* c1,
const char* c2) {
785 struct table *tp, *lp;
821 while (
c !=
'\n' &&
c != 0)
830 while (
c !=
' ' &&
c !=
'\t') {
860 if (
t > 1 || (f > 0 &&
t != 0))
862 if (f == 0 &&
t == 1) {
886 while (
c ==
' ' ||
c ==
'\t');
889 if (
c >=
'0' &&
c <=
'9') {
899 if (
c ==
'+' ||
c ==
'-') {
903 while (
c >=
'0' &&
c <=
'9') {
909 d_modern = atof(str);
948 h = h * 57 + *
np++ -
'0';
int Sprintf(char(&buf)[N], const char *fmt, Args &&... args)
Redirect sprintf to snprintf if the buffer size can be deduced.
void unit_mag_mul(double d)
static char const *const dfile
static void units_alloc()
void nrnunit_str(char(&buf)[NRN_BUFSIZE], const char *name, const char *u1, const char *u2)
static char const *const dfilealt
static FILE * open_embedded_nrnunits_as_file()
static std::string neuronhome()
static void install_units_help(char *s1, char *s2)
void unit_push_num(double d)
static char * unames[NDIM]
static int equal(const char *c1, const char *c2)
const char * Unit_str(unit *up)
struct table * hash_table(const char *)
int lookup(char *name, unit *up, int den, int c)
void install_units(char *s1, char *s2)
static int Getc(FILE *inp)
void Unit_push(const char *)
#define OUTTOLERANCE(arg1, arg2)
static struct table * table
void diag(const char *, const char *)
void Unit_exponent(int val)
static struct unit unit_stack[UNIT_STK_SIZE]
static constexpr std::string_view embedded_nrnunits