1 #include <../../nmodlconf.h>
34 #if !defined(NRN_DYNAMIC_UNITS)
35 #define NRN_DYNAMIC_UNITS 0
39 #include "../mswin/extra/d2upath.cpp"
48 extern double fabs(
double);
50 extern void diag(
char*,
char*);
56 #define OUTTOLERANCE(arg1, arg2) (fabs(arg2 / arg1 - 1.) > 1.e-5)
70 #if defined(NEURON_DATA_DIR)
71 static char*
dfile = NEURON_DATA_DIR
"/lib/nrnunits.lib" SUFFIX;
73 static char*
dfile =
"/usr/lib/units";
76 #if defined(__TURBOC__) || defined(__GO32__)
93 int pu(
int,
int,
int);
112 #if NRN_DYNAMIC_UNITS
113 static struct dynam {
122 }
prefix[] = {1
e-18,
"atto", 1
e-15,
"femto", 1
e-12,
"pico", 1
e-9,
"nano", 1
e-6,
123 "micro", 1
e-3,
"milli", 1
e-2,
"centi", 1
e-1,
"deci", 1e1,
"deka",
124 1e2,
"hecta", 1e2,
"hecto", 1e3,
"kilo", 1e6,
"mega", 1e6,
125 "meg", 1e9,
"giga", 1e12,
"tera", 0.0, 0};
144 }
else if (
pc && *
pc) {
145 return (
int) (*
pc++);
151 #define UNIT_STK_SIZE 20
157 static char buf[256];
158 GetModuleFileName(
NULL,
buf, 256);
159 for (
i = strlen(
buf);
i >= 0 &&
buf[
i] !=
'\\'; --
i) {
164 for (
i = strlen(
buf);
i >= 0 &&
buf[
i] !=
'\\'; --
i) {
175 return getenv(
"NEURONHOME");
184 static char buf[256];
201 f |=
pu(
p->dim[
i],
i, f);
206 f |=
pu(-
p->dim[
i],
i, f);
324 printf(
"Redefinition of units (%s) to:", s1);
326 printf(
" is ignored.\nThey remain:");
329 diag(
"Units redefinition", (
char*) 0);
340 #if NRN_DYNAMIC_UNITS
341 table = dynam[legacy].table;
342 names = dynam[legacy].names;
347 #if NRN_DYNAMIC_UNITS
349 for (
i = 0;
i < 2; ++
i) {
411 for (
i = 1;
i < val;
i++) {
426 if (up->
dim[0] == 9 ||
usp->
dim[0] == 9) {
477 diag(
"The units of the previous two expressions are not conformable", (
char*)
"\n");
483 "The previous primary expression with units: %s\n\
484 is missing a conversion factor and should read:\n (%g)*(",
488 diag(
")\n", (
char*) 0);
506 if (up->
dim[0] == 9 ||
usp->
dim[0] == 9) {
535 diag(
"underflow or overflow in units calculation", (
char*) 0);
551 diag(
"The previous expression is not dimensionless", (
char*) 0);
563 "The previous expression needs the conversion factor (%g)\n",
579 static int units_alloc_called = 0;
580 if (!units_alloc_called) {
581 units_alloc_called = 1;
582 #if NRN_DYNAMIC_UNITS
583 for (
i = 0;
i < 2; ++
i) {
586 dynam[
i].names = (
char*) calloc(
NTAB * 10,
sizeof(
char));
593 names = (
char*) calloc(
NTAB * 10,
sizeof(
char));
599 #if MODL || NMODL || HMODL || SIMSYS
604 static int first = 1;
608 #if NRN_DYNAMIC_UNITS
609 for (
i = 0;
i < 2; ++
i) {
635 diag(
"Bad MODLUNIT environment variable. Cant open:",
buf);
638 #if defined(__MINGW32__)
642 if (strncmp(s,
"/cygdrive/", 10) == 0) {
665 fprintf(stderr,
"Set a MODLUNIT environment variable path to the units table file\n");
666 fprintf(stderr,
"Cant open units table in either of:\n%s\n",
buf);
710 if(u1.dim[
i] != u2.dim[
i])
712 f = u1.factor/u2.factor;
722 printf(
"conformability\n");
728 printf(
"underflow or overflow\n");
737 int pu(
int u,
int i,
int f) {
768 if (
p->factor == 0.) {
820 p->factor /=
q->factor *
e;
822 p->dim[
i] -=
q->dim[
i];
824 p->factor *=
q->factor *
e;
826 p->dim[
i] +=
q->dim[
i];
828 if (
c >=
'2' &&
c <=
'9') {
836 while (*cp1 == *cp2++)
848 for (cp1 =
name; *cp1; cp1++)
850 if (cp1 >
name + 1 && *--cp1 ==
's') {
855 "Need declaration in UNITS block of the form:\n\
858 diag(
"Cannot recognize the units: ",
name);
863 static int equal(
char* s1,
char* s2) {
876 struct table *tp, *lp;
915 while (
c !=
'\n' &&
c != 0)
920 #if NRN_DYNAMIC_UNITS
931 for (
i = 0;
i < 6; ++
i) {
935 assert(strcmp(legstr,
"Legacy") == 0);
938 legacy = (
y_or_n ==
'Y') ? 1 : 0;
941 while (
c !=
'\n' &&
c != 0) {
954 while (
c !=
' ' &&
c !=
'\t') {
984 if (
t > 1 || (f > 0 &&
t != 0))
986 if (f == 0 &&
t == 1) {
997 printf(
"redefinition %s\n", np);
1001 #if NRN_DYNAMIC_UNITS
1005 double modern_getflt() {
1016 while (
c ==
' ' ||
c ==
'\t');
1019 if (
c >=
'0' &&
c <=
'9') {
1029 if (
c ==
'+' ||
c ==
'-') {
1033 while (
c >=
'0' &&
c <=
'9') {
1039 d_modern = atof(str);
1041 d_modern /= modern_getflt();
1054 #if NRN_DYNAMIC_UNITS
1056 return modern_getflt();
1063 while (
c ==
' ' ||
c ==
'\t');
1066 if (
c >=
'0' &&
c <=
'9') {
1067 d = d * 10. +
c -
'0';
1080 if (
c ==
'+' ||
c ==
'-') {
1086 while (
c >=
'0' &&
c <=
'9') {
1087 i =
i * 10 +
c -
'0';
1140 h = h * 57 + *np++ -
'0';
1173 #if NRN_DYNAMIC_UNITS
1179 "#define %s _nrnunit_%s[_nrnunit_use_legacy_]\n"
1181 "static double _nrnunit_%s[2] = {%a, %g}; /* %.18g */\n",
1194 #if (defined(LegacyFR) && LegacyFR == 1)
char * hoc_dos2unixpath(const char *d)
sprintf(buf, " if (secondorder) {\n" " int _i;\n" " for (_i = 0; _i < %d; ++_i) {\n" " _p[_slist%d[_i]] += dt*_p[_dlist%d[_i]];\n" " }}\n", numeqn, listnum, listnum)
char * getenv(const char *s)
static double dynam_unit_mag(int legacy, char *u1, char *u2)
void unit_mag_mul(double d)
static void units_alloc()
static void install_units_help(char *s1, char *s2)
void unit_push_num(double d)
static char * unames[NDIM]
int lookup(char *name, unit *up, int den, int c)
static char * neuronhome()
static void switch_units(int legacy)
void nrnunit_dynamic_str(char *buf, const char *name, char *u1, char *u2)
void install_units(char *s1, char *s2)
void diag(char *, char *)
static int Getc(FILE *inp)
#define OUTTOLERANCE(arg1, arg2)
static struct table * table
static int equal(char *s1, char *s2)
void Unit_exponent(int val)
static struct unit unit_stack[UNIT_STK_SIZE]
char * Unit_str(unit *up)
struct table * hash_table(char *)
static void print_unit_expr(int i)