Пример #1
0
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");
}
Пример #2
0
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;
}
Пример #3
0
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;
	}
}
Пример #4
0
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
	}
}
Пример #5
0
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;
}
Пример #6
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;
}
Пример #7
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__);
		}
	}
}
Пример #8
0
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;
}