NEURON
global_scalar.cpp
Go to the documentation of this file.
1 // NOTE: this assumes neuronapi.h is on your CPLUS_INCLUDE_PATH
2 // Exercises nrn_symbol_dataptr on a NOTUSER runtime scalar (created by HOC
3 // `x = 42`). Its value is stored in the top-level object-data array, not at
4 // sym->u.pval, so before the fix the returned pointer was an offset cast to a
5 // pointer and dereferencing it was undefined. The pointer must now alias the
6 // same storage HOC reads and writes.
7 #include <cmath>
8 #include <iostream>
9 #include "neuronapi.h"
10 
11 using std::cerr;
12 using std::endl;
13 
14 extern "C" void modl_reg(){/* No modl_reg */};
15 
16 static bool check(bool cond, const char* msg) {
17  if (!cond) {
18  cerr << "FAIL: " << msg << endl;
19  }
20  return cond;
21 }
22 
23 static bool eq(double got, double want, const char* msg) {
24  if (std::fabs(got - want) > 1e-12) {
25  cerr << "FAIL: " << msg << " — got " << got << ", want " << want << endl;
26  return false;
27  }
28  return true;
29 }
30 
31 int main(void) {
32  static const char* argv[] = {"global_scalar", "-nogui", "-nopython", nullptr};
33  nrn_init(3, argv);
34 
35  bool ok = true;
36 
37  // NOTUSER: a runtime scalar. Its data lives in the top-level object-data
38  // array, not at sym->u.pval -- this is the case the fix addresses.
39  nrn_hoc_call("myvar = 42");
40  double* p = nrn_symbol_dataptr(nrn_symbol("myvar"));
41  ok &= check(p != nullptr, "NOTUSER dataptr is non-null");
42  ok &= eq(*p, 42.0, "NOTUSER dataptr dereferences to 42");
43 
44  // The pointer must alias the storage HOC uses: write through it, then have
45  // HOC copy myvar into the built-in hoc_ac_ and confirm HOC saw the change.
46  *p = 3.5;
47  nrn_hoc_call("hoc_ac_ = myvar");
48  double* ac = nrn_symbol_dataptr(nrn_symbol("hoc_ac_"));
49  ok &= eq(*ac, 3.5, "HOC reads the value written through the NOTUSER dataptr");
50 
51  // USERDOUBLE built-in (t): dataptr already worked; make sure it still does.
52  double* t = nrn_symbol_dataptr(nrn_symbol("t"));
53  *t = 12.0;
54  nrn_hoc_call("hoc_ac_ = t");
55  ok &= eq(*ac, 12.0, "USERDOUBLE dataptr round-trips through HOC");
56 
57  return ok ? 0 : 1;
58 }
void modl_reg()
int main(void)
static bool check(bool cond, const char *msg)
static bool eq(double got, double want, const char *msg)
static char ** argv
Definition: inithoc.cpp:46
static void nrn_init(neuron::model_sorted_token const &, NrnThread *nt, Memb_list *ml, int type)
Definition: kschan.cpp:69
fabs
Definition: extdef.h:3
Symbol * nrn_symbol(char const *const name)
Definition: neuronapi.cpp:246
double * nrn_symbol_dataptr(const Symbol *sym)
Definition: neuronapi.cpp:260
int nrn_hoc_call(char const *const command)
Definition: neuronapi.cpp:494
size_t p