int find_insert(Var lst, Var key) { /* find_insert(sortedlist,key) => index of first element in sortedlist > key. sortedlist is assumed to bem sorted in increasing order and the number returned is anywhere from 1 to length(sortedlist)+1, inclusive. */ /* returns -10 if an E_TYPE occurs */ Var compare; int r = lst.v.list[0].v.num, l=1, i; while(r >= l) { compare = value_compare(var_ref(key), var_ref(lst.v.list[i = ((r + l) / 2)] ) ); if(compare.type == TYPE_ERR) { free_var(compare); return -10; } if(compare.v.num < 0) { r = i - 1; } else { l = i + 1; } } return l; }
static package bf_sort(Var arglist, Byte next, void *vdata, Objid progr) { /* sort(list) => sorts and returns list. sort({1,3,2}) => {1,2,3} */ /* returns E_TYPE is list is not all the same type */ Var sorted = new_list(0), tmp; Var e; int i, l; e.type=TYPE_NONE; for(i = 1; i <= arglist.v.list[1].v.list[0].v.num; i++) { e = var_ref(arglist.v.list[1].v.list[i]); l = find_insert(sorted, e); if(l == -10) { free_var(arglist); free_var(sorted); free_var(e); return make_error_pack(E_TYPE); } tmp = listinsert(var_ref(sorted), var_ref(e), l); free_var(sorted); sorted = var_ref(tmp); free_var(tmp); } free_var(arglist); free_var(e); return make_var_pack(sorted); }
void fill_in_rt_consts(Var * env, DB_Version version) { Var v; v.type = TYPE_INT; v.v.num = (int) TYPE_ERR; env[SLOT_ERR] = var_ref(v); v.v.num = (int) TYPE_INT; env[SLOT_NUM] = var_ref(v); v.v.num = (int) _TYPE_STR; env[SLOT_STR] = var_ref(v); v.v.num = (int) TYPE_OBJ; env[SLOT_OBJ] = var_ref(v); v.v.num = (int) _TYPE_LIST; env[SLOT_LIST] = var_ref(v); if (version >= DBV_Float) { v.v.num = (int) TYPE_INT; env[SLOT_INT] = var_ref(v); v.v.num = (int) _TYPE_FLOAT; env[SLOT_FLOAT] = var_ref(v); } if (version >= DBV_Hash) { v.v.num = (int) _TYPE_HASH; env[SLOT_HASH] = var_ref(v); } }
static void insert_prop(Objid oid, int pos, Pval pval) { Pval *new_propval; Object *o; int i, nprops; nprops = dbpriv_count_properties(oid); new_propval = mymalloc(nprops * sizeof(Pval), M_PVAL); o = dbpriv_find_object(oid); for (i = 0; i < pos; i++) new_propval[i] = o->propval[i]; new_propval[pos] = pval; new_propval[pos].var = var_ref(pval.var); if (new_propval[pos].perms & PF_CHOWN) new_propval[pos].owner = o->owner; for (i = pos + 1; i < nprops; i++) new_propval[i] = o->propval[i - 1]; if (o->propval) myfree(o->propval, M_PVAL); o->propval = new_propval; }
void set_rt_env_obj(Var * env, int slot, Objid o) { Var v; v.type = TYPE_OBJ; v.v.obj = o; env[slot] = var_ref(v); }
enum error proto_make_listener(Var desc, int *fd, Var * canon, const char **name) { struct sockaddr_in address; int s, port, option = 1; static Stream *st = 0; if (!st) st = new_stream(20); if (desc.type != TYPE_INT) return E_TYPE; port = desc.v.num; s = socket(AF_INET, SOCK_STREAM, 0); if (s < 0) { log_perror("Creating listening socket"); return E_QUOTA; } if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &option, sizeof(option)) < 0) { log_perror("Setting listening socket options"); close(s); return E_QUOTA; } address.sin_family = AF_INET; address.sin_addr.s_addr = bind_local_ip; address.sin_port = htons(port); if (bind(s, (struct sockaddr *) &address, sizeof(address)) < 0) { enum error e = E_QUOTA; log_perror("Binding listening socket"); if (errno == EACCES) e = E_PERM; close(s); return e; } if (port == 0) { size_t length = sizeof(address); if (getsockname(s, (struct sockaddr *) &address, &length) < 0) { log_perror("Discovering local port number"); close(s); return E_QUOTA; } canon->type = TYPE_INT; canon->v.num = ntohs(address.sin_port); } else *canon = var_ref(desc); stream_printf(st, "port %d", canon->v.num); *name = reset_stream(st); *fd = s; return E_NONE; }
Var * copy_rt_env(Var * from, unsigned size) { unsigned i; Var *ret = new_rt_env(size); for (i = 0; i < size; i++) ret[i] = var_ref(from[i]); return ret; }
/* Remove_Duplicates - from Access_Denied@LambdaMOO. */ static package bf_remove_duplicates(Var arglist, Byte next, void *vdata, Objid progr) { Var r; int i; r = new_list(0); for (i = 1; i <= arglist.v.list[1].v.list[0].v.num; i++) r = setadd(r, var_ref(arglist.v.list[1].v.list[i])); free_var(arglist); return make_var_pack(r); }
static void finish_node(XMLdata *data) { XMLdata *parent = data->parent; Var element = data->element; Var body; Stream *s = data->body; body.type = TYPE_STR; if(s == NULL) { body.v.str = str_dup(""); } else { body.v.str = str_dup(reset_stream(s)); } element.v.list[3] = body; if(parent != NULL) { Var pelement = parent->element; pelement.v.list[4] = listappend(pelement.v.list[4], var_ref(element)); } }
/** * Parse an XML string into a nested list. * The second parameter indicates if body text (text within XML tags) * should show up among the children of the tag or in its own * section. * * See documentation (ext-xml.README) for examples. */ static package parse_xml(const char *data, int bool_stream) { /* * FIXME: Feed expat smaller chunks of the string and * check for task timeout between chunks * */ int decoded_length; const char *decoded; package result; XML_Parser parser = XML_ParserCreate(NULL); XMLdata *root = new_node(NULL, ""); XMLdata *child = root; decoded_length = strlen(data); decoded = data; XML_SetUserData(parser, &child); XML_SetElementHandler(parser, xml_startElement, xml_endElement); if(bool_stream) { XML_SetCharacterDataHandler(parser, xml_streamCharacterDataHandler); } else { XML_SetCharacterDataHandler(parser, xml_characterDataHandler); } if (!XML_Parse(parser, decoded, decoded_length, 1)) { Var r; r.type = TYPE_INT; r.v.num = XML_GetCurrentByteIndex(parser); flush_nodes(child); result = make_raise_pack(E_INVARG, XML_ErrorString(XML_GetErrorCode(parser)), r); } else { finish_node(root); result = make_var_pack(var_ref(root->element.v.list[4].v.list[1])); free_node(root); } XML_ParserFree(parser); return result; }
Var server_version_full(Var arg) { Var r; const char *s; Var *tree; if (!version_structure) { init_version_structure(); } if (arg.type != TYPE_STR || arg.v.str[0] == '\0' ) { r.type = TYPE_LIST; r.v.list = version_structure; return var_ref(r); } s = arg.v.str; tree = version_structure; for (;;) { /* invariants: * s is a nonempty string; * tree has at least one string or {string,_} pair */ int i = tree[0].v.num; const char *e = s; while (*e != '/' && *++e != '\0'); do { --i; ++tree; switch (tree[0].type) { default: break; case TYPE_STR: if (memo_strlen(tree[0].v.str) == e - s && strncmp(tree[0].v.str, s, e - s) == 0) goto found; break; case TYPE_LIST: if (tree[0].v.list[0].v.num == 2 && tree[0].v.list[1].type == TYPE_STR && memo_strlen(tree[0].v.list[1].v.str) == e - s && strncmp(tree[0].v.list[1].v.str, s, e - s) == 0) { if (tree[0].v.list[0].v.num > 1) tree = tree[0].v.list + 2; else tree = tree[0].v.list + 1; goto found; } break; } } while (i > 0); break; found: s = (*e != '\0' ? e+1 : e); /* skip trailing slash */ if (*s == '\0') return var_ref(tree[0]); if (tree[0].type != TYPE_LIST) break; tree = tree[0].v.list; if (tree[0].v.num <= 0 || (tree[1].type != TYPE_STR && tree[1].type != TYPE_LIST)) break; } r.type = TYPE_ERR; r.v.err = E_INVARG; return r; }