Ejemplo n.º 1
0
int tableSet(PTable t,const pchar Name,const pchar Value)
{
  PTablePage p=t->pFirst,q;
  int idx0,idx=0,res=0;
  p=tableFind(p,&idx,Name);
  if(p)
  {
    q=p;idx0=idx;
    while((p=tableFind(p,&idx,Name)))
    {
      if(t->iFlags&TABLE_FLAG_ALLOCNAME)xfree(p->Values[idx].szName);
      if(t->iFlags&TABLE_FLAG_ALLOCVALUE)xfree(p->Values[idx].szValue);
      if(idx!=p->iCount-1)memmove(&p->Values[idx],&p->Values[idx+1],sizeof(SAttr)*(p->iCount-idx-1));
      p->iCount--;
      t->iCount--;
      res++;
    }
    if(res)t->iHoles++;
    if(t->iFlags&TABLE_FLAG_ALLOCVALUE)xfree(q->Values[idx].szValue);
    if(xstrlen(q->Values[idx0].szValue)>=xstrlen(Value))
      xstrcpy(q->Values[idx0].szValue,Value);
    else
      q->Values[idx0].szValue=xstrdup(t->pPool,Value);
    return t->iCount;
  }else return tableAdd(t,Name,Value);
}
Ejemplo n.º 2
0
/*
 * Returns the value, or -1 for failure
 */
