Esempio n. 1
0
/*
 * Unescape XML string
 *
 * input and output may be the same buffers
 * return len of output
 *
 * "&lt;"   -> "<"
 * "&gt;"   -> "<"
 * "&apos;" -> "'"
 * "&quot;" -> "\""
 * "&amp;"  -> "&"
 */
int unescape_xml_r( const char *input, int input_len, char *output){
	int output_len=0;

	while(input_len){
		if(*input=='&'){
			if(IS_LT(input, input_len)){
				*output='<';
				input+=LT_LEN;
				input_len-=LT_LEN;
			}else if(IS_GT(input, input_len)){
				*output='>';
				input+=GT_LEN;
				input_len-=GT_LEN;
			}else if(IS_APOS(input, input_len)){
				*output='\'';
				input+=APOS_LEN;
				input_len-=APOS_LEN;
			}else if(IS_QUOT(input, input_len)){
				*output='"';
				input+=QUOT_LEN;
				input_len-=QUOT_LEN;
			}else if(IS_AMP(input, input_len)){
				*output='&';
				input+=AMP_LEN;
				input_len-=AMP_LEN;
			}else{
				*output='&';
				input++;
				input_len--;
			}
		}else{
			*output=*input++;
			input_len--;
		}
		output_len++;
		output++;
	}
	return output_len;
}
Esempio n. 2
0
File: bvm.c Progetto: tkriik/bvm
/* Executes a program in a BVM instance until termination.
 * Returns a non-zero error code if an error occurred. */
