static void inet_pton(TP, const char *buf, int len, __u32 *addr) { char *p = (char *)buf; int i = 0; __u32 val = 0; *addr = 0; while (*p && p < buf + len && i < 4) { if (*p == '.' || !*p) { if (val > 255) tp_raise(tp_None, "ValueError: number > 255 in IP address", tp_None); *addr += (val << ((i++) << 3)); val = 0; } else { if (*p < '0' || *p > '9') tp_raise(tp_None, "ValueError: bad char in IP address, digit expected", tp_None); val = val * 10 + *p - '0'; } p++; } if (!*p) { if (i == 3) *addr += (val << ((i++) << 3)); else tp_raise(tp_None, "ValueError: bad IP address", tp_None); } }
tp_obj tp_len(tp_vm *tp, tp_obj self) { double len = _tp_len(self); if (-1.0 == len) { tp_raise(None, "tp_len(%s)", STR(self)); } return tp_number(tp, len); }
/* Socket recv method. * * data="<html><head><title>Preved!!!</title></head><body>Example.</body></html>" * s.recv(data) * or: * s.recv(data, 20) # Send just 20 bytes */ static tp_obj kolibri_recv(TP) { tp_obj self = TP_TYPE(TP_DICT); __u32 datalen = TP_DEFAULT(tp_False).number.val; __u32 s; __u8 c; __u8 *buf, *p; __u32 buf_size; __u32 bytes_read = 0; int i; GET_SOCKET_DESCRIPTOR(self, s); if (datalen) buf_size = datalen; else buf_size = 2048; if (!(buf = malloc(datalen))) tp_raise(tp_None, "Cannot allocate buffer for received data", tp_None); p = buf; while (__menuet__read_socket(s, &c) && bytes_read < buf_size) { *p++ = c; bytes_read++; if (bytes_read >= buf_size && !datalen) { buf_size += 1024; buf = realloc(buf, buf_size); } } return tp_string_n(buf, bytes_read); }
/* Socket listen method. * * Example: * s.listen('10.10.1.1', 5000) */ tp_obj kolibri_listen(TP) { tp_obj self = TP_TYPE(TP_DICT); tp_obj remote_addr_obj = TP_OBJ(); __u32 remote_addr; __u32 remote_port = (__u32)TP_TYPE(TP_NUMBER).number.val; __u32 local_port = tp_get(tp, self, tp_string("local_port")).number.val; __u32 socktype = (__u32)tp_get(tp, self, tp_string("type")).number.val; int s = -1; /* Socket descriptor */ if (socktype != SOCK_STREAM) tp_raise(tp_None, "IOError: attempt to listen on non-TCP socket", tp_None); if (remote_addr_obj.type == TP_NUMBER) remote_addr = remote_addr_obj.number.val; else if (remote_addr_obj.type == TP_STRING) inet_pton(tp, (const char *)remote_addr_obj.string.val, remote_addr_obj.string.len, &remote_addr); if ((s = __menuet__open_TCP_socket(local_port, remote_port, remote_addr, 0)) >= 0) { tp_set(tp, self, tp_string("socket"), tp_number(s)); return tp_True; } else return tp_False; }
tp_obj tp_str_index(TP) { tp_obj s = TP_OBJ(); tp_obj v = TP_OBJ(); int n = _tp_str_index(s,v); if (n >= 0) { return tp_number(n); } tp_raise(tp_None,tp_string("(tp_str_index) ValueError: substring not found")); }
tp_obj tp_ord(TP) { tp_obj s = TP_STR(); if (s.string.len != 1) { tp_raise(tp_None,tp_string("(tp_ord) TypeError: ord() expected a character")); } return tp_number((unsigned char)s.string.val[0]); }
int tp_cmp(TP,tp_obj a, tp_obj b) { if (a.type != b.type) { return a.type-b.type; } switch(a.type) { case TP_NONE: return 0; case TP_NUMBER: return _tp_sign(a.number.val-b.number.val); case TP_STRING: { int l = _tp_min(a.string.len,b.string.len); int v = memcmp(a.string.val,b.string.val,l); if (v == 0) { v = a.string.len-b.string.len; } return v; } case TP_LIST: { int n,v; for(n=0;n<_tp_min(a.list.val->len,b.list.val->len);n++) { tp_obj aa = a.list.val->items[n]; tp_obj bb = b.list.val->items[n]; if (aa.type == TP_LIST && bb.type == TP_LIST) { v = aa.list.val-bb.list.val; } else { v = tp_cmp(tp,aa,bb); } if (v) { return v; } } return a.list.val->len-b.list.val->len; } case TP_DICT: return a.dict.val - b.dict.val; case TP_FNC: return a.fnc.info - b.fnc.info; case TP_DATA: return (char*)a.data.val - (char*)b.data.val; } tp_raise(0,tp_string("(tp_cmp) TypeError: ?")); }
/* Function: tp_iter * Iterate through a list or dict. * * If self is a list/string/dictionary, this will iterate over the * elements/characters/keys respectively, if k is an increasing index * starting with 0 up to the length of the object-1. * * In the case of a list of string, the returned items will correspond to the * item at index k. For a dictionary, no guarantees are made about the order. * You also cannot call the function with a specific k to get a specific * item -- it is only meant for iterating through all items, calling this * function len(self) times. Use <tp_get> to retrieve a specific item, and * <tp_len> to get the length. * * Parameters: * self - The object over which to iterate. * k - You must pass 0 on the first call, then increase it by 1 after each call, * and don't call the function with k >= len(self). * * Returns: * The first (k = 0) or next (k = 1 .. len(self)-1) item in the iteration. */ tp_obj tp_iter(TP,tp_obj self, tp_obj k) { int type = self.type; if (type == TP_LIST || type == TP_STRING) { return tp_get(tp,self,k); } if (type == TP_DICT && k.type == TP_NUMBER) { return self.dict.val->items[_tp_dict_next(tp,self.dict.val)].key; } tp_raise(tp_None,tp_string("(tp_iter) TypeError: iteration over non-sequence")); }
tp_obj tp_iter(TP,tp_obj self, tp_obj k) { int type = obj_type(self); if (type == TP_LIST || type == TP_STRING) { return tp_get(tp,self,k); } if (type == TP_DICT && obj_type(k) == TP_NUMBER) { return tp_dict_val(self)->items[_tp_dict_next(tp, tp_dict_val(self))].key; } tp_raise(None,"tp_iter(%s,%s)",STR(self),STR(k)); }
tp_obj tp_istype(TP) { tp_obj v = TP_OBJ(); char *t = TP_STR(); if (strcmp("string",t) == 0) { return tp_number(v.type == TP_STRING); } if (strcmp("list",t) == 0) { return tp_number(v.type == TP_LIST); } if (strcmp("dict",t) == 0) { return tp_number(v.type == TP_DICT); } if (strcmp("number",t) == 0) { return tp_number(v.type == TP_NUMBER); } tp_raise(None,"is_type(%s,%s)",STR(v),t); }
tp_obj tp_copy(TP) { tp_obj r = TP_OBJ(); int type = r.type; if (type == TP_LIST) { return _tp_list_copy(tp,r); } else if (type == TP_DICT) { return _tp_dict_copy(tp,r); } tp_raise(tp_None,tp_string("(tp_copy) TypeError: ?")); }
tp_obj tp_copy(TP) { tp_obj r = TP_OBJ(); int type = r.type; if (type == TP_LIST) { return _tp_list_copy(tp,r); } else if (type == TP_DICT) { return _tp_dict_copy(tp,r); } tp_raise(None,"tp_copy(%s)",STR(r)); }
tp_obj tp_iter(TP,tp_obj self, tp_obj k) { int type = self.type; if (type == TP_LIST || type == TP_STRING) { return tp_get(tp,self,k); } if (type == TP_DICT && k.type == TP_NUMBER) { return self.dict.val->items[_tp_dict_next(tp,self.dict.val)].key; } tp_raise(tp_None,"tp_iter(%s,%s)",TP_CSTR(self),TP_CSTR(k)); }
tp_obj tp_save(TP) { char *fname = TP_STR(); tp_obj v = TP_OBJ(); FILE *f; f = fopen(fname,"wb"); if (!f) { tp_raise(None,"tp_save(%s,...)",fname); } fwrite(v.string.val,v.string.len,1,f); fclose(f); return None; }
tp_obj tp_save(TP) { char fname[256]; tp_cstr(tp,TP_STR(),fname,256); tp_obj v = TP_OBJ(); FILE *f; f = fopen(fname,"wb"); if (!f) { tp_raise(tp_None,tp_string("(tp_save) IOError: ?")); } fwrite(v.string.val,v.string.len,1,f); fclose(f); return tp_None; }
tp_obj tp_float(TP) { tp_obj v = TP_OBJ(); int ord = TP_DEFAULT(tp_number(0)).number.val; int type = v.type; if (type == TP_NUMBER) { return v; } if (type == TP_STRING) { if (strchr(STR(v),'.')) { return tp_number(atof(STR(v))); } return(tp_number(strtol(STR(v),0,ord))); } tp_raise(None,"tp_float(%s)",STR(v)); }
tp_obj tp_istype(TP) { tp_obj v = TP_OBJ(); tp_obj t = TP_STR(); if (tp_cmp(tp,t,tp_string("string")) == 0) { return tp_number(v.type == TP_STRING); } if (tp_cmp(tp,t,tp_string("list")) == 0) { return tp_number(v.type == TP_LIST); } if (tp_cmp(tp,t,tp_string("dict")) == 0) { return tp_number(v.type == TP_DICT); } if (tp_cmp(tp,t,tp_string("number")) == 0) { return tp_number(v.type == TP_NUMBER); } if (tp_cmp(tp,t,tp_string("fnc")) == 0) { return tp_number(v.type == TP_FNC && (v.fnc.ftype&2) == 0); } if (tp_cmp(tp,t,tp_string("method")) == 0) { return tp_number(v.type == TP_FNC && (v.fnc.ftype&2) != 0); } tp_raise(tp_None,tp_string("(is_type) TypeError: ?")); }
tp_obj tp_len(TP,tp_obj self) { int type = self.type; if (type == TP_STRING) { return tp_number(self.string.len); } else if (type == TP_DICT) { return tp_number(self.dict.val->len); } else if (type == TP_LIST) { return tp_number(self.list.val->len); } tp_raise(tp_None,"tp_len(%s)",TP_CSTR(self)); }
tp_obj tp_load(TP) { char *fname = TP_STR(); struct stat stbuf; stat(fname, &stbuf); long l = stbuf.st_size; FILE *f; f = fopen(fname,"rb"); if (!f) { tp_raise(None,"tp_load(%s)",fname); } tp_obj r = tp_string_t(tp,l); char *s = r.string.val; fread(s,1,l,f); fclose(f); return tp_track(tp,r); }
/* Function: tp_has * Checks if an object contains a key. * * Returns tp_True if self[k] exists, tp_False otherwise. */ tp_obj tp_has(TP,tp_obj self, tp_obj k) { int type = self.type; if (type == TP_DICT) { if (_tp_dict_find(tp,self.dict.val,k) != -1) { return tp_True; } return tp_False; } else if (type == TP_STRING && k.type == TP_STRING) { return tp_number(_tp_str_index(self,k)!=-1); } else if (type == TP_LIST) { return tp_number(_tp_list_find(tp,self.list.val,k)!=-1); } tp_raise(tp_None,tp_string("(tp_has) TypeError: iterable argument required")); }
/* Function: tp_len * Returns the length of an object. * * Returns the number of items in a list or dict, or the length of a string. */ tp_obj tp_len(TP,tp_obj self) { int type = self.type; if (type == TP_STRING) { return tp_number(self.string.len); } else if (type == TP_DICT) { return tp_number(self.dict.val->len); } else if (type == TP_LIST) { return tp_number(self.list.val->len); } tp_raise(tp_None,tp_string("(tp_len) TypeError: len() of unsized object")); }
tp_obj tp_has(tp_vm *tp, tp_obj self, tp_obj k) { int type = obj_type(self); if (type == TP_DICT) { if (_tp_dict_find(tp, tp_dict_val(self), k) != -1) { return True; } return False; } else if (type == TP_STRING && obj_type(k) == TP_STRING) { char *p = strstr(STR(self),STR(k)); return tp_number(tp, p != 0); } else if (type == TP_LIST) { return tp_number(tp, _tp_list_find(tp,tp_list_val(self),k)!=-1); } tp_raise(None,"tp_has(%s,%s)",STR(self),STR(k)); }
tp_obj tp_float(TP) { tp_obj v = TP_OBJ(); int ord = TP_DEFAULT(tp_number(0)).number.val; int type = v.type; if (type == TP_NUMBER) { return v; } if (type == TP_STRING && v.string.len < 32) { char s[32]; memset(s,0,v.string.len+1); memcpy(s,v.string.val,v.string.len); if (strchr(s,'.')) { return tp_number(atof(s)); } return(tp_number(strtol(s,0,ord))); } tp_raise(tp_None,tp_string("(tp_float) TypeError: ?")); }
tp_obj tp_has(TP,tp_obj self, tp_obj k) { int type = self.type; if (type == TP_DICT) { if (_tp_dict_find(tp,self.dict.val,k) != -1) { return tp_True; } return tp_False; } else if (type == TP_STRING && k.type == TP_STRING) { char *p = strstr(TP_CSTR(self),TP_CSTR(k)); return tp_number(p != 0); } else if (type == TP_LIST) { return tp_number(_tp_list_find(tp,self.list.val,k)!=-1); } tp_raise(tp_None,"tp_has(%s,%s)",TP_CSTR(self),TP_CSTR(k)); }
tp_obj tp_mul(tp_vm *tp, tp_obj a, tp_obj b) { if (obj_type(a) == TP_NUMBER && obj_type(a) == obj_type(b)) { return tp_number(tp, tp_number_val(a) * tp_number_val(b)); } else if (obj_type(a) == TP_STRING && obj_type(b) == TP_NUMBER) { int al = tp_str_len(a); int n = tp_number_val(b); tp_obj r = tp_string_t(tp,al*n); char *s = tp_str_val(r); int i; for (i=0; i<n; i++) { memcpy(s+al*i, tp_str_val(a),al); } return tp_track(tp,r); } tp_raise(None,"tp_mul(%s,%s)",STR(a),STR(b)); }
tp_obj tp_mul(TP,tp_obj a, tp_obj b) { if (a.type == TP_NUMBER && a.type == b.type) { return tp_number(a.number.val*b.number.val); } else if (a.type == TP_STRING && b.type == TP_NUMBER) { int al = a.string.len; int n = b.number.val; tp_obj r = tp_string_t(tp,al*n); char *s = r.string.info->s; int i; for (i=0; i<n; i++) { memcpy(s+al*i,a.string.val,al); } return tp_track(tp,r); } tp_raise(tp_None,"tp_mul(%s,%s)",TP_CSTR(a),TP_CSTR(b)); }
int _tp_lookup_(TP,tp_obj self, tp_obj k, tp_obj *meta, int depth) { int n = _tp_dict_find(tp,self.dict.val,k); if (n != -1) { *meta = self.dict.val->items[n].val; return 1; } depth--; if (!depth) { tp_raise(0,tp_string("(tp_lookup) RuntimeError: maximum lookup depth exceeded")); } if (self.dict.dtype && self.dict.val->meta.type == TP_DICT && _tp_lookup_(tp,self.dict.val->meta,k,meta,depth)) { if (self.dict.dtype == 2 && meta->type == TP_FNC) { *meta = tp_fnc_new(tp,meta->fnc.ftype|2, meta->fnc.cfnc,meta->fnc.info->code, self,meta->fnc.info->globals); } return 1; } return 0; }
tp_obj tp_load(TP) { FILE *f; long l; tp_obj r; char *s; char const *fname = TP_STR(); struct stat stbuf; stat(fname, &stbuf); l = stbuf.st_size; f = fopen(fname,"rb"); if (!f) { tp_raise(tp_None,"tp_load(%s)",fname); } r = tp_string_t(tp,l); s = r.string.info->s; fread(s,1,l,f); fclose(f); return tp_track(tp,r); }
tp_obj tp_add(TP,tp_obj a, tp_obj b) { if (a.type == TP_NUMBER && a.type == b.type) { return tp_number(a.number.val+b.number.val); } else if (a.type == TP_STRING && a.type == b.type) { int al = a.string.len, bl = b.string.len; tp_obj r = tp_string_t(tp,al+bl); char *s = r.string.info->s; memcpy(s,a.string.val,al); memcpy(s+al,b.string.val,bl); return tp_track(tp,r); } else if (a.type == TP_LIST && a.type == b.type) { tp_obj r; tp_params_v(tp,1,a); r = tp_copy(tp); tp_params_v(tp,2,r,b); tp_extend(tp); return r; } tp_raise(tp_None,tp_string("(tp_add) TypeError: ?")); }
tp_obj tp_add(tp_vm *tp, tp_obj a, tp_obj b) { if (obj_type(a) == TP_NUMBER && obj_type(a) == obj_type(b)) { return tp_number(tp, tp_number_val(a) + tp_number_val(b)); } else if (obj_type(a) == TP_STRING && obj_type(a) == obj_type(b)) { int al = tp_str_len(a), bl = tp_str_len(b); tp_obj r = tp_string_t(tp,al+bl); char *s = tp_str_val(r); memcpy(s, tp_str_val(a),al); memcpy(s+al, tp_str_val(b),bl); return tp_track(tp,r); } else if (obj_type(a) == TP_LIST && obj_type(a) == obj_type(b)) { tp_obj r; tp_params_v(tp,1,a); r = tp_copy(tp); tp_params_v(tp,2,r,b); tp_extend(tp); return r; } tp_raise(None,"tp_add(%s,%s)",STR(a),STR(b)); }