int
tableInsert(table_t *table, const char *key, int value)
{
	const int v = tableFind(table, key);

	if(v > 0)	/* duplicate key */
		return (v == value) ? value : -1;	/* allow real dups */

	assert(value != -1);	/* that would confuse us */

	if(table->tableHead == NULL)
		table->tableLast = table->tableHead = (tableEntry *)cli_malloc(sizeof(tableEntry));
	else
		table->tableLast = table->tableLast->next =
			(tableEntry *)cli_malloc(sizeof(tableEntry));

	if(table->tableLast == NULL)
		return -1;

	table->tableLast->next = NULL;
	table->tableLast->key = strdup(key);
	table->tableLast->value = value;

	return value;
}
Ejemplo n.º 3
0
//变量声明的四元式生成
std::string* varDefEmit(AST_node t)
{
	std::vector<AST_node>::iterator i = t->children->begin();
	std::string *name = NULL, *op1 = NULL, *op2 = NULL, op;

	for (; i != t->children->end(); i++)
	{
		if ((*i)->lex_symbol == IDENT)
		{
			name = (*i)->val.ident;
			tableItem *item = tableFind(*(*i)->symTable, *(*i)->val.ident, (*i)->parent);
			if (item->attribute == CHAR)
			{
				op = "char";
			}
			else if(item->attribute == INT)
			{
				op = "int";
			}
			else
			{
				op = "arraydef";
				op1 = ((arrayTemplet*)item->addr)->type == INT ? new std::string("int")
																: new std::string("char");
				char _s[5], *s = itoa(((arrayTemplet*)item->addr)->length, _s, 10);
				op2 = new std::string(s);
			}
			emit(op, name, op1, op2);
		}

	}
	return name;
}
Ejemplo n.º 4
0
//常量声明的四元式生成
std::string* constDefEmit(AST_node t)
{
	std::vector<AST_node>::iterator i = t->children->begin();
	std::string *res = NULL, *op1 = NULL, *op2 = NULL, op;

	if (i == t->children->end() || (*i)->lex_symbol != IDENT)
	{
		return NULL;
	}

	if ((*i)->lex_symbol == IDENT)
	{
		res = (*i)->val.ident;
		tableItem *item = tableFind(*(*i)->symTable, *res, (*i)->parent);
		if (item->attribute == CHAR)
		{
			char c[2];
			c[0] = *((char*)item->addr);
			c[1] = '\0';
			op1 = new std::string(c);
			op = "char";
		}
		else
		{
			char _s[5], *s;
			s = itoa(*((int*)item->addr), _s, 10);
			op1 = new std::string(s);
			op = "int";
		}
	}
	i += 2;
	emit(op, res, op1, op2);
	return res;
}
Ejemplo n.º 5
0
//过程调用语句
//<过程调用语句>::=<标识符>[<实在参数表>]
//<实在参数表>::='('<实在参数>{,<实在参数>}')
std::string* callStatEmit(AST_node t)
{
	std::vector<AST_node>::iterator i = t->children->begin();
	std::vector<std::string*> args;

	std::string *name = new std::string(*(*i)->val.ident);
	i++;
	if (i == t->children->end())
	{
		//无参数调用
		std::string *n = new std::string("0");
		return emit("call", NULL, name, n);
	}
	//记录参数
	for (std::vector<AST_node>::iterator j = (*i)->children->begin();
	j != (*i)->children->end(); j++)
	{
		if ((*j)->ast_type == EXPRESSION)
			args.push_back(expEmit(*j));
	}
	//从右至左将参数压栈
	for (std::vector<std::string*>::reverse_iterator j = args.rbegin();
	j != args.rend(); j++)
	{
		if((*j)->c_str()[0] > '9' || (*j)->c_str()[0] < '0')
		{
			//j是标识符
			tableItem *item = tableFind(*(t->symTable), *name, t->parent);	//函数的符号表项
			if(tableFind(*(item->table),*(*j),NULL)->type == REFERENCE)
			{
				//该参数是传引用
				emit("param", *j, new std::string("reference"), NULL);
				continue;
			}
		}
		//j是数或者传值的参数	
		emit("param", *j, NULL, NULL);
	}
	std::string *n = NULL;
	char _s[5], *s = NULL;
	s = itoa(args.size(), _s, 10);
	n = new std::string(s);

	return emit("call", NULL, name, n);
}
Ejemplo n.º 6
0
pchar tableGet(PTable t,const pchar Name)
{
  PTablePage p;
  int idx=0;
  if(!t)return NULL;
  p=t->pFirst;
  p=tableFind(p,&idx,Name);
  if(p)return p->Values[idx].szValue;else return NULL;
}
Ejemplo n.º 7
0
//函数声明的四元式生成
//t的类型为FUNDEF
std::string* funDefEmit(AST_node t)
{
	std::vector<AST_node>::iterator i = t->children->begin();	//t的子节点是prohead和program
	std::string *name = (*i)->children->at(1)->val.ident;
	tableItem *item = tableFind(*(t->symTable), *name, t->parent);

	char _s[5];
	char *s = itoa(((functionTemplet*)item->addr)->args, _s, 10);
	std::string *op2 = NULL;
	op2 = item->attribute == INT ? new std::string("int") : new std::string("char");
	emit("function", name, new std::string(s), op2);
	i++;
	IREmit((*i));
	return NULL;
}
Ejemplo n.º 8
0
//过程声明的四元式生成
//t的类型为PRODEF
std::string* proDefEmit(AST_node t)
{
	std::vector<AST_node>::iterator i = t->children->begin();	//t的子节点是prohead和program
	std::string *name = (*i)->children->at(1)->val.ident;
	tableItem *item = tableFind(*(t->symTable), *name, t->parent);

	char _s[5];
	char *s = itoa(((procedureTemplet*)item->addr)->args, _s, 10);

	i++;
	emit("procedure", name, new std::string(s), NULL);
	IREmit(*i);

	return NULL;
}
Ejemplo n.º 9
0
/*
 * Returns the value, or -1 for failure
 */
