std::map<std::string, std::string> q::qDict2StringMap(K data) throw(std::string) { if (data == K_NIL) { throw std::string("nil dict"); } std::vector<std::string> keys, vals; switch (data->t) { case 0: if (data->n != 0) { throw std::string("not a dict or empty list"); } break; case XT: return qDict2StringMap(data->k); case XD: assert(data->n == 2); keys = qList2String(kK(data)[0]); vals = qList2String(kK(data)[1]); break; default: throw std::string("not a dict"); } assert(keys.size() == vals.size()); std::map<std::string, std::string> result; for (auto k = keys.begin(), v = vals.begin(); k != keys.end(); ++k, ++v) { result[*k] = *v; } return result; }
//create ,pass and recieve a simple dictionary. [Note Dictionary will be // homogenous. This demo gives an idea on how to deal withthe heterogenous // case.] int eg6() { int i=0,l=2; K keys=ktn(KS,l); K vals=ktn(KI,l); K dict; K result,resultk,resultv; //A dictionary is a mapping of two conforming lists. kI(vals)[0]=1; kI(vals)[1]=2; kS(keys)[0]=ss("key1"); kS(keys)[1]=ss("key2"); // Turn these into a dictionary dict=xD(keys,vals); result=k(c,"{[x]x[`key3]:`int$.z.t;show x;x}",dict,(K)0); printf( " This return has [type=%i] and contains %i enclosed elements\n\n\n",result->t,result->i); //Extract the keys and value vectors from the k bject resultk=kK(result)[0]; resultv=kK(result)[1]; //extract the lenth of the vectors l=resultk->n; printf( " The returned dictionary has %i elements.\n",l); for(i=0;i<l;i++) { printf( " The %i key is %s \n",i,kS(resultk)[i]); printf( " The associated value is %i \n",kI(resultv)[i]); } return 1; }
int mlput(K x,K y){ int fstype=y->t,fsint=y->i,i=0,funcerr=0; K z; char b[2]={0,0}; mlint64 j={0,0}; //printf("%s:%d,%d\n","mlput",x->t,x->n); switch(x->t){ case -KB: case -KG: case -KC:b[0]=x->g;R MLPutString(ml_lp,b); case -KH:R MLPutInteger16(ml_lp,x->h); case -KI:R MLPutInteger32(ml_lp,x->i); case -KJ:*(J*)&j=x->j;R MLPutInteger64(ml_lp,j); case -KE:R MLPutReal32(ml_lp,x->e); case -KF:R MLPutReal64(ml_lp,x->f); case -KS:R MLPutSymbol(ml_lp,x->s); case KB: case KG: case KC:R MLPutByteString(ml_lp,kG(x),x->n); case KH:R MLPutInteger16List(ml_lp,kH(x),x->n); case KI:R MLPutInteger32List(ml_lp,kI(x),x->n); case KJ:R MLPutInteger64List(ml_lp,(mlint64*)kJ(x),x->n); case KE:R MLPutReal32List(ml_lp,kE(x),x->n); case KF:R MLPutReal64List(ml_lp,kF(x),x->n); case KS:if(!MLPutFunction(ml_lp,"List",x->n)){ R 0; }else{ for(i=0;i<x->n;i++)if(!MLPutSymbol(ml_lp,kS(x)[i]))R 0; } break; case 0: if(0==x->n){ R MLPutFunction(ml_lp, "List",0); }else if((3==x->n)&&(fstype==kK(x)[0]->t)){ z=kK(x)[2]; if(!MLPutFunction(ml_lp,kK(x)[1]->s,z->n)){R 0;}else{ switch(z->t){ case 0:for(i=0;i<z->n;i++)if(!mlput(kK(z)[i],y))R 0;break; case KH:for(i=0;i<z->n;i++)if(!MLPutInteger16(ml_lp,kH(z)[i]))R 0;break; case KI:for(i=0;i<z->n;i++)if(!MLPutInteger32(ml_lp,kI(z)[i]))R 0;break; case KJ:for(i=0;i<z->n;i++){*(J*)&j=kJ(z)[i];if(!MLPutInteger64(ml_lp,j))R 0;}break; case KE:for(i=0;i<z->n;i++)if(!MLPutReal32(ml_lp,kE(z)[i]))R 0;break; case KF:for(i=0;i<z->n;i++)if(!MLPutReal64(ml_lp,kF(z)[i]))R 0;break; case KS:for(i=0;i<z->n;i++)if(!MLPutSymbol(ml_lp,kS(z)[i]))R 0;break; case KC:for(i=0;i<z->n;i++){b[0]=kC(z)[i];if(!MLPutString(ml_lp,b))R 0;}break; default:break; } } }else{ if(!MLPutFunction(ml_lp,"List",x->n)){R 0;}else{for(i=0;i<x->n;i++)if(!mlput(kK(x)[i],y)){MLPutSymbol(ml_lp,"ParaErr");funcerr=1;}if(funcerr)R 0;} } break; default: R 0; } R 1; }
int main(int argc,char*argv[]) { K flip,result,columnNames,columnData; int row,col,nCols,nRows; int handle=khpu("localhost",1234,"user:password"); if(handle<0) exit(1); result = k(handle,"`asc",(K)0); std::string str = "([]a:til 10;b:reverse til 10;c:10#01010101010b;d:`a)"; result = k(handle,str.c_str(),(K)0); if(!result) printf("Network Error\n"),perror("Network"),exit(1); if(result->t==-128) printf("Server Error %s\n",result->s),kclose(handle),exit(1); // kclose(handle); if(result->t!=99&&result->t!=98) { printf("type %d\n",result->t); r0(result); exit(1); } flip = ktd(result); // if keyed table, unkey it. ktd decrements ref count of arg. // table (flip) is column names!list of columns (data) columnNames = kK(flip->k)[0]; columnData = kK(flip->k)[1]; nCols = columnNames->n; nRows = kK(columnData)[0]->n; for(row=0;row<nRows;row++) { if(0==row) { for(col=0;col<nCols;col++) { if(col>0)printf(","); printf("%s",kS(columnNames)[col]); } printf("\n"); } for(col=0;col<nCols;col++) { K obj=kK(columnData)[col]; if(col>0)printf(","); switch(obj->t) { case(1):{printf("%d",kG(obj)[row]);}break; case(4):{printf("%d",kG(obj)[row]);}break; case(5):{printf("%d",kH(obj)[row]);}break; case(6):{printf("%d",kI(obj)[row]);}break; case(7):{printf("%lld",kJ(obj)[row]);}break; case(8):{printf("%f",kE(obj)[row]);}break; case(9):{printf("%f",kF(obj)[row]);}break; case(11):{printf("%s",kS(obj)[row]);}break; default:{printf("unknown type");}break; } } printf("\n"); } r0(flip); return 0; }
//create ,pass and recieve a simple table. int eg7() { K cc,d,e,v,tab; K flip,result,columnNames,columnData; int row,col,nCols,nRows; cc=ktn(KS,2);kS(cc)[0]=ss("pid");kS(cc)[1]=ss("uid"); d=ktn(KS,3);kS(d)[0]=ss("ibm");kS(d)[1]=ss("gte");kS(d)[2]=ss("kvm"); e=ktn(KI,3);kI(e)[0]=1;kI(e)[1]=2;kI(e)[2]=3; v=knk(2,d,e); tab=xT(xD(cc,v)); flip=k(c,"{[x]a:update t:.z.t,y:.z.d from x;.tst.t:a;a}",tab,(K)0); //Turn into a dictionary. flip->k [transpose?] //Display table. [Borrowed from code.kx.com: // https://code.kx.com/trac/attachment/wiki/Cookbook/InterfacingWithC/csv.c ] columnNames=kK(flip->k)[0]; columnData=kK(flip->k)[1]; nCols=columnNames->n; nRows=kK(columnData)[0]->n; for(row=0;row<nRows;row++) { if(0==row) { for(col=0;col<nCols;col++) { if(col>0)printf(","); printf("%s",kS(columnNames)[col]); } printf("\n"); } for(col=0;col<nCols;col++) { K obj=kK(columnData)[col]; if(col>0)printf(","); switch(obj->t) { case(1):{printf("%d",kG(obj)[row]);}break; case(4):{printf("%d",kG(obj)[row]);}break; case(5):{printf("%d",kH(obj)[row]);}break; case(6):{printf("%d",kI(obj)[row]);}break; case(7):{printf("%lld",kJ(obj)[row]);}break; case(8):{printf("%f",kE(obj)[row]);}break; case(9):{printf("%f",kF(obj)[row]);}break; case(11):{printf("%s",kS(obj)[row]);}break; case(19):{printf("%i",kI(obj)[row]);}break; case(14):{printf("%i",kI(obj)[row]);}break; default:{printf("unknown type");}break; } } printf("\n"); } return 1; }
int iskeyedtable(K p) { K v; if (99!=p->t) return FALSE; v=kK(p)[0]; if (98!=v->t) return FALSE; v=kK(p)[1]; if (98!=v->t) return FALSE; return TRUE; }
static PyObject* from_table_kobject(K x){ /* the strategy is to create a list of tuples these are then passed to OrderedDict to retain the order of the columns for example OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)]). OrderedDict does not have a c-api so use a callback constructor */ PyObject* result ; Py_ssize_t i, length; PyObject *keys ; PyObject *vals ; PyObject *collectionsName, *collectionsMod, *OrderedDict, *pDict, *list, *tple, *args; keys = from_any_kobject( kK(x->k)[0] ); vals = from_columns_kobject( kK(x->k)[1] ); collectionsName = PyUnicode_FromString((char*)"collections"); collectionsMod = PyImport_Import(collectionsName); Py_DECREF(collectionsName); if(collectionsMod != NULL) { /* printf("creating ordered table\n"); */ length = PyList_Size(keys); list = PyList_New(length); for(i = 0; i != length; ++i) { /* tple create new ref, pylist_setitem steals it */ tple = PyTuple_Pack(2, PyList_GetItem(keys, i), PyList_GetItem(vals, i)); PyList_SetItem(list, i, tple); } pDict = PyModule_GetDict(collectionsMod); // borrowed ref OrderedDict = PyDict_GetItemString(pDict, (char*)"OrderedDict"); // borrowed ref args = PyTuple_Pack(1, list); // new ref result = PyObject_CallObject(OrderedDict, args); // new ref Py_DECREF(args); Py_DECREF(collectionsMod); Py_DECREF(list); } else { /* printf("creating unordered table\n"); */ result = PyDict_New(); if( PyList_CheckExact(keys)) { length = PyList_Size(keys); for(i = 0; i != length; ++i) { PyDict_SetItem(result, PyList_GetItem(keys, i), PyList_GetItem(vals, i)); } } } Py_DECREF(keys); Py_DECREF(vals); return result; }
K eval(K x,K y,K z){K*k;S*b,s;SQLULEN w;SQLLEN*nb;SQLINTEGER*wb;H*tb,u,t,j=0,p,m;F f;C c[128];I n=xj<0;D d=d1(n?-xj:xj);U(d)x=y;Q(z->t!=-KJ||xt!=-KS&&xt!=KC,"type") if(z->j)SQLSetStmtAttr(d,SQL_ATTR_QUERY_TIMEOUT,(SQLPOINTER)(SQLULEN)z->j,0); if(xt==-KS)Q1(SQLColumns(d,(S)0,0,(S)0,0,xs,S0,(S)0,0))else{I e;K q=kpn(xG,xn);ja(&q,"\0");e=SQLExecDirect(d,q->G0,xn);r0(q);Q1(e)} SQLNumResultCols(d,&j);P(!j,(d0(d),knk(0))) b=malloc(j*SZ),tb=malloc(j*2),wb=malloc(j*SZ),nb=malloc(j*SZ),x=ktn(KS,j),y=ktn(0,j);// sqlserver: no bind past nonbind DO(j,Q1(SQLDescribeCol(d,(H)(i+1),c,128,&u,&t,&w,&p,&m))xS[i]=sn(c,u); if(t>90)t-=82; Q(t<-11||t>12,xS[i])wb[i]=ut[tb[i]=t=t>0?t:12-t]==KS&&w?w+1:wt[t];if(ut[t]==KS&&(n||!wb[i]||wb[i]>9))tb[i]=13) DO(j,kK(y)[i]=ktn(ut[t=tb[i]],0);if(w=wb[i])Q1(SQLBindCol(d,(H)(i+1),ct[t],b[i]=malloc(w),w,nb+i))) for(;SQL_SUCCEEDED(SQLFetch(d));)DO(j,k=kK(y)+i;u=ut[t=tb[i]];s=b[i];n=SQL_NULL_DATA==(int)nb[i]; if(!u)jk(k,n?ktn(ct[t]?KC:KG,0):wb[i]?kp(s):gb(d,(H)(i+1),t)); else ja(k,n?nu(u):u==KH&&wb[i]==1?(t=(H)*s,(S)&t):u==KS?(s=dtb(s,nb[i]),(S)&s):u<KD?s:u==KZ?(f=ds(s)+(vs(s+6)+*(I*)(s+12)/1e9)/8.64e4,(S)&f):(w=u==KD?ds(s):vs(s),(S)&w))) if(!SQLMoreResults(d))O("more\n");DO(j,if(wb[i])free(b[i]))R free(b),free(tb),free(wb),free(nb),d0(d),xT(xD(x,y));}
std::size_t setServerInfos(K const servers, ::TDF_SERVER_INFO out[MAXSERVER]) throw(std::string) { if (servers == K_NIL) throw std::string("null servers"); if (servers->t != XT) throw std::string("not a table"); std::vector<std::string> const cols = q::qList2String(kK(servers->k)[0]); if (cols.size() != 4) throw std::string("invalid server info table"); K const table = kK(servers->k)[1]; assert(table->t == 0); assert(table->n == 4); assert(kK(table)[0]->t >= 0); assert(kK(table)[0]->n >= 0); std::size_t const count = static_cast<std::size_t>(kK(table)[0]->n); if (count > MAXSERVER) { throw std::string("too many servers"); } std::vector<std::string> hosts, uids, pwds; std::vector<long long> ports; for (std::size_t c = 0; c < table->n; ++c) { if (cols[c] == "host") { hosts = q::qList2String(kK(table)[c]); } else if (cols[c] == "port") { ports = q::qList2Dec(kK(table)[c]); } else if (cols[c] == "username") { uids = q::qList2String(kK(table)[c]); } else if (cols[c] == "password") { pwds = q::qList2String(kK(table)[c]); } else { throw cols[c]; } } for (std::size_t i = 0; i < count; ++i) { setServerInfo(hosts[i], out[i].szIp, "host/IP", i); setServerInfo(uids[i], out[i].szUser, "username", i); setServerInfo(pwds[i], out[i].szPwd, "password", i); if (ports[i] >= std::pow(10, _countof(out[i].szPort))) { std::ostringstream buffer; buffer << "port number [" << i << "] too long"; throw buffer.str(); } else { std::memset(out[i].szPort, '\0', _countof(out[i].szPort)); std::snprintf(out[i].szPort, _countof(out[i].szPort), "%ld", ports[i]); } } return count; }
static K printdict(K x) { K keys = kK(x)[0]; K data = kK(x)[1]; for (int row = 0; row < keys->n; row++) { printitem(keys, row); printf("| "); printitem(data, row); if (row < keys->n - 1) printf("\n"); } return (K) 0; }
int ei_x_encode_table(ei_x_buff* types, ei_x_buff* values, K r, QOpts* opts) { EI(ei_x_encode_tuple_header(types, 2)); EI(ei_x_encode_atom(types, "table")); EI(ei_x_encode_tuple_header(values, 2)); ei_x_buff column_types; ei_x_new_with_version(&column_types); EIC(ei_x_encode_k_tv(&column_types, values, kK(r->k)[0], opts), ei_x_free(&column_types)); ei_x_free(&column_types); EI(ei_x_encode_k_tv(types, values, kK(r->k)[1], opts)); return 0; }
K itemAtIndex(K a, I i) { // Return i-th item from any type as K - TODO: oom wherever this is used I at=a->t; if( 0< at)R ci(a); if(-4==at)R Ks(kS(a)[i]); //could refactor all this if(-3==at)R Kc(kC(a)[i]); if(-2==at)R Kf(kF(a)[i]); if(-1==at)R Ki(kI(a)[i]); R ci(kK(a)[i]); }
int ei_x_encode_dict_impl(ei_x_buff* types, ei_x_buff* values, const char* t, K r, QOpts* opts) { EI(ei_x_encode_tuple_header(types, r->n+1)); EI(ei_x_encode_atom(types, t)); EI(ei_x_encode_tuple_header(values, r->n)); int i; for(i=0; i<r->n; ++i) { EI(ei_x_encode_k_tv(types, values, kK(r)[i], opts)); } return 0; }
int ei_x_encode_unknown(ei_x_buff* types, ei_x_buff* values, K r, QOpts* opts) { EI(ei_x_encode_tuple_header(types, r->n+1)); EI(ei_x_encode_long(types, r->t)); EI(ei_x_encode_tuple_header(values, r->n)); int i; for(i=0; i<r->n; ++i) { EI(ei_x_encode_k_tv(types, values, kK(r)[i], opts)); } return 0; }
static PyObject* from_table_kobject(K x){ PyObject* result ; Py_ssize_t i, length; PyObject *keys ; PyObject *vals ; keys = from_any_kobject( kK(x->k)[0] ); vals = from_columns_kobject( kK(x->k)[1] ); result = PyDict_New(); if( PyList_CheckExact(keys)) { length = PyList_Size(keys); for(i = 0; i != length; ++i) { PyDict_SetItem(result, PyList_GetItem(keys, i), PyList_GetItem(vals, i)); } } Py_DECREF(keys); Py_DECREF(vals); return result; }
int ei_x_encode_general_list(ei_x_buff* types, ei_x_buff* values, K r, QOpts* opts) { LOG("ei_x_encode_general_list length "FMT_KN"\n", r->n); EI(ei_x_encode_tuple_header(types, 2)); EI(ei_x_encode_atom(types, "list")); if(r->n > 0) { int all_strings = 1; EI(ei_x_encode_list_header(values, r->n)); int i; for(i=0; i<r->n; ++i) { K elem = kK(r)[i]; if(elem->t != KC) { all_strings = 0; break; } EI(ei_x_encode_string_len(values, (const char*)kC(elem), elem->n)); } if(all_strings) { EI(ei_x_encode_atom(types, "string")); } else { EI(ei_x_encode_list_header(types, r->n)); int j; for(j=0; j<i; ++j) { EI(ei_x_encode_atom(types, "string")); } for(; i<r->n; ++i) { EI(ei_x_encode_k_tv(types, values, kK(r)[i], opts)); } EI(ei_x_encode_empty_list(types)); } } else { EI(ei_x_encode_empty_list(types)); } EI(ei_x_encode_empty_list(values)); return 0; }
static K printtable(K x) { K flip = ktd(x); K columns = kK(flip->k)[0]; K rows = kK(flip->k)[1]; int colcount = columns->n; int rowcount = kK(rows)[0]->n; for (int i = 0; i < colcount; i++) printf("%s\t", kS(columns)[i]); printf("\n"); for (int i = 0; i < rowcount; i++) { for (int j = 0; j < colcount; j++) { printitem(kK(rows)[j], i); printf("\t"); } printf("\n"); } return (K) 0; }
//Arthur says he doesn't use malloc or free. Andrei Moutchkine claims smallest unit is vm page (his truss says no malloc + add pages one at a time). //Arthur not using malloc is probably true. No strdup & related functions in binary's strings. Note: Skelton references "different allocator" not in \w report //This source would be improved by getting ridding of remaing malloc/calloc/realloc K cd(K x) { #ifdef DEBUG if(x && x->c <=0 ) { er(Tried to cd() already freed item) dd(tests) dd((L)x) dd(x->c) dd(x->t) dd(x->n) show(x); } #endif P(!x,0) x->c -= 1; SW(xt) { CSR(5,) CS(0, DO(xn, cd(kK(x)[xn-i-1]))) //repool in reverse, attempt to maintain order } if(x->c > 0) R x; #ifdef DEBUG DO(kreci, if(x==krec[i]){krec[i]=0; break; })
static K printitem(K x, int index) { switch (xt) { case 0: printq(kK(x)[index]); break; case 1: showatom(kb, kG, x, index); break; case 4: showatom(kg, kG, x, index); break; case 5: showatom(kh, kH, x, index); break; case 6: showatom(ki, kI, x, index); break; case 7: showatom(kj, kJ, x, index); break; case 8: showatom(ke, kE, x, index); break; case 9: showatom(kf, kF, x, index); break; case 10: showatom(kc, kC, x, index); break; case 11: showatom(ks, kS, x, index); break; case 14: showatom(kd, kI, x, index); break; case 15: showatom(kz, kF, x, index); break; default: return krr("notimplemented"); } return (K) 0; }
std::vector<std::string> q::qList2String(K data) throw(std::string) { if (data == K_NIL) { throw std::string("nil string or symbol list"); } std::vector<std::string> result; switch (data->t) { case 0: // char list list (a.k.a. string list) assert(data->n >= 0); result.reserve(static_cast<std::size_t>(data->n)); for (J i = 0; i < data->n; ++i) { result.push_back(q2String(kK(data)[i])); } break; case KS: // symbol list assert(data->n >= 0); result.reserve(static_cast<std::size_t>(data->n)); for (J i = 0; i < data->n; ++i) { result.push_back(kS(data)[i]); } break; default: if ((ENUMmin <= data->t) && (data->t <= ENUMmax)) { // enumerated symbol list K_ptr syms(k(0, "value", r1(data), K_NIL)); assert(syms && (syms->n == data->n)); assert(syms->n >= 0); result.reserve(static_cast<std::size_t>(syms->n)); for (J i = 0; i < data->n; ++i) { result.push_back(kS(syms)[i]); } } else { throw std::string("not a string or symbol list"); } } assert(result.size() == data->n); return result; }
K kclone(K a)//Deep copy -- eliminate where possible { if(!a) R 0; I t=a->t,n=a->n; K z= 7==t?Kv():newK(t,n); if (4==ABS(t)) DO(n, kS(z)[i]=kS(a)[i]) //memcpy everywhere is better else if(3==ABS(t)) DO(n, kC(z)[i]=kC(a)[i]) else if(2==ABS(t)) DO(n, kF(z)[i]=kF(a)[i]) else if(1==ABS(t)) DO(n, kI(z)[i]=kI(a)[i]) else if(0== t ) DO(n, kK(z)[i]=kclone(kK(a)[i])) else if(5== t ) DO(n, kK(z)[i]=kclone(kK(a)[i])) else if(7== t ) { I k=0; z->t=a->t; I vt=z->n = a->n; K kv; V*v; SW(vt) { CS(1, k=((K)kV(a)[CODE])->n-1; M(z,kv=newK(-4,k+1)) v=(V*)kK(kv); //v[k]=0;//superfluous reminder DO(k, V w=kW(a)[i]; if(VA(w))v[i]=w; //TODO: is this ok for NAMES? see similar code in capture() else { K r=kclone(*(K*)w); //oom V q=newE(LS,r); //oom kap((K*) kV(z)+LOCALS,&q);//oom cd(q);//kap does ci q=EVP(q); //oom free z etc. kap needs checking v[i]=q; } ) ) CS(2, M(z,kv=newK(-4,3)) v=(V*)kK(kv); memcpy(v,kW(a),3*sizeof(V)); )
TDF_API K K_DECL TDF_codeTable(K h, K market) { ::THANDLE tdf = NULL; std::string mkt; try { TDF::parseTdfHandle(h, tdf); mkt = q::q2String(market); } catch (std::string const& error) { return q::error2q(error); } unsigned int codeCount = 0; ::TDF_CODE* t = NULL; ::TDF_ERR const result = static_cast<::TDF_ERR>(::TDF_GetCodeTable(tdf, mkt.c_str(), &t, &codeCount)); TDF::Ptr<::TDF_CODE> codes(t); if (result != TDF_ERR_SUCCESS) { return q::error2q(TDF::getError(result)); } assert(codes); assert(codeCount >= 0); q::K_ptr data(ktn(0, 6)); kK(data.get())[0] = //Wind Code: AG1312.SHF Wind::accessor::SymbolAccessor<::TDF_CODE, char[32]>(&::TDF_CODE::szWindCode).extract(codes.get(), codeCount); kK(data.get())[1] = //market code: SHF Wind::accessor::SymbolAccessor<::TDF_CODE, char[ 8]>(&::TDF_CODE::szMarket).extract(codes.get(), codeCount); kK(data.get())[2] = //original code: ag1312 Wind::accessor::SymbolAccessor<::TDF_CODE, char[32]>(&::TDF_CODE::szCode).extract(codes.get(), codeCount); kK(data.get())[3] = Wind::accessor::SymbolAccessor<::TDF_CODE, char[32]>(&::TDF_CODE::szENName).extract(codes.get(), codeCount); kK(data.get())[4] = //Chinese name: »¦Òø1302 Wind::accessor::SymbolAccessor<::TDF_CODE, char[32], Wind::encoder::GB18030_UTF8>(&::TDF_CODE::szCNName).extract(codes.get(), codeCount); kK(data.get())[5] = Wind::accessor::IntAccessor<::TDF_CODE, G>(&::TDF_CODE::nType).extract(codes.get(), codeCount); return data.release(); }
K py(K f, K x, K lib) { int argc; char **argv; char *error, *p, *buf; void *h; K r; #ifdef PY3K char *oldloc; #endif h = dlopen((const char *)kG(lib), RTLD_NOW|RTLD_GLOBAL); if (!h) R krr(dlerror()); dlerror(); /* Clear any existing error */ Py_Main = dlsym(h, "Py_Main"); P((error = dlerror()),krr(error)); P(xt, krr("argv type")); I m = 0; /* buf length */ DO(xn, K y; P((y = kK(x)[i])->t!=KC, krr("arg type")); m += y->n+1); argc = xn+1; argv = malloc(sizeof(char*) * argc); P(!argv, krr("memory")); buf = malloc(m); P(!buf,(free(argv),krr("memory"))); argv[0] = f->s; p = buf; DO(xn, K y = kK(x)[i]; argv[i+1] = memcpy(p, kG(y), y->n); p += y->n; *p++ = '\0'); #ifdef PY3K dlerror(); /* Clear any existing error */ #if PY3K < 35 c2w = dlsym(h, "_Py_char2wchar"); #else c2w = dlsym(h, "Py_DecodeLocale"); #endif P((error = dlerror()),krr(error)); dlerror(); /* Clear any existing error */ #if PY3K < 34 PyMem_Free = dlsym(h, "PyMem_Free"); #else PyMem_Free = dlsym(h, "PyMem_RawFree"); #endif P((error = dlerror()),krr(error)); wchar_t **wargv = malloc(sizeof(wchar_t*)*(argc+1)); wchar_t **wargv_copy = malloc(sizeof(wchar_t*)*(argc+1)); oldloc = strdup(setlocale(LC_ALL, NULL)); setlocale(LC_ALL, ""); DO(argc,P(!(wargv[i]=c2w(argv[i],NULL)),krr("decode"))); memcpy(wargv_copy, wargv, sizeof(wchar_t*)*argc); setlocale(LC_ALL, oldloc); free(oldloc); wargv[argc] = wargv_copy[argc] = NULL; r = ki(Py_Main(argc, wargv)); DO(argc,PyMem_Free(wargv_copy[i])); free(wargv_copy); free(wargv); #else r = ki(Py_Main(argc, argv)); #endif dlclose(h); free(argv); free(buf); R r; }
TDF_API K K_DECL TDF_optionCodeInfo(K h, K windCode) { ::THANDLE tdf = NULL; std::string code; try { TDF::parseTdfHandle(h, tdf); code = q::q2String(windCode); } catch (std::string const& error) { return q::error2q(error); } ::TDF_OPTION_CODE info = { 0 }; ::TDF_ERR result = static_cast<::TDF_ERR>(::TDF_GetOptionCodeInfo(tdf, code.c_str(), &info)); if (result != TDF_ERR_SUCCESS) { return q::error2q(::TDF::getError(result)); } q::K_ptr data(ktn(0, 6 + 12)); kK(data.get())[0 + 0] = ks(const_cast<S>(info.basicCode.szWindCode)); kK(data.get())[0 + 1] = ks(const_cast<S>(info.basicCode.szMarket)); kK(data.get())[0 + 2] = ks(const_cast<S>(info.basicCode.szCode)); kK(data.get())[0 + 3] = ks(const_cast<S>(info.basicCode.szENName)); kK(data.get())[0 + 4] = ks(const_cast<S>(Wind::encoder::GB18030_UTF8::encode(info.basicCode.szCNName).c_str())); kK(data.get())[0 + 5] = kg(info.basicCode.nType); kK(data.get())[6 + 0] = ks(const_cast<S>(info.szContractID)); kK(data.get())[6 + 1] = ks(const_cast<S>(info.szUnderlyingSecurityID)); kK(data.get())[6 + 2] = kc(info.chCallOrPut); kK(data.get())[6 + 3] = kd(q::date2q(info.nExerciseDate)); kK(data.get())[6 + 4] = kc(info.chUnderlyingType); kK(data.get())[6 + 5] = kc(info.chOptionType); kK(data.get())[6 + 6] = kc(info.chPriceLimitType); kK(data.get())[6 + 7] = ki(info.nContractMultiplierUnit); kK(data.get())[6 + 8] = kf(info.nExercisePrice); kK(data.get())[6 + 9] = kd(q::date2q(info.nStartDate)); kK(data.get())[6 + 10] = kd(q::date2q(info.nEndDate)); kK(data.get())[6 + 11] = kd(q::date2q(info.nExpireDate)); return data.release(); }
static int ProcessMessage(const FeedData *data) { static int sent = 0; K condvec; if (trades == NULL) { trades = create_trade_schema(); } if (quotes == NULL) { quotes = create_quote_schema(); } switch(data->type) { case FF_TRADE_MSG: js(&kK(trades)[0], ss(data->core.sym)); js(&kK(trades)[1], ss(data->core.exg)); ja(&kK(trades)[2], (void *) &data->msg.trade.size); ja(&kK(trades)[3], (void *) &data->msg.trade.volume); ja(&kK(trades)[4], (void *) &data->core.sequence); ja(&kK(trades)[5], (void *) &data->msg.trade.price); condvec = ktn(4, KC); memcpy(&kC(condvec)[0], &data->core.cond, 4); jk(&kK(trades)[6], condvec); break; case FF_QUOTE_MSG: js(&kK(quotes)[0], ss(data->core.sym)); js(&kK(quotes)[1], ss(data->core.exg)); ja(&kK(quotes)[2], (void *) &data->msg.quote.asksize); ja(&kK(quotes)[3], (void *) &data->msg.quote.bidsize); ja(&kK(quotes)[4], (void *) &data->msg.quote.askprice); ja(&kK(quotes)[5], (void *) &data->msg.quote.bidprice); ja(&kK(quotes)[6], (void *) &data->core.sequence); condvec = ktn(4, KC); memcpy(&kC(condvec)[0], &data->core.cond, 4); jk(&kK(quotes)[7], condvec); break; } if (++sent >= 10) { SendToKDB("quote", quotes); quotes = NULL; SendToKDB("trade", trades); trades = NULL; sent = 0; } return FEED_STATE; }
V *o=p-1; K(*f)(K,K); K k=0; if(VA(*o) && (f=DT[(L)*o].alt_funcs.verb_over))k=f(a,b); //k==0 just means not handled. Errors are not set to come from alt_funcs P(k,k) K u=0,v=0; K y=a?v=join(u=enlist(a),b):b; //oom u (TODO: need to unroll to 'x f/y' and 'f/y' to optimize?) K z=0,g=0; if(yt > 0){z=ci(y); GC;} if(yn == 0){if(VA(*o))z=LE; GC; } //Some verbs will handle this in alt_funcs K c=first(y),d;//mm/o //TODO: this reuse of g should be implemented in other adverbs if(0 >yt) DO(yn-1, d=c; if(!g)g=newK(ABS(yt),1); memcpy(g->k,((V)y->k)+(i+1)*bp(yt),bp(yt)); c=dv_ex(d,p-1,g); if(2==g->c){cd(g);g=0;} cd(d); if(!c) GC;) //TODO: oom err/mmo unwind above - oom-g if(0==yt) DO(yn-1, d=c; c=dv_ex(d,p-1,kK(y)[i+1]); cd(d); if(!c) GC;) //TODO: err/mmo unwind above z=c; cleanup: if(g)cd(g); if(u)cd(u); if(v)cd(v); R z; } Z K scanDyad(K a, V *p, K b) //k4 has 1 +\ 2 3 yield 3 6 instead of 1 3 6 { V *o=p-1; K(*f)(K,K); K k=0; if(VA(*o) && (f=DT[(L)*o].alt_funcs.verb_scan))k=f(a,b); //k==0 just means not handled. Errors are not set to come from alt_funcs P(k,k)
//Dictionary and Dictionary Entry utility functions and accessors // currently no guards for 0 inputs ... should this change? K DI(K d, I i){R kK(d)[i];} //dictionary index, yields entry
static int enc(K*k,lua_State *L) { switch (lua_type(L, -1)) { case LUA_TSTRING: { size_t len;const char *str = lua_tolstring(L,-1,&len);(*k)=kpn(str,len);R 1;} break; case LUA_TNUMBER: { F num = lua_tonumber(L,-1);(*k) = (num==floor(num))?kj((J)num):kf(num);R 1;} break; case LUA_TBOOLEAN: { (*k)=kb( lua_toboolean(L,-1) );R 1;} break; case LUA_TNIL: { (*k)=ktn(0,0);R 1;} break; case LUA_TTABLE: { double p; int max = 0; int items = 0; int t_integer = 0, t_number = 0, t_boolean = 0, t_other= 0; lua_pushnil(L); /* table, startkey */ while (lua_next(L, -2) != 0) { items++; /* table, key, value */ switch (lua_type(L, -1)) { case LUA_TNUMBER: t_number++; p = lua_tonumber(L,-1); t_integer += (floor(p) == p); break; case LUA_TBOOLEAN: t_boolean++; break; default: t_other++; break; /* or anything else */ }; if (lua_type(L, -2) == LUA_TNUMBER && (p = lua_tonumber(L, -2))) { /* Integer >= 1 ? */ if (floor(p) == p && p >= 1) { if (p > max) max = p; lua_pop(L, 1); continue; } } /* Must not be an array (non integer key) */ for (lua_pop(L,1); lua_next(L, -2) != 0; lua_pop(L,1)) ++items; max = 0; break; } lua_pushnil(L); if (max != items) { /* build K dictionary */ K keys = ktn(KS,items); K values = ktn(0,items); int n = 0; /* table, startkey */ while (lua_next(L, -2) != 0) { kS(keys)[n] = ss(lua_tostring(L, -2)); if(!enc(kK(values)+n,L))R 0; lua_pop(L,1); ++n; } *k = xD(keys,values); R 1; } /* build K list */ if(t_other || ((!!t_boolean)+(!!t_number)) > 1) { K a = ktn(0,items); while (lua_next(L, -2) != 0) { p = lua_tonumber(L, -2); if(!enc(kK(a)+LI(p),L))R 0; lua_pop(L, 1); } *k = a; R 1; } if(t_boolean) { K a = ktn(KB,items); while (lua_next(L, -2) != 0) { p = lua_tonumber(L, -2); kG(a)[LI(p)] = lua_toboolean(L,-1); lua_pop(L, 1); } *k = a; R 1; } if(t_number == t_integer) { K a = ktn(KJ,items); while (lua_next(L, -2) != 0) { p = lua_tonumber(L, -2); kJ(a)[LI(p)] = (int)floor(lua_tonumber(L,-1)); lua_pop(L, 1); } *k = a; R 1; } if(t_number) { K a = ktn(KF,items); while (lua_next(L, -2) != 0) { p = lua_tonumber(L, -2); kF(a)[LI(p)] = lua_tonumber(L,-1); lua_pop(L, 1); } *k = a; R 1; } *k = ktn(0,0); R 1; }; break; default: luaL_error(L, "Cannot serialise %s: %s", lua_typename(L, lua_type(L, -1)), "can't serialize type"); R 0; }; }
S ES(K d){ R *kS(kK(d)[0]);} //dictionary entry's symbol
R 0; } //Arthur says he doesn't use malloc or free. Andrei Moutchkine claims smallest unit is vm page (his truss says no malloc + add pages one at a time). //Arthur not using malloc is probably true. No strdup & related functions in binary's strings. Note: Skelton references "different allocator" not in \w report //This source would be improved by getting ridding of remaing malloc/calloc/realloc K cd(K a) { #ifdef DEBUG if(a && a->c <=0 ) { er(Tried to cd() already freed item) dd(tests) dd(a) dd(a->c) dd(a->t) dd(a->n) show(a); } #endif if(!a || --a->c) R a; #ifdef DEBUG DO(kreci, if(a==krec[i]){krec[i]=0; break; }) #endif if(7==a->t){ DO(-2+TYPE_SEVEN_SIZE,cd(kV(a)[2+i]))} //-4 special trick: don't recurse on V members. assumes sizeof S==K==V. (don't free CONTEXT or DEPTH) if(0==a->t || 5==a->t) DO(a->n, cd(kK(a)[a->n-i-1])) //repool in reverse, attempt to maintain order #ifdef DEBUG if(0)R 0; //for viewing K that have been over-freed #endif //assumes seven_type a->k is < PG I o=((size_t)a)&(PG-1);//file-mapped? 1: I k=sz(a->t,a->n), r=lsz(k); //assert file-maps have sizeof(V)==o and unpooled blocks never do (reasonable) if(sizeof(V)==o || r>KP_MAX)munmap(((V)a)-o,k+o); //(file-mapped or really big) do not go back into pool. else repool(a,r); R 0; } K ci(K a){if(a)a->c++; R a;} I bp(I t) {SW(ABS(t)){CSR(1, R sizeof(I)) CSR(2, R sizeof(F)) CSR(3, R sizeof(C)) CD: R sizeof(V); } } //Default 0/+-4/5/6/7 (assumes sizeof(K)==sizeof(S)==...) I sz(I t,I n){R 3*sizeof(I)+(7==t?TYPE_SEVEN_SIZE:n)*bp(t)+(3==ABS(t));} //not recursive. assert sz() > 0: Everything gets valid block for simplified munmap/(free)