NrnProperty::NrnProperty(const char* name) { Symbol* sym = hoc_table_lookup(name, hoc_built_in_symlist); if (!sym) { sym = hoc_table_lookup(name, hoc_top_level_symlist); } if(sym) { if (sym->type == MECHANISM) { /*EMPTY*/ }else if (sym->type == TEMPLATE && sym->u.ctemplate->is_point_){ sym = hoc_table_lookup(name, sym->u.ctemplate->symtable); }else{ sym = 0; } } if (sym) { Prop* p, *p0 = 0, *p1; //printf("prop_alloc %s %p type=%d\n", sym->name, sym, sym->subtype); // need to do this with no args hoc_push_frame(sym, 0); p = prop_alloc(&p0, sym->subtype, NULL); hoc_pop_frame(); for (; p0 != p; p0 = p1) { p1 = p0->next; single_prop_free(p0); } npi_ = new NrnPropertyImpl(p); npi_->del_ = true; }else{ npi_ = NULL; hoc_execerror(name, "is not a Mechanism or Point Process"); } }
void remake_pmech_types() { int i; Py_XDECREF(pmech_types); Py_XDECREF(rangevars_); pmech_types = PyDict_New(); rangevars_ = PyDict_New(); rangevars_add(hoc_table_lookup("diam", hoc_built_in_symlist)); rangevars_add(hoc_table_lookup("cm", hoc_built_in_symlist)); rangevars_add(hoc_table_lookup("v", hoc_built_in_symlist)); for (i=4; i < n_memb_func; ++i) { // start at pas nrnpy_reg_mech(i); } }
void nrnpy_reg_mech(int type) { int i; char* s; Memb_func* mf = memb_func + type; if (!nrnmodule_) { return; } if (mf->is_point) { if (nrn_is_artificial_[type] == 0) { Symlist* sl = nrn_pnt_template_[type]->symtable; Symbol* s = hoc_table_lookup("get_segment", sl); if (!s) { s = hoc_install("get_segment", OBFUNCTION, 0, &sl); #if MAC s->u.u_proc->defn.pfo = (Object**(*)(...))pp_get_segment; #else s->u.u_proc->defn.pfo = (Object**(*)())pp_get_segment; #endif } } return; } s = mf->sym->name; //printf("nrnpy_reg_mech %s %d\n", s, type); if (PyDict_GetItemString(pmech_types, s)) { hoc_execerror(s, "mechanism already exists"); } Py_INCREF(&nrnpy_MechanismType); PyModule_AddObject(nrnmodule_, s, (PyObject *)pmech_generic_type); PyDict_SetItemString(pmech_types, s, Py_BuildValue("i", type)); for (i = 0; i < mf->sym->s_varn; ++i) { Symbol* sym = mf->sym->u.ppsym[i]; rangevars_add(sym); } }
/** Make a hoc equivalent to Java class (jname) calling it hname in hoc. Done from NrnJava.load("name") after the class is loaded with FindClass. */ int convertJavaClassToHoc( JNIEnv *env, const char* jname, const char* hname, const char* path ) { //only if classname not already in use. if (!njclassnames) { njclassnames = new NJStrList(); } char* hn = nrn_dot2underbar(hname); // printf("loading %s --- calling it %s\n", jname, hn); Symbol* s = hoc_table_lookup(hn, hoc_top_level_symlist); if (s) { delete [] hn; if (s->type == TEMPLATE && s->u.ctemplate->id < 0) { return 2; } return 0; } jstring js = env->NewStringUTF( jname ); if (env->ExceptionOccurred()) { env->ExceptionDescribe();} jstring hs = env->NewStringUTF( hn ); jstring jp = env->NewStringUTF(path); int i = env->CallStaticIntMethod(neuronCls, makeHocClassID, js, hs, jp); if (i == 1) { njclassnames->append(new CopyString(jname)); } errno = 0; // have seen this set to 2 by linux delete [] hn; return i; }
JNIEXPORT jlong JNICALL Java_neuron_Neuron_methodID (JNIEnv *env, jclass, jlong jc, jstring name){ const char* s = env->GetStringUTFChars(name, 0); Object* ho = (Object*)jc; Symbol* sym = hoc_table_lookup(s, ho->ctemplate->symtable); //printf("methodID %s %s\n", s, sym->name); env->ReleaseStringUTFChars(name, s); return (jlong)sym; }
void OcPointer_reg() { class2oc("Pointer", cons, destruct, members, NULL, NULL, s_memb); // now make the val variable an actual double Symbol* sv = hoc_lookup("Pointer"); Symbol* sx = hoc_table_lookup("val", sv->u.ctemplate->symtable); sx->type = VAR; sx->arayinfo = NULL; sv->u.ctemplate->steer = steer_val; }
JNIEXPORT jstring JNICALL Java_neuron_Neuron_sGet (JNIEnv *env, jclass, jstring js){ const char* s = env->GetStringUTFChars(js, 0); Symbol* sym = hoc_table_lookup(s, hoc_top_level_symlist); assert(sym && sym->type == STRING); char** sval = hoc_top_level_data[sym->u.oboff].ppstr; env->ReleaseStringUTFChars(js, s); return env->NewStringUTF(*sval); }
JNIEXPORT jstring JNICALL Java_neuron_Neuron_hGetStringField (JNIEnv *env, jclass, jlong v, jstring js){ const char* s = env->GetStringUTFChars(js, 0); Object* o = (Object*)v; Symbol* sym = hoc_table_lookup(s, o->ctemplate->symtable); assert(sym && sym->type == STRING); char** sval = hoc_top_level_data[sym->u.oboff].ppstr; env->ReleaseStringUTFChars(js, s); return env->NewStringUTF(*sval); }
// note that an sgi CC complained about the alloc token not being interpretable //as std::alloc so we changed to hm_alloc static HocMech* common_register(char** m, Symbol* classsym, Symlist* slist, void (hm_alloc)(Prop*), int& type){ Pvmi cur, jacob, stat, initialize; cur = nil; jacob = nil; stat = nil; initialize = nil; HocMech* hm = new HocMech(); hm->slist = nil; hm->mech = classsym; hm->initial = hoc_table_lookup("initial", slist); hm->after_step = hoc_table_lookup("after_step", slist); if (hm->initial) initialize = (Pvmi)initial; if (hm->after_step) stat = (Pvmi)after_step; register_mech(m, hm_alloc, cur, jacob, stat, initialize, -1, 0); type = nrn_get_mechtype(m[1]); hoc_register_cvode(type, nil, nil, nil, nil); memb_func[type].hoc_mech = hm; return hm; }
JNIEXPORT jobject JNICALL Java_neuron_Neuron_oGet (JNIEnv *env, jclass, jstring js){ const char* s = env->GetStringUTFChars(js, 0); Symbol* sym = hoc_table_lookup(s, hoc_top_level_symlist); assert(sym && sym->type == OBJECTVAR); Object** po = hoc_top_level_data[sym->u.oboff].pobj; env->ReleaseStringUTFChars(js, s); jobject jo = h2jObject(*po); hoc_obj_unref(*po); return jo; }
JNIEXPORT jobject JNICALL Java_neuron_Neuron_hGetObjectField (JNIEnv *env, jclass, jlong v, jstring js){ const char* s = env->GetStringUTFChars(js, 0); Object* o = (Object*)v; Symbol* sym = hoc_table_lookup(s, o->ctemplate->symtable); assert(sym && sym->type == OBJECTVAR); Object** po = o->u.dataspace[sym->u.oboff].pobj; env->ReleaseStringUTFChars(js, s); jobject jo = h2jObject(*po); hoc_obj_unref(*po); return jo; }
JNIEXPORT void JNICALL Java_neuron_Neuron_hSetObjectField__Ljava_lang_String_2Ljava_lang_Object_2I (JNIEnv *env, jclass, jstring js, jobject joval, jint type){ jnisave const char* s = env->GetStringUTFChars(js, 0); Symbol* sym = hoc_table_lookup(s, hoc_top_level_symlist); assert(sym && sym->type == OBJECTVAR); Object** po = hoc_top_level_data[sym->u.oboff].pobj; Object** poval = nj_j2hObject(joval, type); Object* old = *po; *po = *poval; (*po)->refcount++; hoc_obj_unref(old); env->ReleaseStringUTFChars(js, s); jnirestore }
NonLinImpRep::NonLinImpRep() { int err; int i, j, ieq, cnt; NrnThread* _nt = nrn_threads; maxiter_ = 500; m_ = NULL; vsymtol_ = NULL; Symbol* vsym = hoc_table_lookup("v", hoc_built_in_symlist); if (vsym->extra) { vsymtol_ = &vsym->extra->tolerance; } // the equation order is the same order as for the fixed step method // for current balance. Remaining ode equation order is // defined by the memb_list. // how many equations n_v_ = _nt->end; n_ext_ = 0; if (_nt->_ecell_memb_list) { n_ext_ = _nt->_ecell_memb_list->nodecount*nlayer; } n_lin_ = nrndae_extra_eqn_count(); n_ode_ = 0; for (NrnThreadMembList* tml = _nt->tml; tml; tml = tml->next) { Memb_list* ml = tml->ml; i = tml->index; Pfridot s = (Pfridot)memb_func[i].ode_count; if (s) { cnt = (*s)(i); n_ode_ += cnt * ml->nodecount; } } neq_v_ = n_v_ + n_ext_ + n_lin_; neq_ = neq_v_ + n_ode_; if (neq_ == 0) { return; } m_ = cmplx_spCreate(neq_, 1, &err); assert(err == spOKAY); pv_ = new double*[neq_]; pvdot_ = new double*[neq_]; v_index_ = new int[n_v_]; rv_ = new double[neq_+1]; rv_ += 1; jv_ = new double[neq_+1]; jv_ += 1; diag_ = new double*[neq_]; deltavec_ = new double[neq_]; for (i=0; i < n_v_; ++i) { // utilize nd->eqn_index in case of use_sparse13 later Node* nd = _nt->_v_node[i]; pv_[i] = &NODEV(nd); pvdot_[i] = nd->_rhs; v_index_[i] = i+1; } for (i=0; i < n_v_; ++i) { diag_[i] = cmplx_spGetElement(m_, v_index_[i], v_index_[i]); } for (i=neq_v_; i < neq_; ++i) { diag_[i] = cmplx_spGetElement(m_, i+1, i+1); } scnt_ = structure_change_cnt; }
static PyObject* segment_getattro(NPySegObj* self, PyObject* name) { Symbol* sym; Py_INCREF(name); char* n = PyString_AsString(name); //printf("segment_getattr %s\n", n); PyObject* result = 0; PyObject* otype; PyObject* rv; if (strcmp(n, "v") == 0) { Node* nd = node_exact(self->pysec_->sec_, self->x_); result = Py_BuildValue("d", NODEV(nd)); }else if ((otype = PyDict_GetItemString(pmech_types, n)) != NULL) { int type = PyInt_AsLong(otype); //printf("segment_getattr type=%d\n", type); Node* nd = node_exact(self->pysec_->sec_, self->x_); Prop* p = nrn_mechanism(type, nd); if (!p) { rv_noexist(self->pysec_->sec_, n, self->x_, 1); Py_DECREF(name); return NULL; } NPyMechObj* m = PyObject_New(NPyMechObj, pmech_generic_type); if (m == NULL) { Py_DECREF(name); return NULL; } m->pyseg_ = self; m->prop_ = p; Py_INCREF(m->pyseg_); result = (PyObject*)m; }else if ((rv = PyDict_GetItemString(rangevars_, n)) != NULL) { sym = ((NPyRangeVar*)rv)->sym_; if (ISARRAY(sym)) { NPyRangeVar* r = PyObject_New(NPyRangeVar, range_type); r->pyseg_ = self; Py_INCREF(r->pyseg_); r->sym_ = sym; r->isptr_ = 0; result = (PyObject*)r; }else{ int err; double* d = nrnpy_rangepointer(self->pysec_->sec_, sym, self->x_, &err); if (!d) { rv_noexist(self->pysec_->sec_, n, self->x_, err); result = NULL; }else{ result = Py_BuildValue("d", *d); } } }else if (strncmp(n, "_ref_", 5) == 0) { if (strcmp(n+5, "v") == 0) { Node* nd = node_exact(self->pysec_->sec_, self->x_); result = nrn_hocobj_ptr(&(NODEV(nd))); }else if ((sym = hoc_table_lookup(n+5, hoc_built_in_symlist)) != 0 && sym->type == RANGEVAR) { if (ISARRAY(sym)) { NPyRangeVar* r = PyObject_New(NPyRangeVar, range_type); r->pyseg_ = self; Py_INCREF(r->pyseg_); r->sym_ = sym; r->isptr_ = 1; result = (PyObject*)r; }else{ int err; double* d = nrnpy_rangepointer(self->pysec_->sec_, sym, self->x_, &err); if (!d) { rv_noexist(self->pysec_->sec_, n+5, self->x_, err); result = NULL; }else{ result = nrn_hocobj_ptr(d); } } }else{ rv_noexist(self->pysec_->sec_, n, self->x_, 2); result = NULL; } }else if (strcmp(n, "__dict__") == 0) { Node* nd = node_exact(self->pysec_->sec_, self->x_); result = PyDict_New(); assert(PyDict_SetItemString(result, "v", Py_None) == 0); assert(PyDict_SetItemString(result, "diam", Py_None) == 0); assert(PyDict_SetItemString(result, "cm", Py_None) == 0); for (Prop* p = nd->prop; p ; p = p->next) { if (p->type > CAP && !memb_func[p->type].is_point){ char* pn = memb_func[p->type].sym->name; assert(PyDict_SetItemString(result, pn, Py_None) == 0); } } }else{ result = PyObject_GenericGetAttr((PyObject*)self, name); } Py_DECREF(name); return result; }
void Cvode::daspk_init_eqn(){ // DASPK equation order is exactly the same order as the // fixed step method for current balance (including // extracellular nodes) and linear mechanism. Remaining ode // equations are same order as for Cvode. Thus, daspk differs from // cvode order primarily in that cap and no-cap nodes are not // distinguished. // note that only one thread is allowed for sparse right now. NrnThread* _nt = nrn_threads; CvodeThreadData&z = ctd_[0]; double vtol; //printf("Cvode::daspk_init_eqn\n"); int i, j, in, ie, k, neq_v; // how many equations are there? Memb_func* mf; CvMembList* cml; //start with all the equations for the fixed step method. if (use_sparse13 == 0 || diam_changed != 0) { recalc_diam(); } z.neq_v_ = spGetSize(_nt->_sp13mat, 0); z.nvsize_ = z.neq_v_; // now add the membrane mechanism ode's to the count for (cml = z.cv_memb_list_; cml; cml = cml->next) { Pfridot s = (Pfridot)memb_func[cml->index].ode_count; if (s) { z.nvsize_ += cml->ml->nodecount * (*s)(cml->index); } } neq_ = z.nvsize_; //printf("Cvode::daspk_init_eqn: neq_v_=%d neq_=%d\n", neq_v_, neq_); if (z.pv_) { delete [] z.pv_; delete [] z.pvdot_; } z.pv_ = new double*[z.nvsize_]; z.pvdot_ = new double*[z.nvsize_]; atolvec_alloc(neq_); double* atv = n_vector_data(atolnvec_, 0); for (i=0; i < neq_; ++i) { atv[i] = ncv_->atol(); } vtol = 1.; if (!vsym) { vsym = hoc_table_lookup("v", hoc_built_in_symlist); } if (vsym->extra) { double x; x = vsym->extra->tolerance; if (x != 0 && x < vtol) { vtol = x; } } // deal with voltage and extracellular and linear circuit nodes // for daspk the order is the same assert(use_sparse13); if (use_sparse13) { for (in = 0; in < _nt->end; ++in) { Node* nd; Extnode* nde; nd = _nt->_v_node[in]; nde = nd->extnode; i = nd->eqn_index_ - 1; // the sparse matrix index starts at 1 z.pv_[i] = &NODEV(nd); z.pvdot_[i] = nd->_rhs; if (nde) { for (ie=0; ie < nlayer; ++ie) { k = i + ie + 1; z.pv_[k] = nde->v + ie; z.pvdot_[k] = nde->_rhs[ie]; } } } linmod_dkmap(z.pv_, z.pvdot_); for (i=0; i < z.neq_v_; ++i) { atv[i] *= vtol; } } // map the membrane mechanism ode state and dstate pointers int ieq = z.neq_v_; for (cml = z.cv_memb_list_; cml; cml = cml->next) { int n; mf = memb_func + cml->index; Pfridot sc = (Pfridot)mf->ode_count; if (sc && ( (n = (*sc)(cml->index)) > 0)) { Memb_list* ml = cml->ml; Pfridot s = (Pfridot)mf->ode_map; if (mf->hoc_mech) { for (j=0; j < ml->nodecount; ++j) { (*s)(ieq, z.pv_ + ieq, z.pvdot_ + ieq, ml->prop[j], atv + ieq); ieq += n; } }else{ for (j=0; j < ml->nodecount; ++j) { (*s)(ieq, z.pv_ + ieq, z.pvdot_ + ieq, ml->data[j], ml->pdata[j], atv + ieq, cml->index); ieq += n; } } } } structure_change_ = false; }
void Cvode::init_eqn(){ double vtol; NrnThread* _nt; CvMembList* cml; Memb_list* ml; Memb_func* mf; int i, j, zneq, zneq_v, zneq_cap_v; //printf("Cvode::init_eqn\n"); if (nthsizes_) { delete [] nthsizes_; nthsizes_ = 0; } neq_ = 0; for (int id = 0; id < nctd_; ++id) { CvodeThreadData& z = ctd_[id]; z.cmlcap_ = nil; z.cmlext_ = nil; for (cml = z.cv_memb_list_; cml; cml = cml->next) { if (cml->index == CAP) { z.cmlcap_ = cml; } if (cml->index == EXTRACELL) { z.cmlext_ = cml; } } } if (use_daspk_) { daspk_init_eqn(); return; } FOR_THREADS(_nt) { // for lvardt, this body done only once and for ctd_[0] CvodeThreadData& z = ctd_[_nt->id]; // how many ode's are there? First ones are non-zero capacitance // nodes with non-zero capacitance zneq_cap_v = z.cmlcap_ ? z.cmlcap_->ml->nodecount : 0; zneq = zneq_cap_v; // now add the membrane mechanism ode's to the count for (cml = z.cv_memb_list_; cml; cml = cml->next) { Pfridot s = (Pfridot)memb_func[cml->index].ode_count; if (s) { zneq += cml->ml->nodecount * (*s)(cml->index); } } //printf("%d Cvode::init_eqn neq_v=%d zneq_=%d\n", nrnmpi_myid, neq_v, zneq_); if (z.pv_) { delete [] z.pv_; delete [] z.pvdot_; z.pv_ = 0; z.pvdot_ = 0; } if (zneq) { z.pv_ = new double*[zneq]; z.pvdot_ = new double*[zneq]; } z.nvoffset_ = neq_; z.nvsize_ = zneq; neq_ += zneq; if (nth_) { break; } //lvardt } #if PARANEURON if (use_partrans_) { global_neq_ = nrnmpi_int_sum_reduce(neq_, mpicomm_); //printf("%d global_neq_=%d neq=%d\n", nrnmpi_myid, global_neq_, neq_); } #endif atolvec_alloc(neq_); for (int id = 0; id < nctd_; ++id) { CvodeThreadData& z = ctd_[id]; double* atv = n_vector_data(atolnvec_, id); zneq_cap_v = z.cmlcap_ ? z.cmlcap_->ml->nodecount : 0; zneq = z.nvsize_; zneq_v = zneq_cap_v; for (i=0; i < zneq; ++i) { atv[i] = ncv_->atol(); } vtol = 1.; if (!vsym) { vsym = hoc_table_lookup("v", hoc_built_in_symlist); } if (vsym->extra) { double x; x = vsym->extra->tolerance; if (x != 0 && x < vtol) { vtol = x; } } for (i=0; i < zneq_cap_v; ++i) { atv[i] *= vtol; } // deal with voltage nodes // only cap nodes for cvode for (i=0; i < z.v_node_count_; ++i) { //sentinal values for determining no_cap NODERHS(z.v_node_[i]) = 1.; } for (i=0; i < zneq_cap_v; ++i) { ml = z.cmlcap_->ml; z.pv_[i] = &NODEV(ml->nodelist[i]); z.pvdot_[i] = &(NODERHS(ml->nodelist[i])); *z.pvdot_[i] = 0.; // only ones = 1 are no_cap } // the remainder are no_cap nodes if (z.no_cap_node_) { delete [] z.no_cap_node_; delete [] z.no_cap_child_; } z.no_cap_node_ = new Node*[z.v_node_count_ - zneq_cap_v]; z.no_cap_child_ = new Node*[z.v_node_count_ - zneq_cap_v]; z.no_cap_count_ = 0; j = 0; for (i=0; i < z.v_node_count_; ++i) { if (NODERHS(z.v_node_[i]) > .5) { z.no_cap_node_[z.no_cap_count_++] = z.v_node_[i]; } if (z.v_parent_[i] && NODERHS(z.v_parent_[i]) > .5) { z.no_cap_child_[j++] = z.v_node_[i]; } } z.no_cap_child_count_ = j; // use the sentinal values in NODERHS to construct a new no cap membrane list new_no_cap_memb(z, _nt); // map the membrane mechanism ode state and dstate pointers int ieq = zneq_v; for (cml = z.cv_memb_list_; cml; cml = cml->next) { int n; ml = cml->ml; mf = memb_func + cml->index; Pfridot sc = (Pfridot)mf->ode_count; if (sc && ( (n = (*sc)(cml->index)) > 0)) { Pfridot s = (Pfridot)mf->ode_map; if (mf->hoc_mech) { for (j=0; j < ml->nodecount; ++j) { (*s)(ieq, z.pv_ + ieq, z.pvdot_ + ieq, ml->prop[j], atv + ieq); ieq += n; } }else{ for (j=0; j < ml->nodecount; ++j) { (*s)(ieq, z.pv_ + ieq, z.pvdot_ + ieq, ml->data[j], ml->pdata[j], atv + ieq, cml->index); ieq += n; } } } } } structure_change_ = false; }
static void check_list(const char* s, Symlist* sl) { if (hoc_table_lookup(s, sl)) { hoc_execerror(s, "already exists"); } }
void make_pointprocess() { char buf[256]; int i, cnt, type, ptype; Symbol* sp, *s2; char* classname = gargstr(1); //printf("classname=%s\n", classname); char* parnames = nil; if (ifarg(2)) { parnames = new char[strlen(gargstr(2)) + 1]; strcpy(parnames, gargstr(2)); } //if(parnames) printf("parnames=%s\n", parnames); Symbol* classsym = hoc_lookup(classname); if (classsym->type != TEMPLATE) { hoc_execerror(classname, "not a template"); } cTemplate* tp = classsym->u.ctemplate; Symlist* slist = tp->symtable; // increase the dataspace by 1 void pointer. The last element // is where the Point_process pointer can be found and when // the object dataspace is freed, so is the Point_process. if (tp->count > 0) { fprintf(stderr, "%d object(s) of type %s already exist.\n", tp->count, classsym->name); hoc_execerror("Can't make a template into a PointProcess when instances already exist", 0); } ++tp->dataspace_size; char** m = make_m(false, cnt, slist, classsym->name, parnames); check_list("loc", slist); check_list("get_loc", slist); check_list("has_loc", slist); //so far we need only the name and type sp = hoc_install("loc", FUNCTION, 0., &slist); sp->cpublic = 1; sp = hoc_install("get_loc", FUNCTION, 0., &slist); sp->cpublic = 1; sp = hoc_install("has_loc", FUNCTION, 0., &slist); sp->cpublic = 1; Symlist* slsav = hoc_symlist; hoc_symlist = nil; HocMech* hm = common_register(m, classsym, slist, alloc_pnt, type); hm->slist = hoc_symlist; hoc_symlist = slsav; s2 = hoc_table_lookup(m[1], hm->slist); assert(s2->subtype == type); // type = s2->subtype; ptype = point_reg_helper(s2); //printf("type=%d pointtype=%d %s %lx\n", type, ptype, s2->name, (long)s2); classsym->u.ctemplate->is_point_ = ptype; // classsym->name is already in slist as an undef, Remove it and // move s2 out of HocMech->slist and into slist. // That is the one with the u.ppsym. // The only reason it needs to be in slist is to find the // mechanims type. And it needs to be LAST in that list. // The only reason for the u.ppsym is for ndatclas.c and we // need to fill those symbols with oboff. sp = hoc_table_lookup(classsym->name, slist); hoc_unlink_symbol(sp, slist); hoc_unlink_symbol(s2, hm->slist); hoc_link_symbol(s2, slist); hoc_link_symbol(sp, hm->slist); // just so it isn't counted as leakage for (i=0; i < s2->s_varn; ++i) { Symbol* sp = hoc_table_lookup(s2->u.ppsym[i]->name, slist); s2->u.ppsym[i]->cpublic = 2; s2->u.ppsym[1]->u.oboff = sp->u.oboff; } for (i=0; i < cnt; ++i) { if (m[i]) { delete [] m[i]; } } delete [] m; if (parnames) { delete [] parnames; } ret(1.); }