int
tableInsert(table_t *table, const char *key, int value)
{
	const int v = tableFind(table, key);

	if(v > 0)	/* duplicate key */
		return (v == value) ? value : -1;	/* allow real dups */

	assert(value != -1);	/* that would confuse us */

	if(table->tableHead == NULL)
		table->tableLast = table->tableHead = (tableEntry *)cli_malloc(sizeof(tableEntry));
	else {
		/*
		 * Re-use deleted items
		 */
		if(table->flags&TABLE_HAS_DELETED_ENTRIES) {
			tableEntry *tableItem;

			assert(table->tableHead != NULL);

			for(tableItem = table->tableHead; tableItem; tableItem = tableItem->next)
				if(tableItem->key == NULL) {
					/* This item has been deleted */
					tableItem->key = cli_strdup(key);
					tableItem->value = value;
					return value;
				}

			table->flags &= ~TABLE_HAS_DELETED_ENTRIES;
		}

		table->tableLast = table->tableLast->next =
			(tableEntry *)cli_malloc(sizeof(tableEntry));
	}

	if(table->tableLast == NULL) {
        cli_dbgmsg("tableInsert: Unable to allocate memory for table\n");
		return -1;
    }

	table->tableLast->next = NULL;
	table->tableLast->key = cli_strdup(key);
	table->tableLast->value = value;

	return value;
}
Ejemplo n.º 10
0
/*
	查找操作:若在所给符号表中找到则返回指向该符号表项的指针,否则返回NULL
	t:待查找的符号表
	name:欲查找的符号
	level:欲查找符号所属层数
*/
tableItem* tableFind(Table &t, std::string name, AST_node parent)
{
	Table::iterator res = t.find(name);
	tableItem *ret = NULL;

	if (res == t.end())
	{
		if (parent == NULL || parent->symTable == NULL)
		{
			return NULL;
		}
		return tableFind(*(parent->symTable), name, parent->parent);
	}
	itemList* list = &(res->second);
	ret = &(list->at(0));
	return ret;
}
Ejemplo n.º 11
0
int tableDel(PTable t,const pchar Name)
{
  PTablePage p=t->pFirst;
  int idx=0;
  int res=0;
  while(p)
  {
    p=tableFind(p,&idx,Name);
    if(p)
    {
      if(t->iFlags&TABLE_FLAG_ALLOCNAME)xfree(p->Values[idx].szName);
      if(t->iFlags&TABLE_FLAG_ALLOCVALUE)xfree(p->Values[idx].szValue);
      if(idx!=p->iCount-1)memmove(&p->Values[idx],&p->Values[idx+1],sizeof(SAttr)*(p->iCount-idx-1));
      p->iCount--;
      t->iCount--;
      res++;
    }
  }
  if(res)t->iHoles++;
  return res;
}
Ejemplo n.º 12
0
int cli_scanrtf(cli_ctx *ctx)
{
	char* tempname;
	const unsigned char* ptr;
	const unsigned char* ptr_end;
	int ret = CL_CLEAN;
	struct rtf_state state;
	struct stack stack;
	size_t bread;
	table_t* actiontable;
	uint8_t main_symbols[256];
	size_t offset = 0;

	cli_dbgmsg("in cli_scanrtf()\n");

	memset(main_symbols, 0, 256);
	main_symbols['{']=1;
	main_symbols['}']=1;
	main_symbols['\\']=1;

	stack.stack_cnt = 0;
	stack.stack_size = 16;
	stack.elements = 0;
	stack.warned = 0;
	stack.states = cli_malloc(stack.stack_size*sizeof(*stack.states));

	if(!stack.states) {
        cli_errmsg("ScanRTF: Unable to allocate memory for stack states\n");
		return CL_EMEM;
    }

	if(!(tempname = cli_gentemp(ctx->engine->tmpdir)))
	    return CL_EMEM;

	if(mkdir(tempname, 0700)) {
	    	cli_dbgmsg("ScanRTF -> Can't create temporary directory %s\n", tempname);
		free(stack.states);
		free(tempname);
		return CL_ETMPDIR;
	}

	actiontable = tableCreate();
	if((ret = load_actions(actiontable))) {
		cli_dbgmsg("RTF: Unable to load rtf action table\n");
		free(stack.states);
		if(!ctx->engine->keeptmp)
			cli_rmdirs(tempname);
		free(tempname);
		tableDestroy(actiontable);
		return ret;
	}

	init_rtf_state(&state);

	for (offset = 0; (ptr = fmap_need_off_once_len(*ctx->fmap, offset, BUFF_SIZE, &bread)) && bread; offset += bread) {
	    ptr_end = ptr + bread;
	    while(ptr < ptr_end) {
			switch(state.parse_state) {
				case PARSE_MAIN: 
					switch(*ptr++) {
						case '{':
							if(( ret = push_state(&stack,&state) )) {
								cli_dbgmsg("RTF:Push failure!\n");
								SCAN_CLEANUP;
								return ret;
							}
							break;
						case '}':
							if(state.cb_data && state.cb_end)
								if(( ret = state.cb_end(&state, ctx) )) {
									SCAN_CLEANUP;
									return ret;
								}
							if(( ret = pop_state(&stack,&state) )) {
								cli_dbgmsg("RTF:pop failure!\n");
								SCAN_CLEANUP;
								return ret;
							}
							break;
						case '\\':
							state.parse_state = PARSE_CONTROL_;
							break;
						default:
							ptr--;
							{
								size_t i;
								size_t left = ptr_end - ptr;
								size_t use = left;
								for(i = 1;i < left; i++)
									if(main_symbols[ptr[i]]) {
										use = i;
										break;
									}
								if(state.cb_begin) {
									if(!state.cb_data)
										 if(( ret = state.cb_begin(&state, ctx,tempname) )) {
											 SCAN_CLEANUP;
											 return ret;
										}
									if(( ret = state.cb_process(&state, ptr, use) )) {
										if(state.cb_end) {
											state.cb_end(&state,ctx);
										}
										SCAN_CLEANUP;
										return ret;
									}
								}
								ptr += use;
							}
					}
					break;
				case PARSE_CONTROL_:
					if(isalpha(*ptr))  {
						state.parse_state = PARSE_CONTROL_WORD;
						state.controlword_cnt = 0;
					}
					else
						state.parse_state = PARSE_CONTROL_SYMBOL;
					break;
				case PARSE_CONTROL_SYMBOL:
					ptr++;	/* Do nothing */
					state.parse_state = PARSE_MAIN;
					break;
				case PARSE_CONTROL_WORD:
					if(state.controlword_cnt == 32) {
						cli_dbgmsg("Invalid control word: maximum size exceeded:%s\n",state.controlword);
						state.parse_state = PARSE_MAIN;
					}
					else if(isalpha(*ptr))
						state.controlword[state.controlword_cnt++] = *ptr++;
					else {
						if(isspace(*ptr)) {
							state.controlword[state.controlword_cnt++] = *ptr++;
							state.parse_state = PARSE_INTERPRET_CONTROLWORD;
						}
						else if (isdigit(*ptr)) {
							state.parse_state = PARSE_CONTROL_WORD_PARAM;
							state.controlword_param = 0;
							state.controlword_param_sign = 1;
						}
						else if(*ptr == '-') {
							ptr++;
							state.parse_state = PARSE_CONTROL_WORD_PARAM;
							state.controlword_param = 0;
							state.controlword_param_sign = -1;
						}
						else {
							state.parse_state = PARSE_INTERPRET_CONTROLWORD;
						}
					}
					break;
				case PARSE_CONTROL_WORD_PARAM:
					if(isdigit(*ptr)) {
						state.controlword_param = state.controlword_param*10 + *ptr++ - '0';
					}
					else if(isalpha(*ptr)) {
						ptr++;
					}
					else {
						if(state.controlword_param_sign < 0)
							state.controlword_param = -state.controlword_param;
						state.parse_state = PARSE_INTERPRET_CONTROLWORD;
					}
					break;
				case PARSE_INTERPRET_CONTROLWORD:
					{
						int action;

						state.controlword[state.controlword_cnt] = '\0';
						action = tableFind(actiontable, state.controlword);
						if(action != -1) {
							if(state.cb_data && state.cb_end) {/* premature end of previous block */
								state.cb_end(&state,ctx);
								state.cb_begin = NULL;
								state.cb_end = NULL;
								state.cb_data = NULL;
							}
							rtf_action(&state,action);
						}
						state.parse_state = PARSE_MAIN;
						break;
					}
			}
		}
	}

	SCAN_CLEANUP;
	return ret;
}