int
bvm_run(struct bvm *vm, const uint8_t *code, size_t code_size)
{
	/* Code size must fit into BVM's memory. */
	if (code_size > sizeof(vm->mem))
		return BVM_PROGRAM_TOO_LARGE;

	/* Zero register file and memory. */
	memset(vm->reg, 0, sizeof(vm->reg));
	memset(vm->mem, 0, sizeof(vm->mem));

	/* Load program code into memory. */
	memcpy(vm->mem, code, code_size);

	/* Reset the clock. */
	vm->clk = 0;

	while (1) {
		uint8_t	op;
		uint8_t	src, dst;
		int	c;

		usleep(BVM_CYCLE);
		vm->clk++;

		op = pc_next(vm);
		switch (op) {
		case HALT:
			return 0;

		case MOV:
			src = pc_next(vm);
			dst = pc_next(vm);
			if (!IS_REGISTER_VALID(src) || !IS_REGISTER_VALID(dst))
				return BVM_BAD_INSTRUCTION;
			vm->reg[dst] = vm->reg[src];
			continue;

		case MOVN:
			src = pc_next(vm);
			dst = pc_next(vm);
			if (!IS_REGISTER_VALID(dst))
				return BVM_BAD_INSTRUCTION;
			vm->reg[dst] = src;
			continue;

		case LOAD:
			src = pc_next(vm);
			dst = pc_next(vm);
			if (!IS_REGISTER_VALID(src) || !IS_REGISTER_VALID(dst))
				return BVM_BAD_INSTRUCTION;
			vm->reg[dst] = vm->mem[vm->reg[src]];
			continue;

		case LOADA:
			src = pc_next(vm);
			dst = pc_next(vm);
			if (!IS_REGISTER_VALID(src) || !IS_REGISTER_VALID(dst))
				return BVM_BAD_INSTRUCTION;
			vm->reg[dst] = vm->mem[src];
			continue;

		case PUT:
			src = pc_next(vm);
			dst = pc_next(vm);
			if (!IS_REGISTER_VALID(src) || !IS_REGISTER_VALID(dst))
				return BVM_BAD_INSTRUCTION;
			vm->mem[vm->reg[dst]] = vm->reg[src];
			continue;

		case PUTN:
			src = pc_next(vm);
			dst = pc_next(vm);
			if (!IS_REGISTER_VALID(dst))
				return BVM_BAD_INSTRUCTION;
			vm->mem[vm->reg[dst]] = src;
			continue;

		case PUTA:
			src = pc_next(vm);
			dst = pc_next(vm);
			if (!IS_REGISTER_VALID(src))
				return BVM_BAD_INSTRUCTION;
			vm->mem[dst] = vm->reg[src];
			continue;

		case PUTNA:
			src = pc_next(vm);
			dst = pc_next(vm);
			vm->mem[dst] = src;
			continue;

		case PUSH:
			src = pc_next(vm);
			if (!IS_REGISTER_VALID(src))
				return BVM_BAD_INSTRUCTION;
			vm->reg[SP]--;
			vm->mem[vm->reg[SP]] = vm->reg[src];
			continue;

		case PUSHN:
			src = pc_next(vm);
			vm->reg[SP]--;
			vm->mem[vm->reg[SP]] = src;
			continue;

		case POP:
			src = pc_next(vm);
			if (!IS_REGISTER_VALID(src))
				return BVM_BAD_INSTRUCTION;
			vm->reg[src] = vm->mem[vm->reg[SP]];
			vm->reg[SP]++;
			continue;

		case INC:
			src = pc_next(vm);
			if (!IS_REGISTER_VALID(src))
				return BVM_BAD_INSTRUCTION;
			vm->reg[src]++;
			continue;

		case DEC:
			src = pc_next(vm);
			if (!IS_REGISTER_VALID(src))
				return BVM_BAD_INSTRUCTION;
			vm->reg[src]--;
			continue;

		case ADD:
			src = pc_next(vm);
			dst = pc_next(vm);
			if (!IS_REGISTER_VALID(src) || !IS_REGISTER_VALID(dst))
				return BVM_BAD_INSTRUCTION;
			vm->reg[dst] += vm->reg[src];
			continue;

		case ADDN:
			src = pc_next(vm);
			dst = pc_next(vm);
			if (!IS_REGISTER_VALID(dst))
				return BVM_BAD_INSTRUCTION;
			vm->reg[dst] += src;
			continue;

		case SUB:
			src = pc_next(vm);
			dst = pc_next(vm);
			if (!IS_REGISTER_VALID(src) || !IS_REGISTER_VALID(dst))
				return BVM_BAD_INSTRUCTION;
			vm->reg[dst] -= vm->reg[src];
			continue;

		case SUBN:
			src = pc_next(vm);
			dst = pc_next(vm);
			if (!IS_REGISTER_VALID(dst))
				return BVM_BAD_INSTRUCTION;
			vm->reg[dst] -= src;
			continue;

		case AND:
			src = pc_next(vm);
			dst = pc_next(vm);
			if (!IS_REGISTER_VALID(src) || !IS_REGISTER_VALID(dst))
				return BVM_BAD_INSTRUCTION;
			vm->reg[dst] &= vm->reg[src];
			continue;

		case ANDN:
			src = pc_next(vm);
			dst = pc_next(vm);
			if (!IS_REGISTER_VALID(src) || !IS_REGISTER_VALID(dst))
				return BVM_BAD_INSTRUCTION;
			vm->reg[dst] &= src;
			continue;

		case OR:
			src = pc_next(vm);
			dst = pc_next(vm);
			if (!IS_REGISTER_VALID(src) || !IS_REGISTER_VALID(dst))
				return BVM_BAD_INSTRUCTION;
			vm->reg[dst] |= vm->reg[src];
			continue;

		case ORN:
			src = pc_next(vm);
			dst = pc_next(vm);
			if (!IS_REGISTER_VALID(src) || !IS_REGISTER_VALID(dst))
				return BVM_BAD_INSTRUCTION;
			vm->reg[dst] |= src;
			continue;

		case XOR:
			src = pc_next(vm);
			dst = pc_next(vm);
			if (!IS_REGISTER_VALID(src) || !IS_REGISTER_VALID(dst))
				return BVM_BAD_INSTRUCTION;
			vm->reg[dst] ^= vm->reg[src];
			continue;

		case XORN:
			src = pc_next(vm);
			dst = pc_next(vm);
			if (!IS_REGISTER_VALID(src) || !IS_REGISTER_VALID(dst))
				return BVM_BAD_INSTRUCTION;
			vm->reg[dst] ^= src;
			continue;

		case NEG:
			src = pc_next(vm);
			if (!IS_REGISTER_VALID(src))
				return BVM_BAD_INSTRUCTION;
			vm->reg[src] = ~vm->reg[src];
			continue;

		case CMP:
			src = pc_next(vm);
			dst = pc_next(vm);
			if (!IS_REGISTER_VALID(src) || !IS_REGISTER_VALID(dst))
				return BVM_BAD_INSTRUCTION;
			vm->reg[CC]  = 0;
			vm->reg[CC] |= (vm->reg[src] == vm->reg[dst])
			    << CC_EQ_SHIFT;
			vm->reg[CC] |= (vm->reg[src]  < vm->reg[dst])
			    << CC_OF_SHIFT;
			continue;

		case CMPN:
			src = pc_next(vm);
			dst = pc_next(vm);
			if (!IS_REGISTER_VALID(src))
				return BVM_BAD_INSTRUCTION;
			vm->reg[CC]  = 0;
			vm->reg[CC] |= (vm->reg[src] == dst) << CC_EQ_SHIFT;
			vm->reg[CC] |= (vm->reg[src]  < dst) << CC_OF_SHIFT;
			continue;

		case TEST:
			src = pc_next(vm);
			if (!IS_REGISTER_VALID(src))
				return BVM_BAD_INSTRUCTION;
			vm->reg[CC]  = 0;
			vm->reg[CC] |= (vm->reg[src] == 0) << CC_EQ_SHIFT;
			continue;

		case JMP:
			vm->reg[PC] = pc_next(vm);
			continue;

		case JE:
			src = pc_next(vm);
			if (IS_EQ(vm->reg[CC]))
				vm->reg[PC] = src;
			continue;

		case JNE:
			src = pc_next(vm);
			if (!IS_EQ(vm->reg[CC]))
				vm->reg[PC] = src;
			continue;

		case JL:
			src = pc_next(vm);
			if (IS_LT(vm->reg[CC]))
				vm->reg[PC] = src;
			continue;

		case JLE:
			src = pc_next(vm);
			if (IS_LT(vm->reg[CC]) || IS_EQ(vm->reg[CC]))
				vm->reg[PC] = src;
			continue;

		case JG:
			src = pc_next(vm);
			if (!IS_LT(vm->reg[CC]) && !IS_EQ(vm->reg[CC]))
				vm->reg[PC] = src;
			continue;

		case JGE:
			src = pc_next(vm);
			if (!IS_LT(vm->reg[CC]) || IS_EQ(vm->reg[CC]))
				vm->reg[PC] = src;
			continue;

		case JEOF:
			src = pc_next(vm);
			if (IS_EOF(vm->reg[CC]))
				vm->reg[PC] = src;
			continue;

		case JNEOF:
			src = pc_next(vm);
			if (!IS_EOF(vm->reg[CC]))
				vm->reg[PC] = src;
			continue;

		case CALL:
			vm->reg[SP]--;
			vm->mem[vm->reg[SP]] = vm->reg[PC] + 1;
			vm->reg[PC] = pc_next(vm);
			continue;

		case RET:
			vm->reg[PC] = vm->mem[vm->reg[SP]];
			vm->reg[SP]++;
			continue;

		case NOP:
			continue;

		case IN:
			src = pc_next(vm);
			if (!IS_REGISTER_VALID(src))
				return BVM_BAD_INSTRUCTION;
			if ((c = fgetc(stdin)) == EOF)
				vm->reg[CC] = CC_EOF;
			vm->reg[src] = c;
			continue;

		case OUT:
			src = pc_next(vm);
			if (!IS_REGISTER_VALID(src))
				return BVM_BAD_INSTRUCTION;
			if (fputc(vm->reg[src], stdout) == EOF)
				vm->reg[CC] = CC_EOF;
			continue;

		case OUTN:
			src = pc_next(vm);
			if (fputc(src, stdout) == EOF)
				vm->reg[CC] = CC_EOF;
			continue;

		default:
			return BVM_BAD_INSTRUCTION;
		}
	}
}