void show(void) { size_t s; int i; Element e; printf("读取列表元素,列表%s,元素数量 = %zu\n", list_isempty(al) ? "为空" : "不空", (s = list_size(al))); printf("使用位置索引随机访问元素:\n"); for (i = 0; i < s; i++) { e = list_get(al, i); printf("%2d) \"%s\"\n", i, POINTOF(e, char)); // String类型的元素不能用VALUEOF()宏 free(e); // 获取的元素值用完必须free } printf("Ok!\n"); printf("使用正向迭代器迭代访问元素:\n"); it_reset(fwd); i = 0; while ((e = it_next(fwd))) { printf("%2d) \"%s\"\n", i++, (char *)e); free(e); } printf("Ok!\n"); printf("使用反向迭代器迭代访问元素:\n"); it_reset(bwd); i = list_size(al); while ((e = it_next(bwd))) { printf("%2d) \"%s\"\n", --i, POINTOF(e, char)); free(e); } printf("Ok!\n"); }
int top_publish(char *name, char *message, RpcEndpoint *ep) { int ret = 0; Topic *st; if (tshm_get(topicTable, name, (void **)&st)) { ret = 1; pthread_mutex_lock(&(st->lock)); if (ll_size(st->regAUs) > 0L) { Iterator *iter; iter = ll_it_create(st->regAUs); if (iter) { Event *event; event = ev_create(name, message, ep, ll_size(st->regAUs)); if (event) { unsigned long id; while (it_hasNext(iter)) { (void) it_next(iter, (void **)&id); au_publish(id, event); } } it_destroy(iter); } } pthread_mutex_unlock(&(st->lock)); } return ret; }
static void exec_pop( gravm_runstack_t *self) { pop(self); if(self->top != NULL) { if(it_next(&self->top->out_it)) self->top->out_cur = self->top->out_it.it.element; else self->top->ip = self->top->out_nextip; } }
static void exec_loop_edge_prepare( gravm_runstack_t *self) { int ret; assert(self->cb->edge_prepare != NULL); assert(self->top->out_cur != NULL); ret = self->cb->edge_prepare(self->user, self->top->out_cur->id, self->top->user); self->invoked = true; switch(ret) { case GRAVM_RS_SUCCESS: if(it_next(&self->top->out_it)) self->top->out_cur = self->top->out_it.it.element; else self->top->ip++; return; EXEC_EXCEPTION_CASES } }
int main(void) { printf("初始化LinkedList及其正反两个方向的迭代器..."); al = list_create(string, LinkedList, NULL); fwd = list_iterator(al, Forward); bwd = list_iterator(al, Reverse); printf("Ok!\n"); printf("TEST1:空列表时的查询\n"); show(); cont(); printf("TEST2: 用append添加一个元素\n"); appends(1); show(); cont(); printf("TEST3: 用remove_at删除一个元素\n"); printf("删除了%zu个元素\n", list_remove_at(al, 0)); show(); cont(); printf("TEST4: 用insert从头部开始连续添加18个元素\n"); inserts(18, 0); show(); int pos = 0; int from = -1; while ((pos = list_search(al, from, Forward, "South Korea", string, 11)) != -1) { printf("正向搜索所有韩国: %d\n", pos); from = pos + 1; } from = -1; while ((pos = list_search(al, from, Reverse, "Brazil", string, 6)) != -1) { printf("反向搜索所有巴西: %d\n", pos); from = pos - 1; } cont(); printf("TEST5: 用remove删除所有Brazil\n"); list_remove(al, "Brazil", string, 6); show(); cont(); printf("TEST6: 用removeall删除所有元素\n"); list_removeall(al); show(); cont(); printf("TEST7: 用push连续添加12个元素后进行递增快速排序\n"); int i, j; for (i = 0; i < 12; i++) { j = rand() % 16; list_push(al, nations[j], string, strlen(nations[j])); } printf("排序前:\n"); type(); printf("排序后:\n"); list_qsort(al, Asc); type(); printf("二分搜索找韩国: %d\n", list_bi_search(al, "South Korea", string, strlen("South Korea"))); printf("二分搜索找中国: %d\n", list_bi_search(al, "中华人民共和国", string, strlen("中华人民共和国"))); cont(); printf("TEST8: 用enqueue连续添加12个元素后进行递减插入排序\n"); for (i = 0; i < 12; i++) { j = rand() % 16; list_enqueue(al, nations[j], string, strlen(nations[j])); } printf("排序前:\n"); type(); printf("排序后:\n"); list_isort(al, Desc); type(); printf("二分搜索找日本: %d\n", list_bi_search(al, "Japan", string, 5)); printf("二分搜索找台湾: %d\n", list_bi_search(al, "中华民国", string, strlen("中华民国"))); printf("反向排列所有元素\n"); list_reverse(al); type(); printf("二分搜索找韩国: %d\n", list_bi_search(al, "South Korea", string, strlen("South Korea"))); printf("二分搜索找中国: %d\n", list_bi_search(al, "中华人民共和国", string, strlen("中华人民共和国"))); printf("二分搜索找日本: %d\n", list_bi_search(al, "Japan", string, 5)); printf("二分搜索找台湾: %d\n", list_bi_search(al, "中华民国", string, strlen("中华民国"))); cont(); printf("TEST9: 用迭代器迭代删除所有元素\n"); Iterator delit = list_iterator(al, Forward); Element ele = NULL; while ((ele = it_next(delit))) { it_remove(delit); printf("删除元素:\"%s\"\n", POINTOF(ele, char)); free(ele); } type(); cont(); printf("TEST10: 模拟堆栈\n"); printf("连续PUSH三次:\n"); j = rand() % 16; list_push(al, nations[j], string, strlen(nations[j])); type(); j = rand() % 16; list_push(al, nations[j], string, strlen(nations[j])); type(); j = rand() % 16; list_push(al, nations[j], string, strlen(nations[j])); type(); printf("用stacktop读取栈顶元素:"); ele = list_stacktop(al); printf(" \"%s\"\n", POINTOF(ele, char)); free(ele); printf("用pop弹空堆栈:\n"); ele = list_pop(al); printf("\"%s\"\n", POINTOF(ele, char)); free(ele); ele = list_pop(al); printf("\"%s\"\n", POINTOF(ele, char)); free(ele); ele = list_pop(al); printf("\"%s\"\n", POINTOF(ele, char)); free(ele); type(); cont(); printf("TEST11: 模拟队列\n"); printf("连续enqueue三次:\n"); j = rand() % 16; list_enqueue(al, nations[j], string, strlen(nations[j])); type(); j = rand() % 16; list_enqueue(al, nations[j], string, strlen(nations[j])); type(); j = rand() % 16; list_enqueue(al, nations[j], string, strlen(nations[j])); type(); printf("用queuehead读取栈顶元素:"); ele = list_queuehead(al); printf(" \"%s\"\n", POINTOF(ele, char)); free(ele); printf("用dequeue全部出队:\n"); ele = list_dequeue(al); printf("\"%s\"\n", POINTOF(ele, char)); free(ele); ele = list_dequeue(al); printf("\"%s\"\n", POINTOF(ele, char)); free(ele); ele = list_dequeue(al); printf("\"%s\"\n", POINTOF(ele, char)); free(ele); type(); cont(); printf("TEST12: 两个列表相加\n"); Container list2 = list_create(string, LinkedList, NULL); appends(9); printf("原列表:\n"); type(); printf("加上一个空列表:\n"); list_plus(al, list2); type(); printf("加上一个有9个元素的列表:\n"); for (i = 0; i < 9; i++) { j = rand() % 16; list_append(list2, nations[j], string, strlen(nations[j])); } list_plus(al, list2); type(); cont(); printf("再减去这个列表:\n"); list_minus(al, list2); type(); printf("再减去一个空列表:\n"); Container empty = list_create(string, LinkedList, NULL); list_minus(al, empty); type(); cont(); printf("添加到18个元素后再进行retain操作,类似取交集\n"); appends(18); printf("原列表:\n"); type(); printf("list2:\n"); for (i = 0; i < 9; i++) { ele = list_get(list2, i); printf("%s, ", POINTOF(ele, char)); free(ele); } printf("\n"); list_retain(al, list2); printf("retain后:\n"); type(); printf("retain一个空列表:\n"); list_retain(al, empty); type(); printf("FIN: 销毁列表和迭代器..."); it_destroy(fwd); it_destroy(bwd); list_destroy(al); list_destroy(list2); list_destroy(empty); printf("Ok!\n"); return 0; }
int main(int argc, char *argv[]) { LinkedList *ll = NULL; TreeSet *ts = NULL; char *sp; char pattern[4096]; RegExp *reg; Iterator *it; if (argc < 2) { fprintf(stderr, "Usage: ./fileCrawler pattern [dir] ...\n"); return -1; } /* * convert bash expression to regular expression and compile */ cvtPattern(pattern, argv[1]); if ((reg = re_create()) == NULL) { fprintf(stderr, "Error creating Regular Expression Instance\n"); return -1; } if (! re_compile(reg, pattern)) { char eb[4096]; re_status(reg, eb, sizeof eb); fprintf(stderr, "Compile error - pattern: `%s', error message: `%s'\n", pattern, eb); re_destroy(reg); return -1; } /* * create linked list and treeset */ if ((ll = ll_create()) == NULL) { fprintf(stderr, "Unable to create linked list\n"); goto done; } if ((ts = ts_create(scmp)) == NULL) { fprintf(stderr, "Unable to create tree set\n"); goto done; } /* * populate linked list */ if (argc == 2) { if (! processDirectory(".", ll, 1)) goto done; } else { int i; for (i = 2; i < argc; i++) { if (! processDirectory(argv[i], ll, 1)) goto done; } } /* * for each directory in the linked list, apply regular expression */ while (ll_removeFirst(ll, (void **)&sp)) { int stat = applyRe(sp, reg, ts); free(sp); if (! stat) break; } /* * create iterator to traverse files matching pattern in sorted order */ if ((it = ts_it_create(ts)) == NULL) { fprintf(stderr, "Unable to create iterator over tree set\n"); goto done; } while (it_hasNext(it)) { char *s; (void) it_next(it, (void **)&s); printf("%s\n", s); } it_destroy(it); /* * cleanup after ourselves so there are no memory leaks */ done: if (ll != NULL) ll_destroy(ll, free); if (ts != NULL) ts_destroy(ts, free); re_destroy(reg); return 0; }
static void _rt_run(struct _rt_invocation* inv) { struct _rt_stack* sp = inv->top->sp; while(1) { int tmp; switch(*inv->top->pc++) { case OP_NOOP: break; case OP_DEBUG: break; case OP_POP: sp++; break; case OP_ADD: if(_rt_num(inv,sp) || _rt_num(inv,sp + 1)) break; sp[1].num += sp[0].num; sp++; break; case OP_SUB: if(_rt_num(inv,sp) || _rt_num(inv,sp + 1)) break; sp[1].num -= sp[0].num; sp++; break; case OP_MUL: if(_rt_num(inv,sp) || _rt_num(inv,sp + 1)) break; sp[1].num *= sp[0].num; sp++; break; case OP_DIV: if(_rt_num(inv,sp) || _rt_num(inv,sp + 1) || sp->num == 0) break; sp[1].num /= sp[0].num; sp++; break; case OP_NOT: sp->num = _rt_test(sp) == 0; sp->type = STACK_NUM; break; case OP_NEG: if(_rt_num(inv,sp)) break; sp->num *= -1; break; case OP_EQ: sp[1].num = _rt_equal(inv,sp,sp + 1); sp[1].type = STACK_NUM; sp++; break; case OP_NE: sp[1].num = _rt_equal(inv,sp,sp + 1) == 0; sp[1].type = STACK_NUM; sp++; break; case OP_GE: sp[1].num = _rt_compare(inv,sp,sp + 1) >= 0; sp++; break; case OP_GT: sp[1].num = _rt_compare(inv,sp,sp + 1) > 0; sp++; break; case OP_LE: sp[1].num = _rt_compare(inv,sp,sp + 1) <= 0; sp++; break; case OP_LT: sp[1].num = _rt_compare(inv,sp,sp + 1) < 0; sp++; break; case OP_BNZ: // emit Is (branch forward conditional) tmp = *((ushort*)inv->top->pc); inv->top->pc += sizeof(ushort); if(_rt_test(sp)) inv->top->pc += tmp; sp++; case OP_BZ: // emit Is (branch forward conditional) tmp = *((ushort*)inv->top->pc); inv->top->pc += sizeof(ushort); if(_rt_test(sp) == 0) inv->top->pc += tmp; sp++; break; case OP_BR: // emit Is (branch forward) tmp = *((ushort*)inv->top->pc); inv->top->pc += tmp + sizeof(ushort); break; case OP_LOOP: // JIT-HOOK // emit Is (branch back) tmp = *((ushort*)inv->top->pc); inv->top->pc -= tmp - sizeof(ushort); break; case OP_ZLOOP: tmp = *((ushort*)inv->top->pc); inv->top->pc += sizeof(ushort); if(_rt_test(sp) == 0) inv->top->pc -= tmp; sp++; break; case OP_NZLOOP: tmp = *((ushort*)inv->top->pc); inv->top->pc += sizeof(ushort); if(_rt_test(sp)) inv->top->pc -= tmp; sp++; break; case OP_FREE: // emit Ic2 (byte,byte) tmp = *inv->top->pc++; while(tmp-- > 0) _rt_free(inv,&inv->top->vars[tmp + *inv->top->pc]); inv->top->pc++; break; case OP_NULL: // remove sp--; sp->type = STACK_NULL; break; case OP_IMM: // emit II (imm short) sp--; sp->type = STACK_NUM; sp->num = *((short*)inv->top->pc); inv->top->pc += sizeof(short); break; case OP_STR: // emit Is sp--; sp->type = STACK_RO_PTR; sp->single_ptr = inv->top->code->strings; st_move(inv->t,&sp->single_ptr,inv->top->pc,sizeof(ushort)); inv->top->pc += sizeof(ushort); break; case OP_OBJ: sp--; sp->type = STACK_OBJ; sp->ptr = sp->obj = inv->top->object; cle_skip_header(inv->hdl->inst,&sp->ptr); break; case OP_NEW: tmp = *((ushort*)inv->top->pc); inv->top->pc += sizeof(ushort); sp--; // if(cle_goto_object_cdat(inv->hdl->inst,inv->top->pc,tmp,&sp->obj)) if (1) _rt_error(inv,__LINE__); else { inv->top->pc += tmp; if(_rt_new_obj(inv,sp)) _rt_error(inv,__LINE__); } break; case OP_CLONE: if(sp->type != STACK_OBJ) _rt_error(inv,__LINE__); else if(_rt_new_obj(inv,sp)) _rt_error(inv,__LINE__); break; case OP_ID: sp--; sp->type = STACK_OBJ; sp->obj = inv->top->object; _rt_type_id(inv,sp); break; case OP_IDO: _rt_type_id(inv,sp); break; case OP_FIND: inv->top->pc++; if(sp->type == STACK_PTR || sp->type == STACK_RO_PTR) { if(cle_goto_object(inv->hdl->inst,sp->single_ptr,&sp->obj)) sp->type = STACK_NULL; else { sp->ptr = sp->obj; cle_skip_header(inv->hdl->inst,&sp->ptr); sp->type = STACK_OBJ; } } else _rt_error(inv,__LINE__); break; case OP_IT: inv->top->pc++; sp--; switch(sp[1].type) { case STACK_PROP: // try to start iterator on value break; case STACK_COLLECTION: it_create(inv->t,&sp->it,&sp[1].ptr); sp->type = STACK_ITERATOR_COL; break; case STACK_PTR: case STACK_RO_PTR: it_create(inv->t,&sp->it,&sp[1].single_ptr); sp->type = STACK_ITERATOR; break; default: _rt_error(inv,__LINE__); } break; case OP_INEXT: tmp = *inv->top->pc++; switch(sp->type) { case STACK_ITERATOR: sp->num = it_next(inv->t,0,&sp->it,0); break; case STACK_ITERATOR_COL: sp->num = it_next(inv->t,0,&sp->it,sizeof(oid)); break; default: _rt_error(inv,__LINE__); } sp->type = STACK_NUM; break; case OP_IPREV: tmp = *inv->top->pc++; switch(sp->type) { case STACK_ITERATOR: sp->num = it_prev(inv->t,0,&sp->it,0); break; case STACK_ITERATOR_COL: sp->num = it_prev(inv->t,0,&sp->it,sizeof(oid)); break; default: _rt_error(inv,__LINE__); } sp->type = STACK_NUM; break; case OP_IKEY: inv->top->pc++; if(sp->type != STACK_ITERATOR && sp->type != STACK_ITERATOR_COL) _rt_error(inv,__LINE__); else { st_ptr pt; st_empty(inv->t,&pt); st_append(inv->t,&pt,sp->it.kdata,sp->it.kused); sp->single_ptr = sp->single_ptr_w = pt; sp->type = STACK_PTR; } break; case OP_IVAL: inv->top->pc++; if(sp->type == STACK_ITERATOR) { st_ptr pt; if(it_current(inv->t,&sp->it,&pt) == 0) { sp->single_ptr = sp->single_ptr_w = pt; sp->type = STACK_PTR; } else sp->type = STACK_NULL; } else if(sp->type == STACK_ITERATOR_COL) { if(sp->it.kused == sizeof(oid)) { // TODO: move to object.c st_ptr pt = inv->hdl->inst.root; st_move(inv->t,&pt,sp->it.kdata,sizeof(oid)); sp->ptr = sp->obj = pt; cle_skip_header(inv->hdl->inst,&sp->ptr); sp->type = STACK_OBJ; } else sp->type = STACK_NULL; } else _rt_error(inv,__LINE__); break; case OP_OMV: tmp = *((ushort*)inv->top->pc); inv->top->pc += sizeof(ushort); sp--; sp->obj = inv->top->object; if(cle_get_property_host(inv->hdl->inst,&sp->ptr,inv->top->pc,tmp) < 0) { sp->type = STACK_NULL; inv->top->pc += tmp; } else { inv->top->pc += tmp; sp->ptr = sp->obj; cle_skip_header(inv->hdl->inst,&sp->ptr); _rt_get(inv,&sp); } break; case OP_MV: tmp = *((ushort*)inv->top->pc); inv->top->pc += sizeof(ushort); if(_rt_move(inv,&sp,inv->top->pc,tmp)) sp->type = STACK_NULL; inv->top->pc += tmp; break; case OP_RIDX: if(sp->type == STACK_NUM) { char buffer[sizeof(rt_number) + HEAD_SIZE]; buffer[0] = 0; buffer[1] = 'N'; memcpy(buffer + 2,&sp->num,sizeof(rt_number)); sp++; if(_rt_move(inv,&sp,buffer,sizeof(buffer))) sp->type = STACK_NULL; } else if(sp->type == STACK_PTR || sp->type == STACK_RO_PTR) { st_ptr mv = sp->single_ptr; sp++; if(_rt_move_st(inv,&sp,&mv)) sp->type = STACK_NULL; } break; case OP_LVAR: sp--; *sp = inv->top->vars[*inv->top->pc++]; break; // writer case OP_POPW: if(sp->type == STACK_OUTPUT) sp->out->pop(sp->outdata); else sp++; break; case OP_DMVW: tmp = *((ushort*)inv->top->pc); inv->top->pc += sizeof(ushort); switch(sp->type) { case STACK_REF: if(sp->var->type == STACK_NULL) { st_empty(inv->t,&sp->var->single_ptr_w); sp->var->single_ptr = sp->var->single_ptr_w; } else if(sp->var->type != STACK_PTR) { _rt_error(inv,__LINE__); return; } sp->single_ptr_w = sp->var->single_ptr; sp->single_ptr = sp->single_ptr_w; sp->type = STACK_PTR; case STACK_PTR: sp--; sp[0] = sp[1]; st_insert(inv->t,&sp->single_ptr_w,inv->top->pc,tmp); break; case STACK_OUTPUT: if(inv->response_started == 0) { sp->out->start(sp->outdata); inv->response_started = 1; } else inv->response_started = 2; sp->out->push(sp->outdata); sp->out->data(sp->outdata,inv->top->pc,tmp); } inv->top->pc += tmp; break; case OP_MVW: tmp = *((ushort*)inv->top->pc); inv->top->pc += sizeof(ushort); switch(sp->type) { case STACK_PTR: st_insert(inv->t,&sp->single_ptr_w,inv->top->pc,tmp); break; case STACK_OUTPUT: if(inv->response_started == 0) { sp->out->start(sp->outdata); inv->response_started = 1; } else inv->response_started = 2; sp->out->data(sp->outdata,inv->top->pc,tmp); } inv->top->pc += tmp; break; case OP_WIDX: // replace by OP_OUT ? _rt_out(inv,&sp,sp,sp + 1); sp++; break; case OP_OPEN: _rt_do_open(inv,&sp); break; case OP_OPEN_POP: // unfinished output if(inv->response_started == 2) sp->out->next(sp->outdata); sp->out->end(sp->outdata,0,0); inv->response_started = 1; tk_commit_task(sp->outtask); // well, what if something went wrong?? sp++; break; // receive input case OP_RECV: sp += *inv->top->pc++; inv->top->sp = sp; return; case OP_SET: if(inv->top->is_expr != 0) _rt_error(inv,__LINE__); else if(sp[1].type != STACK_PROP) _rt_error(inv,__LINE__); else { switch(sp->type) { case STACK_PROP: if(cle_identity_value(inv->hdl->inst,sp->prop_id,sp->prop_obj,&sp->ptr)) _rt_error(inv,__LINE__); if(cle_set_property_ptr(inv->hdl->inst,sp[1].prop_obj,sp[1].prop_id,&sp[1].ptr)) _rt_error(inv,__LINE__); // might not be a good idea if prop-val is a mem-ref st_copy_st(inv->t,&sp[1].ptr,&sp->ptr); break; case STACK_RO_PTR: // link if(cle_set_property_ptr(inv->hdl->inst,sp[1].prop_obj,sp[1].prop_id,&sp[1].ptr)) _rt_error(inv,__LINE__); st_link(inv->t,&sp[1].ptr,&sp->single_ptr); break; case STACK_PTR: // copy if(cle_set_property_ptr(inv->hdl->inst,sp[1].prop_obj,sp[1].prop_id,&sp[1].ptr)) _rt_error(inv,__LINE__); st_copy_st(inv->t,&sp[1].ptr,&sp->single_ptr); break; case STACK_NUM: // bin-num if(cle_set_property_num(inv->hdl->inst,sp[1].prop_obj,sp[1].prop_id,sp->num)) _rt_error(inv,__LINE__); break; case STACK_OBJ: // obj-ref if(cle_set_property_ref(inv->hdl->inst,sp[1].prop_obj,sp[1].prop_id,sp->obj)) _rt_error(inv,__LINE__); break; case STACK_CODE: // write out path/event to method/handler if(st_move(inv->t,&sp->single_ptr,"p",1) == 0) { if(cle_set_property_ptr(inv->hdl->inst,sp[1].prop_obj,sp[1].prop_id,&sp[1].ptr)) _rt_error(inv,__LINE__); st_copy_st(inv->t,&sp[1].ptr,&sp->single_ptr); break; } // or null default: // empty / null if(cle_set_property_ptr(inv->hdl->inst,sp[1].prop_obj,sp[1].prop_id,&sp[1].ptr)) _rt_error(inv,__LINE__); } } sp += 2; break; case OP_MERGE: switch(sp->type) { case STACK_PROP: if(inv->top->is_expr != 0) _rt_error(inv,__LINE__); else if(cle_set_property_ptr(inv->hdl->inst,sp->prop_obj,sp->prop_id,&sp->single_ptr)) _rt_error(inv,__LINE__); else { sp->single_ptr_w = sp->single_ptr; sp->type = STACK_PTR; } break; case STACK_REF: if(sp->var->type == STACK_NULL) { st_empty(inv->t,&sp->var->single_ptr); sp->var->single_ptr_w = sp->var->single_ptr; sp->var->type = STACK_PTR; } else if(sp->var->type != STACK_PTR) _rt_error(inv,__LINE__); case STACK_PTR: case STACK_OUTPUT: break; default: _rt_error(inv,__LINE__); } break; case OP_2STR: tmp = *inv->top->pc++; // vars if(tmp != 1) { _rt_error(inv,__LINE__); break; } // fall throu case OP_CAT: { struct _rt_stack to; st_empty(inv->t,&to.single_ptr); to.single_ptr_w = to.single_ptr; to.type = STACK_PTR; _rt_out(inv,&sp,&to,sp); *sp = to; } break; case OP_NEXT: // non-string (concat) out-ing [OUT Last Tree] if(sp[1].type == STACK_REF) { if(sp[1].var->type == STACK_NULL) *sp[1].var = *sp; else _rt_ref_out(inv,&sp,sp + 1); } else { if(_rt_out(inv,&sp,sp + 1,sp) == 0) { sp++; if(inv->response_started == 2 && sp->type == STACK_OUTPUT) { inv->response_started = 1; sp->out->next(sp->outdata); } } } break; case OP_OUTL: // TODO: stream out structures case OP_OUT: // stream out string if(sp[1].type == STACK_REF) _rt_ref_out(inv,&sp,sp + 1); else _rt_out(inv,&sp,sp + 1,sp); sp++; break; case OP_AVAR: inv->top->vars[*inv->top->pc++] = *sp; sp++; break; case OP_DEFP: // emit Is2 (branch forward) tmp = *inv->top->pc++; // var if(inv->top->vars[tmp].type == STACK_NULL) { sp--; inv->top->vars[tmp].var = sp; inv->top->vars[tmp].type = STACK_REF; inv->top->pc += sizeof(ushort); } else { tmp = *((ushort*)inv->top->pc); inv->top->pc += tmp + sizeof(ushort); } break; case OP_END: tmp = inv->top->code->body.maxparams; while(tmp-- > 0) _rt_free(inv,&inv->top->vars[tmp]); if(inv->top->parent == 0) { // unfinished output? -> next if(inv->response_started == 2) inv->hdl->response->next(inv->hdl->respdata); cle_stream_end(inv->hdl); return; } else { struct _rt_callframe* cf = inv->top; inv->top = inv->top->parent; sp = inv->top->sp; // unref page of origin tk_unref(inv->t,cf->pg); } break; case OP_DOCALL: tmp = *inv->top->pc++; // params if(_rt_call(inv,sp,tmp) == 0) { inv->top->parent->sp = sp + 1 + tmp; // return-stack *(--inv->top->sp) = *(sp + 1 + tmp); // copy output-target sp = inv->top->sp; // set new stack } break; case OP_DOCALL_N: tmp = *inv->top->pc++; // params if(_rt_call(inv,sp,tmp) == 0) { inv->top->parent->sp = sp + tmp; // return-stack inv->top->sp--; inv->top->sp->type = STACK_REF; // ref to sp-top inv->top->sp->var = sp + tmp; inv->top->sp->var->type = STACK_NULL; sp = inv->top->sp; // set new stack } break; case OP_ERROR: // system exception return; default: _rt_error(inv,__LINE__); } } }
int main(int argc, char *argv[]) { char buf[1024]; char *p; LinkedList *ll; long i, n; FILE *fd; char **array; Iterator *it; if (argc != 2) { fprintf(stderr, "usage: ./lltest file\n"); return -1; } if ((ll = ll_create()) == NULL) { fprintf(stderr, "Error creating linked list of strings\n"); return -1; } if ((fd = fopen(argv[1], "r")) == NULL) { fprintf(stderr, "Unable to open %s to read\n", argv[1]); return -1; } /* * test of add() */ printf("===== test of add\n"); while (fgets(buf, 1024, fd) != NULL) { if ((p = strdup(buf)) == NULL) { fprintf(stderr, "Error duplicating string\n"); return -1; } if (!ll_add(ll, p)) { fprintf(stderr, "Error adding string to linked list\n"); return -1; } } fclose(fd); n = ll_size(ll); /* * test of get() */ printf("===== test of get\n"); for (i = 0; i < n; i++) { if (!ll_get(ll, i, (void **)&p)) { fprintf(stderr, "Error retrieving %ld'th element\n", i); return -1; } printf("%s", p); } /* * test of remove */ printf("===== test of remove\n"); for (i = n - 1; i >= 0; i--) { if (!ll_remove(ll, i, (void **)&p)) { fprintf(stderr, "Error removing string from linked list\n"); return -1; } free(p); } /* * test of destroy with NULL userFunction */ printf("===== test of destroy(NULL)\n"); ll_destroy(ll, NULL); /* * test of insert */ if ((ll = ll_create()) == NULL) { fprintf(stderr, "Error creating linked list of strings\n"); return -1; } fd = fopen(argv[1], "r"); /* we know we can open it */ printf("===== test of insert\n"); while (fgets(buf, 1024, fd) != NULL) { if ((p = strdup(buf)) == NULL) { fprintf(stderr, "Error duplicating string\n"); return -1; } if (!ll_insert(ll, 0, p)) { fprintf(stderr, "Error adding string to linked list\n"); return -1; } } fclose(fd); for (i = 0; i < n; i++) { if (!ll_get(ll, i, (void **)&p)) { fprintf(stderr, "Error retrieving %ld'th element\n", i); return -1; } printf("%s", p); } /* * test of set */ printf("===== test of set\n"); for (i = 0; i < n; i++) { char bf[1024], *q; sprintf(bf, "line %ld\n", i); if ((p = strdup(bf)) == NULL) { fprintf(stderr, "Error duplicating string\n"); return -1; } if (!ll_set(ll, i, p, (void **)&q)) { fprintf(stderr, "Error replacing %ld'th element\n", i); return -1; } free(q); } /* * test of toArray */ printf("===== test of toArray\n"); if ((array = (char **)ll_toArray(ll, &n)) == NULL) { fprintf(stderr, "Error in invoking ll_toArray()\n"); return -1; } for (i = 0; i < n; i++) { printf("%s", array[i]); } free(array); /* * test of iterator */ printf("===== test of iterator\n"); if ((it = ll_it_create(ll)) == NULL) { fprintf(stderr, "Error in creating iterator\n"); return -1; } while (it_hasNext(it)) { char *p; (void) it_next(it, (void **)&p); printf("%s", p); } it_destroy(it); /* * test of destroy with free() as userFunction */ printf("===== test of destroy(free)\n"); ll_destroy(ll, free); return 0; }