Esempio n. 1
0
void buffer_vprintf(buffer *b, const char *format, va_list ap)
{
    char c;
    const char *s;
    buffer *buf;
    
    while (*format) {
        if (*format == '%') {
            format++;
            switch (*format) {
                case 'c':
                    c = va_arg(ap, int);
                    buffer_append_char(b, c);
                    break;
                case 's':
                    s = va_arg(ap, const char *);
                    buffer_append_str(b, s);
                    break;
                case 'b':
                    buf = va_arg(ap, buffer *);
                    buffer_append_buffer(b, buf);
                    break;
                default:
                    buffer_append_char(b, '%');
                    break;
            }
        } else
Esempio n. 2
0
File: main.c Progetto: robinp/neko
static void report( neko_vm *vm, value exc, int isexc ) {
	int i;
	buffer b = alloc_buffer(NULL);
	value st = neko_exc_stack(vm);
	for(i=0;i<val_array_size(st);i++) {
		value s = val_array_ptr(st)[i];
		buffer_append(b,"Called from ");
		if( val_is_null(s) )
			buffer_append(b,"a C function");
		else if( val_is_string(s) ) {
			buffer_append(b,val_string(s));
			buffer_append(b," (no debug available)");
		} else if( val_is_array(s) && val_array_size(s) == 2 && val_is_string(val_array_ptr(s)[0]) && val_is_int(val_array_ptr(s)[1]) ) {
			val_buffer(b,val_array_ptr(s)[0]);
			buffer_append(b," line ");
			val_buffer(b,val_array_ptr(s)[1]);
		} else
			val_buffer(b,s);
		buffer_append_char(b,'\n');
	}
	if( isexc )
		buffer_append(b,"Uncaught exception - ");
	val_buffer(b,exc);
#	ifdef NEKO_STANDALONE
	neko_standalone_error(val_string(buffer_to_string(b)));
#	else
	fprintf(stderr,"%s\n",val_string(buffer_to_string(b)));
#	endif
}
Esempio n. 3
0
void buffer_append_str(buffer *b, const char *s)
{
    if (!s)
        return;
    while (*s)
        buffer_append_char(b, *s++);
}
Esempio n. 4
0
TEST(Buffer, Append)
{
	char * text;
	buffer * buf;

	buf = buffer_new(8);
	buffer_prepare(buf, 2);
	EXPECT_EQ(buf->size, 8);

	buffer_prepare(buf, 10);
	EXPECT_EQ(buf->size, 18);

	buffer_append_string(buf, "Hello");
	EXPECT_EQ(buf->used, 5);
	
	buffer_append_char(buf, ' ');
	EXPECT_TRUE(strncmp((char*)buf->data, "Hello ", buf->used) == 0);

	text = strdup("WORLD");
	buffer_append_data_tolower(buf, (unsigned char*) text, strlen(text));
	EXPECT_TRUE(strncmp((char*)buf->data, "Hello world", buf->used) == 0);
	free(text);

	text = strdup("\nWORLD\n...");
	buffer_append_string_n(buf, text, 6);
	EXPECT_TRUE(strncmp((char*)buf->data, "Hello world\nWORLD", buf->used) == 0);
	free(text);

	buffer_destroy(buf);
}
Esempio n. 5
0
/**
	buffer_add_char : 'buffer -> c:int -> void
	<doc>Add a single char to a buffer. Error if [c] is not in the 0..255 range</doc>
**/
static value buffer_add_char( value b, value c ) {
	val_check_kind(b,k_buffer);
	val_check(c,int);
	if( val_int(c) < 0 || val_int(c) > 255 )
		neko_error();	
	buffer_append_char( (buffer)val_data(b), (char)(unsigned char)val_int(c) );
	return val_true;
}
Esempio n. 6
0
void buffer_append_buffer(buffer *b, buffer *x)
{
    int c;
    buffer_iterator it;
    
    buffer_get_iterator(x, &it);
    
    while((c = buffer_iterator_next(&it)) != EOF)
        buffer_append_char(b, c);
}
Esempio n. 7
0
/**
	request : 'db -> sql:string -> 'result
	<doc>Executes the SQL request and returns its result</doc>
**/
static value request( value v, value sql ) {
	database *db;
	result *r;
	const char *tl;
	int i,j;
	val_check_kind(v,k_db);
	val_check(sql,string);
	db = val_db(v);
	r = (result*)alloc(sizeof(result));
	r->db = db;
	if( sqlite3_prepare(db->db,val_string(sql),val_strlen(sql),&r->r,&tl) != SQLITE_OK ) {
		buffer b = alloc_buffer("Sqlite error in ");
		val_buffer(b,sql);
		buffer_append(b," : ");
		buffer_append(b,sqlite3_errmsg(db->db));
		val_throw(buffer_to_string(b));
	}
	if( *tl ) {
		sqlite3_finalize(r->r);
		val_throw(alloc_string("Cannot execute several SQL requests at the same time"));
	}
	r->ncols = sqlite3_column_count(r->r);
	r->names = (field*)alloc_private(sizeof(field)*r->ncols);
	r->bools = (int*)alloc_private(sizeof(int)*r->ncols);
	r->first = 1;
	r->done = 0;
	for(i=0;i<r->ncols;i++) {
		field id = val_id(sqlite3_column_name(r->r,i));
		const char *dtype = sqlite3_column_decltype(r->r,i);
		for(j=0;j<i;j++)
			if( r->names[j] == id ) {
				if( strcmp(sqlite3_column_name(r->r,i),sqlite3_column_name(r->r,j)) == 0 ) {
					buffer b = alloc_buffer("Error, same field is two times in the request ");
					val_buffer(b,sql);
					sqlite3_finalize(r->r);
					val_throw(buffer_to_string(b));
				} else {
					buffer b = alloc_buffer("Error, same field ids for : ");
					buffer_append(b,sqlite3_column_name(r->r,i));
					buffer_append(b," and ");
					buffer_append(b,sqlite3_column_name(r->r,j));
					buffer_append_char(b,'.');
					sqlite3_finalize(r->r);
					val_throw(buffer_to_string(b));
				}
			}
		r->names[i] = id;
		r->bools[i] = dtype?(strcmp(dtype,"BOOL") == 0):0;
	}
	// changes in an update/delete
	if( db->last != NULL )
		finalize_result(val_result(db->last),0);
	db->last = alloc_abstract(k_result,r);
	return db->last;
}
Esempio n. 8
0
static void zlib_error( z_stream *z, int err ) {
	buffer b = alloc_buffer("ZLib Error : ");
	if( z && z->msg ) {
		buffer_append(b,z->msg);
		buffer_append(b," (");
	}
	val_buffer(b,alloc_int(err));
	if( z && z->msg )
		buffer_append_char(b,')');
	val_throw(buffer_to_string(b));
}
Esempio n. 9
0
int buffer_stream_putchar(char c, FILE *f)
{
buffer_stream_t *pbs;

    pbs = fdev_get_udata(f);
    buffer_append_char(pbs->pbufout, c);
    if( pbs->outcb != NULL)
    {
        pbs->outcb(pbs->pbufout);
    }
    return EOF;
}
Esempio n. 10
0
TEST(Buffer, Case)
{
	buffer * buf;

	buf = buffer_new(1);
	buffer_append_char(buf, 'n');
	EXPECT_EQ(buf->used, 1);
	EXPECT_EQ(buf->size, 1);

	buffer_append_string(buf, "Idium-a-nEw-breed-of-browser");
	EXPECT_EQ(buf->used, 29);
	buffer_camelify(buf);
	EXPECT_TRUE(strncmp((char*)buf->data, "NIdium-A-NEw-Breed-Of-Browser ", buf->used) == 0);
	//@FIXME: EXPECT_TRUE(strncmp((char*)buf->data, "NidiumANewBreedOfBrowser ", buf->used) == 0); EXPECT_EQ(buf->used, 24);
	
	buffer_destroy(buf);
}
Esempio n. 11
0
static int read_http_header(buffer *header, pool_t *p, int fd){
	int palloc_size = 1024;
	char *c ;
	char *ptr;

	c = palloc(p,sizeof(char));
	header->ptr = palloc(p, palloc_size);
	header->size = palloc_size;


	while(read(fd, c, 1)) {
		buffer_append_char(header,*c,p);
		if(*c == '\n' && header->used >= 2) {
			ptr =  header->ptr + header->used - 2;
			if(strncasecmp(ptr, "\n\n", 2) == 0) {
				return 0;
			}
		}
	}

	return 0;
}
Esempio n. 12
0
/**
 * A subparser function for compiler_build() that looks at the current token,
 * checks for a 'function' token. If found, it proceeds to evaluate the function
 * declaration, make note of the number of arguments, and store the index where
 * the function will begin in the byte code. This function then dispatches
 * subparsers that define stack variables, evaluate logical blocks (if, else,
 * while, etc), and evaluate straight code.
 * c: an instance of Compiler.
 * l: an instance of lexer. 
 * returns: false if the current token is not the start of a function declaration
 * ('function'), and true if it is. If an error occurs, function returns true,
 * but c->err is set to a relevant error code.
 */
static bool parse_function_definitions(Compiler * c, Lexer * l) {

  /*
   * A Function definition looks like so:
   *
   * function [EXPORTED] [NAME] ( [ARG1], [ARG2], ... ) {
   *   [code]
   * }
   * 
   * The code below parses these tokens and then dispatches the straight code
   * parsers to handle the function body.
   */
   
  bool exported = false;
  size_t len;
  LexerType type;
  char * token = lexer_current_token(l, &type, &len);
  char * name;
  size_t nameLen;
  int numArgs;
  int numVars;

  /* check that this is a function declaration token */
  if(!tokens_equal(token, len, LANG_FUNCTION, LANG_FUNCTION_LEN)) {
    c->err = COMPILERERR_UNEXPECTED_TOKEN;
    return false;
  }

  /* advance to next token. if is is EXPORTED, take note for later */
  token = lexer_next(l, &type, &len);
  if(tokens_equal(token, len, LANG_EXPORTED, LANG_EXPORTED_LEN)) {
    exported = true;
    token = lexer_next(l, &type, &len);
  }

  /* this is the name token, store it and check for correct type */
  name = token;
  nameLen = len;
  if(type != LEXERTYPE_KEYVAR || is_keyword(name, nameLen)) {
    c->err = COMPILERERR_EXPECTED_FNAME;
    return true;
  }

  /* check if name is too long */
  if(nameLen > GS_MAX_FUNCTION_NAME_LEN) {
    c->err = COMPILERERR_FUNCTION_NAME_TOO_LONG;
    return true;
  }

  /* check for the open parenthesis */
  token = lexer_next(l, &type, &len);
  if(!tokens_equal(token, len, LANG_OPARENTH, LANG_OPARENTH_LEN)) {
    c->err = COMPILERERR_EXPECTED_OPARENTH;
    return true;
  }

  /* we're going down a level. push new symbol table to stack */
  if(!symtblstk_push(c)) {
    c->err = COMPILERERR_ALLOC_FAILED;
    return true;
  }

  /* parse the arguments, return if the process fails */
  if((numArgs = parse_arguments(c, l)) == -1) {
    return true;
  }

  /* check for open brace defining start of function "{" */
  token = lexer_next(l, &type, &len);
  if(!tokens_equal(token, len, LANG_OBRACKET, LANG_OBRACKET_LEN)) {
    c->err = COMPILERERR_EXPECTED_OBRACKET;
    return true;
  }
  token = lexer_next(l, &type, &len);

  /****************************** Do function body ****************************/
  
  /* handle variable declarations */
  if((numVars = define_variables(c, l)) == -1) {
    return false;
  }

  /* retrieve next token (it was modified by define_variable */
  token = lexer_current_token(l, &type, &len);

  /* store the function name, location in the output, and # of args and vars */
  if(!function_store_definition(c, name, nameLen, numArgs, numVars, exported)) {
    return true;
  }

  if(!parse_body(c, l)) {
    return true;
  }

  /* retrieve current token (it was modified by parse_body) */
  token = lexer_current_token(l, &type, &len);

  /****************************** End function body ***************************/

  /* check for closing brace defining end of body "}" */
  if(!tokens_equal(token, len, LANG_CBRACKET, LANG_CBRACKET_LEN)) {
    c->err = COMPILERERR_EXPECTED_CBRACKET;
    return true;
  }

  /* push default return value. if no other return is given, this value is 
   * returned */
  buffer_append_char(vm_buffer(c->vm), OP_NULL_PUSH);

  /* pop function frame and return to calling function */
  buffer_append_char(vm_buffer(c->vm), OP_FRM_POP);

  token = lexer_next(l, &type, &len);

  /* we're done here! pop the symbol table for this function off the stack. */
  ht_free(symtblstk_pop(c));

  return true;
}
Esempio n. 13
0
/**
	process_run : cmd:string -> args:string array -> 'process
	<doc>
	Start a process using a command and the specified arguments.
	When args is not null, cmd and args will be auto-quoted/escaped.
	If no auto-quoting/escaping is desired, you should append necessary 
	arguments to cmd as if it is inputted to the shell directly, and pass
	null as args.
	</doc>
**/
static value process_run( value cmd, value vargs ) {
	int i, isRaw;
	vprocess *p;
	val_check(cmd,string);
	isRaw = val_is_null(vargs);
	if (!isRaw) {
		val_check(vargs,array);
	}
#	ifdef NEKO_WINDOWS
	{		 
		SECURITY_ATTRIBUTES sattr;		
		STARTUPINFO sinf;
		HANDLE proc = GetCurrentProcess();
		HANDLE oread,eread,iwrite;
		// creates commandline
		buffer b = alloc_buffer(NULL);
		value sargs;
		if (isRaw) {
			char* cmdexe = getenv("COMSPEC");
			if (!cmdexe) cmdexe = "cmd.exe";
			buffer_append(b,"\"");
			buffer_append(b,cmdexe);
			buffer_append(b,"\" /C \"");
			buffer_append(b,val_string(cmd));
			buffer_append_char(b,'"');
		} else {
			buffer_append_char(b,'"');
			val_buffer(b,cmd);
			buffer_append_char(b,'"');
			for(i=0;i<val_array_size(vargs);i++) {
				value v = val_array_ptr(vargs)[i];
				int j,len;
				unsigned int bs_count = 0;
				unsigned int k;
				val_check(v,string);
				len = val_strlen(v);
				buffer_append(b," \"");
				for(j=0;j<len;j++) {
					char c = val_string(v)[j];
					switch( c ) {
					case '"':
						// Double backslashes.
						for (k=0;k<bs_count*2;k++) {
							buffer_append_char(b,'\\');
						}
						bs_count = 0;
						buffer_append(b, "\\\"");
						break;
					case '\\':
						// Don't know if we need to double yet.
						bs_count++;
						break;
					default:
						// Normal char
						for (k=0;k<bs_count;k++) {
							buffer_append_char(b,'\\');
						}
						bs_count = 0;
						buffer_append_char(b,c);
						break;
					}
				}
				// Add remaining backslashes, if any.
				for (k=0;k<bs_count*2;k++) {
					buffer_append_char(b,'\\');
				}
				buffer_append_char(b,'"');
			}
		}
		sargs = buffer_to_string(b);
		p = (vprocess*)alloc_private(sizeof(vprocess));
		// startup process
		sattr.nLength = sizeof(sattr);
		sattr.bInheritHandle = TRUE;
		sattr.lpSecurityDescriptor = NULL;
		memset(&sinf,0,sizeof(sinf));
		sinf.cb = sizeof(sinf);
		sinf.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
		sinf.wShowWindow = SW_HIDE;
		CreatePipe(&oread,&sinf.hStdOutput,&sattr,0);
		CreatePipe(&eread,&sinf.hStdError,&sattr,0);
		CreatePipe(&sinf.hStdInput,&iwrite,&sattr,0);
		DuplicateHandle(proc,oread,proc,&p->oread,0,FALSE,DUPLICATE_SAME_ACCESS);
		DuplicateHandle(proc,eread,proc,&p->eread,0,FALSE,DUPLICATE_SAME_ACCESS);
		DuplicateHandle(proc,iwrite,proc,&p->iwrite,0,FALSE,DUPLICATE_SAME_ACCESS);
		CloseHandle(oread);
		CloseHandle(eread);
		CloseHandle(iwrite);
		if( !CreateProcess(NULL,val_string(sargs),NULL,NULL,TRUE,0,NULL,NULL,&sinf,&p->pinf) )			
			neko_error();
		// close unused pipes
		CloseHandle(sinf.hStdOutput);
		CloseHandle(sinf.hStdError);
		CloseHandle(sinf.hStdInput);
	}
#	else
	char **argv;
	if (isRaw) {
		argv = (char**)alloc_private(sizeof(char*)*4);
		argv[0] = "/bin/sh";
		argv[1] = "-c";
		argv[2] = val_string(cmd);
		argv[3] = NULL;
	} else {
		argv = (char**)alloc_private(sizeof(char*)*(val_array_size(vargs)+2));
		argv[0] = val_string(cmd);
		for(i=0;i<val_array_size(vargs);i++) {
			value v = val_array_ptr(vargs)[i];
			val_check(v,string);
			argv[i+1] = val_string(v);
		}
		argv[i+1] = NULL;
	}
	int input[2], output[2], error[2];
	if( pipe(input) || pipe(output) || pipe(error) )
		neko_error();
	p = (vprocess*)alloc_private(sizeof(vprocess));
	p->pid = fork();
	if( p->pid == -1 ) {
		do_close(input[0]);
		do_close(input[1]);
		do_close(output[0]);
		do_close(output[1]);
		do_close(error[0]);
		do_close(error[1]);
		neko_error();
	}
	// child
	if( p->pid == 0 ) {
		close(input[1]);
		close(output[0]);
		close(error[0]);
		dup2(input[0],0);
		dup2(output[1],1);
		dup2(error[1],2);
		execvp(argv[0],argv);
		fprintf(stderr,"Command not found : %s\n",val_string(cmd));
		exit(1);
	}
	// parent
	do_close(input[0]);
	do_close(output[1]);
	do_close(error[1]);
	p->iwrite = input[1];
	p->oread = output[0];
	p->eread = error[0];
#	endif
	{
		value vp = alloc_abstract(k_process,p);
		val_gc(vp,free_process);
		return vp;
	}
}
Esempio n. 14
0
enum json_error json_parser_scan_whitespace(const char** in, const char* end, struct whitespace* out) {

	assert(*in < end);

	struct buffer buffer = { .content = NULL, .length = 0, .size = 0 };

	while(*in < end) {
		if(**in != 0x20 && **in != 0x09 && **in != 0x0A && **in != 0x0D) {
			break;
		}
		if(out) buffer_append(&buffer, *in, 1);
		(*in)++;
	}

	if(buffer.length != 0) {
		out->content = buffer.content;
		out->length = buffer.length;
	}

	return JSON_ERROR_OK;
}


enum json_error json_parser_scan_object(const char** in, const char* end, struct json_object* out) {

	assert(*in < end);

	if(**in != '{') return JSON_ERROR_OK;

	(*in)++;

	struct json_string* keys = NULL;
	struct json_value* values = NULL;
	unsigned int size = 0, length = 0;
//	struct whitespace* whitespaces = NULL;
//	unsigned int whitespaces_size = 0, whitespaces_length = 0;

	enum json_error error;

	const char* tmp_pos;
	struct whitespace whitespace = { .length = 0 };

	while(*in < end) {

		json_parser_scan_whitespace(in, end, &whitespace);
//		if(whitespace.length) {
//			whitespace.length = 0;
//		}

		if(*in >= end) goto unexpected_end;

		struct json_string key;
		tmp_pos = *in;
		error = json_parser_scan_string(in, end, &key);
		if(error) goto error;
		if(*in == tmp_pos) break;
		if(*in >= end) goto unexpected_end;

		json_parser_scan_whitespace(in, end, &whitespace);
//		if(whitespace.length) {
//			whitespace.length = 0;
//		}

		if(*in >= end) goto unexpected_end;

		if(**in != ':') {
			error = JSON_ERROR_UNEXPECTED_TOKEN;
			goto error;
		}

		(*in)++;
		if(*in >= end) goto unexpected_end;

		json_parser_scan_whitespace(in, end, &whitespace);
//		if(whitespace.length) {
//			whitespace.length = 0;
//		}

		if(*in >= end) goto unexpected_end;

		struct json_value value;
		tmp_pos = *in;
		error = json_parser_scan_value(in, end, &value);
		if(error) goto error;
		if(*in == tmp_pos) {
			error = JSON_ERROR_UNEXPECTED_TOKEN;
			goto error;
		}

		if(size < length + 1) {
			if(size == 0) {
				size = 1;
				keys = malloc(sizeof(struct json_string));
				values = malloc(sizeof(struct json_value));
			} else {
				size *= 2;
				keys = realloc(keys, sizeof(struct json_string) * size);
				values = realloc(values, sizeof(struct json_value) * size);
			}
		}

		keys[length] = key;
		values[length] = value;
		length++;

		if(*in >= end) goto unexpected_end;

		tmp_pos = *in;
		json_parser_scan_whitespace(in, end, &whitespace);
//		if(whitespace.length) {
//			whitespace.length = 0;
//		}

		if(*in >= end) goto unexpected_end;

		if(**in != ',') break;

		(*in)++;
	}

	if(*in >= end) goto unexpected_end;

	if(**in != '}') {
		error = JSON_ERROR_UNEXPECTED_TOKEN;
		goto error;
	}

	(*in)++;

	out->keys = keys;
	out->values = values;
	out->length = length;
//	out->whitespaces = whitespaces;
//	out->whitespaces_length = whitespaces_length;

	return JSON_ERROR_OK;

 unexpected_end:

 	error = JSON_ERROR_UNEXPECTED_END;

 error:

	free(keys);
	free(values);
//	free(whitespaces);

 	return error;
}


enum json_error json_parser_scan_array(const char** in, const char* end, struct json_array* out) {

	assert(*in < end);

	if(**in != '[') return JSON_ERROR_OK;

	(*in)++;

	struct json_value* values = NULL;
	unsigned int size = 0, length = 0;
//	struct whitespace* whitespaces = NULL;
//	unsigned int whitespaces_size = 0, whitespaces_length = 0;

	enum json_error error;

	const char* tmp_pos;
	struct whitespace whitespace = { .length = 0 };

	while(*in < end) {

		json_parser_scan_whitespace(in, end, &whitespace);
//		if(whitespace.length) {
//			whitespace.length = 0;
//		}

		if(*in >= end) goto unexpected_end;

		struct json_value value;
		tmp_pos = *in;
		error = json_parser_scan_value(in, end, &value);
		if(error) goto error;
		if(*in == tmp_pos) {
			if(length == 0) break;
			error = JSON_ERROR_UNEXPECTED_TOKEN;
			goto error;
		}

		if(size < length + 1) {
			if(size == 0) {
				size = 1;
				values = malloc(sizeof(struct json_value));
			} else {
				size *= 2;
				values = realloc(values, sizeof(struct json_value) * size);
			}
		}

		values[length] = value;
		length++;

		if(*in >= end) goto unexpected_end;

		tmp_pos = *in;
		json_parser_scan_whitespace(in, end, &whitespace);
//		if(whitespace.length) {
//			whitespace.length = 0;
//		}

		if(*in >= end) goto unexpected_end;

		if(**in != ',') break;

		(*in)++;
	}

	if(*in >= end) goto unexpected_end;

	if(**in != ']') {
		error = JSON_ERROR_UNEXPECTED_TOKEN;
		goto error;
	}

	(*in)++;
	out->values = values;
	out->length = length;
//	out->whitespaces = whitespaces;
//	out->whitespaces_length = whitespaces_length;

	return JSON_ERROR_OK;

 unexpected_end:

 	error = JSON_ERROR_UNEXPECTED_END;

 error:

	free(values);
//	free(whitespaces);

 	return error;

}


enum json_error json_parser_scan_string(const char** in, const char* end, struct json_string* out) {
	assert(*in < end);

	if(**in != '"') return JSON_ERROR_OK;

	struct buffer buffer = { .content = NULL, .length = 0, .size = 0 };

	enum json_error error = 0;

	(*in)++;

	while(*in < end) {

		unsigned char c = **in;

		if(c == '"') break;

		if(c != '\\') {

			if(c <= 0x1f || c == 0x7f) { // disable control characters
				error = JSON_ERROR_UNEXPECTED_TOKEN;
				goto error;
			}

			buffer_append(&buffer, &c, 1);

		} else {

			(*in)++;

			if(*in >= end) goto unexpected_end;

			// early declaration
			uint16_t unicode_char;
			const char* uend = *in + 5;

			switch(**in) {
			default:
				error = JSON_ERROR_UNEXPECTED_TOKEN;
				goto error;
			case '"':
			case '\\':
			case '/':
				c = **in;
				break;
			case 'b':
				c = '\b';
				break;
			case 'f':
				c = '\f';
				break;
			case 'n':
				c = '\n';
				break;
			case 'r':
				c = '\r';
				break;
			case 't':
				c = '\t';
				break;
			case 'u':
				if(uend > end) goto unexpected_end;

				(*in)++;

				unicode_char = 0;

				while(1) {
					unsigned char c;
					if(**in >= '0' && **in <= '9') c= **in - '0';
					else if(**in >= 'a' && **in <= 'f') c = **in - 'a' + 10;
					else if(**in >= 'A' && **in <= 'F') c = **in - 'A' + 10;
					else {
						error = JSON_ERROR_UNEXPECTED_TOKEN;
						goto error;
					}
					unicode_char |= c;
					(*in)++;
					if(*in >= uend) break;
					unicode_char <<= 4;
				}

//				printf("Unicode in: %x\n", unicode_char);

				// FIXME: I guess this could be optimized/cleaned
				if(unicode_char < 0x80) {
//					printf("Bytes: %x\n", unicode_char);
					buffer_append_char(&buffer, (unicode_char & 0xff));
				} else if(unicode_char < 0x800) {
					unsigned char firstByte = 0xc0 | (0x1f & (unicode_char >> 6));
					unsigned char secondByte = 0x80 | (0x3f & unicode_char);
//					printf("Bytes: %x %x\n", firstByte, secondByte);
					buffer_append_char(&buffer, firstByte);
					buffer_append_char(&buffer, secondByte);
				} else {
					unsigned char firstByte = 0xe0 | (0x1f & (unicode_char >> 12));
					unsigned char secondByte = 0x80 | (0x3f & (unicode_char >> 6));
					unsigned char thirdByte = 0x80 | (0x3f & unicode_char);
//					printf("Bytes: %x %x %x\n", firstByte, secondByte, thirdByte);
					buffer_append_char(&buffer, firstByte);
					buffer_append_char(&buffer, secondByte);
					buffer_append_char(&buffer, thirdByte);
				}
				continue;
			}
			buffer_append(&buffer, &c, 1);
		}

		(*in)++;
	}
Esempio n. 15
0
/**
	process_run_raw : cmd:string -> 'process
	<doc>
	Start a process using a command. The input string contains
	the command as well as the arguments. Shell meta-characters
	will not be auto escaped/quoted. 
	</doc>
**/
CAMLprim value process_run_raw( value cmd ) {
	int i;
	vprocess *p;
	val_check(cmd,string);
	char* cmdStr = val_string(cmd);
#	ifdef _WIN32
	{
		SECURITY_ATTRIBUTES sattr;
		STARTUPINFO sinf;
		HANDLE proc = GetCurrentProcess();
		HANDLE oread,eread,iwrite;
		// creates commandline
		buffer b = alloc_buffer(NULL);
		char *sargs;
		buffer_append_char(b,'"');
		char* cmdexe = getenv("COMSPEC");
		if (!cmdexe) cmdexe = "cmd.exe";
		buffer_append_str(b,cmdexe);
		buffer_append_char(b,'"');
		buffer_append_str(b,"/C \"");
		buffer_append_str(b,cmdStr);
		buffer_append_char(b,'"');
		sargs = buffer_to_string(b);
		p = (vprocess*)alloc_private(sizeof(vprocess));
		// startup process
		sattr.nLength = sizeof(sattr);
		sattr.bInheritHandle = TRUE;
		sattr.lpSecurityDescriptor = NULL;
		memset(&sinf,0,sizeof(sinf));
		sinf.cb = sizeof(sinf);
		sinf.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
		sinf.wShowWindow = SW_HIDE;
		CreatePipe(&oread,&sinf.hStdOutput,&sattr,0);
		CreatePipe(&eread,&sinf.hStdError,&sattr,0);
		CreatePipe(&sinf.hStdInput,&iwrite,&sattr,0);
		DuplicateHandle(proc,oread,proc,&p->oread,0,FALSE,DUPLICATE_SAME_ACCESS);
		DuplicateHandle(proc,eread,proc,&p->eread,0,FALSE,DUPLICATE_SAME_ACCESS);
		DuplicateHandle(proc,iwrite,proc,&p->iwrite,0,FALSE,DUPLICATE_SAME_ACCESS);
		CloseHandle(oread);
		CloseHandle(eread);
		CloseHandle(iwrite);
		
		if( !CreateProcess(NULL,val_string(sargs),NULL,NULL,TRUE,0,NULL,NULL,&sinf,&p->pinf) ) {
			CloseHandle(p->eread);
			CloseHandle(p->oread);
			CloseHandle(p->iwrite);
			free(sargs);
			neko_error();
		}
		free(sargs);
		// close unused pipes
		CloseHandle(sinf.hStdOutput);
		CloseHandle(sinf.hStdError);
		CloseHandle(sinf.hStdInput);
	}
#	else
	char **argv = (char**)alloc_private(sizeof(char*)*4);
	argv[0] = cmd = "/bin/sh";
	argv[1] = "-c";
	argv[2] = cmdStr;
	argv[3] = NULL;
	int input[2], output[2], error[2];
	if( pipe(input) || pipe(output) || pipe(error) )
		neko_error();
	p = (vprocess*)alloc_private(sizeof(vprocess));
	p->pid = fork();
	if( p->pid == -1 ) {
		do_close(input[0]);
		do_close(input[1]);
		do_close(output[0]);
		do_close(output[1]);
		do_close(error[0]);
		do_close(error[1]);
		neko_error();
	}
	// child
	if( p->pid == 0 ) {
		close(input[1]);
		close(output[0]);
		close(error[0]);
		dup2(input[0],0);
		dup2(output[1],1);
		dup2(error[1],2);
		execvp(val_string(cmd),argv);
		fprintf(stderr,"Command not found : %s\n",val_string(cmd));
		exit(1);
	}
	// parent
	do_close(input[0]);
	do_close(output[1]);
	do_close(error[1]);
	p->iwrite = input[1];
	p->oread = output[0];
	p->eread = error[0];
#	endif
	{
		value vp = alloc_abstract(k_process,p);
		val_gc(vp,free_process);
		return vp;
	}
}
Esempio n. 16
0
GSAPI bool gunderscript_import_bytecode(Gunderscript * instance, char * fileName) {
  DSValue value;
  FILE * inFile = fopen(fileName, "r");
  GSByteCodeHeader header;
  int i = 0;

  if(inFile == NULL) {
    instance->err = GUNDERSCRIPTERR_BAD_FILE_OPEN_READ;
    return false;
  }

  /* read header */
  if(fread(&header, sizeof(GSByteCodeHeader), 1, inFile) != 1) {
    instance->err = GUNDERSCRIPTERR_BAD_FILE_READ;
    fclose(inFile);
    return false;
  }

  /* check for header */
  if(strcmp(header.header, GS_BYTECODE_HEADER) != 0) {
    instance->err = GUNDERSCRIPTERR_NOT_BYTECODE_FILE;
    fclose(inFile);
    return false;
  }

  /* check that this build is the same as the one that created the file */
  if(strcmp(header.buildDate, GUNDERSCRIPT_BUILD_DATE) != 0) {
    instance->err = GUNDERSCRIPTERR_INCORRECT_RUNTIME_VERSION;
    fclose(inFile);
    return false;
  }

  /* check that the number of functions isn't negative or zero */
  if(header.numFunctions < 1) {
    instance->err = GUNDERSCRIPTERR_CORRUPTED_BYTECODE;
    return false;
  }

  /* import the exported functions definitions (script entry points) */
  for(i = 0; i < header.numFunctions; i++) {
    VMFunc * currentFunc = calloc(1, sizeof(VMFunc));
    char functionName[GS_MAX_FUNCTION_NAME_LEN];
    char functionNameLen;
    bool prevValue = false;

    /* check if VMFunc alloc failed */
    if(currentFunc == NULL) {
      instance->err = GUNDERSCRIPTERR_ALLOC_FAILED;
      fclose(inFile);
      return false;
    }

    /* read function name length */
    if(fread(&functionNameLen, sizeof(char), 1, inFile) != 1) {
      instance->err = GUNDERSCRIPTERR_BAD_FILE_READ;
      return false;
    }

    /* check function name length */
    if(functionNameLen > GS_MAX_FUNCTION_NAME_LEN) {
      instance->err = GUNDERSCRIPTERR_CORRUPTED_BYTECODE;
      fclose(inFile);
      return false;
    }

    /* read function name */
    if(fread(&functionName, sizeof(char), functionNameLen, inFile) 
       != functionNameLen) {
      instance->err = GUNDERSCRIPTERR_BAD_FILE_READ;
      fclose(inFile);
      return false;
    }
    
    /* read from file into new VMFunc */
    value.pointerVal = currentFunc;
    if(fread(currentFunc, sizeof(VMFunc), 1, inFile) != 1) {
      instance->err = GUNDERSCRIPTERR_BAD_FILE_READ;
      fclose(inFile);
      return false;
    }

    /* put functions into VM functions hashtable */
    if(!ht_put_raw_key(vm_functions(instance->vm), functionName, 
		       functionNameLen, &value, NULL, &prevValue)) {
      instance->err = GUNDERSCRIPTERR_ALLOC_FAILED;
      fclose(inFile);
      return false;
    }

    /* check for duplicate function names */
    if(prevValue) {
      instance->err = GUNDERSCRIPTERR_CORRUPTED_BYTECODE;
      fclose(inFile);
      return false;
    }
  }

  /* make space in buffer for the bytecode */
  if(!buffer_resize(vm_buffer(instance->vm), header.byteCodeLen)) {
    instance->err = GUNDERSCRIPTERR_ALLOC_FAILED;
    fclose(inFile);
    return false;
  }

  /* read raw bytecode from end of bytecode file */
  {
    int c, i;
    for(i = 0; (c = fgetc(inFile)) != -1; i++) {
      buffer_append_char(vm_buffer(instance->vm), (char)c);
    }

    if(i != (header.byteCodeLen)) {
      instance->err = GUNDERSCRIPTERR_BAD_FILE_READ;
      fclose(inFile);
      return false;
    }
  }

  fclose(inFile);
  return true;
}
Esempio n. 17
0
/**
	process_run : cmd:string -> args:string array -> 'process
	<doc>
	Start a process using a command and the specified arguments.
	</doc>
**/
CAMLprim value process_run( value cmd, value vargs ) {
	int i;
	vprocess *p;
	val_check(cmd,string);
	val_check(vargs,array);
#	ifdef _WIN32
	{
		SECURITY_ATTRIBUTES sattr;
		STARTUPINFO sinf;
		HANDLE proc = GetCurrentProcess();
		HANDLE oread,eread,iwrite;
		// creates commandline
		buffer b = alloc_buffer(NULL);
		char *sargs;
		buffer_append_char(b,'"');
		buffer_append_str(b,val_string(cmd));
		buffer_append_char(b,'"');
		for(i=0;i<val_array_size(vargs);i++) {
			value v = val_array_ptr(vargs)[i];
			int j,len;
			val_check(v,string);
			len = val_strlen(v);
			buffer_append_str(b," \"");
			for(j=0;j<len;j++) {
				char c = val_string(v)[j];
				switch( c ) {
				case '"':
					buffer_append_str(b,"\\\"");
					break;
				case '\\':
					buffer_append_str(b,"\\\\");
					break;
				default:
					buffer_append_char(b,c);
					break;
				}
			}
			buffer_append_char(b,'"');
		}
		sargs = buffer_to_string(b);
		p = (vprocess*)alloc_private(sizeof(vprocess));
		// startup process
		sattr.nLength = sizeof(sattr);
		sattr.bInheritHandle = TRUE;
		sattr.lpSecurityDescriptor = NULL;
		memset(&sinf,0,sizeof(sinf));
		sinf.cb = sizeof(sinf);
		sinf.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
		sinf.wShowWindow = SW_HIDE;
		CreatePipe(&oread,&sinf.hStdOutput,&sattr,0);
		CreatePipe(&eread,&sinf.hStdError,&sattr,0);
		CreatePipe(&sinf.hStdInput,&iwrite,&sattr,0);
		DuplicateHandle(proc,oread,proc,&p->oread,0,FALSE,DUPLICATE_SAME_ACCESS);
		DuplicateHandle(proc,eread,proc,&p->eread,0,FALSE,DUPLICATE_SAME_ACCESS);
		DuplicateHandle(proc,iwrite,proc,&p->iwrite,0,FALSE,DUPLICATE_SAME_ACCESS);
		CloseHandle(oread);
		CloseHandle(eread);
		CloseHandle(iwrite);
		
		if( !CreateProcess(NULL,val_string(sargs),NULL,NULL,TRUE,0,NULL,NULL,&sinf,&p->pinf) ) {
			CloseHandle(p->eread);
			CloseHandle(p->oread);
			CloseHandle(p->iwrite);
			free(sargs);
			neko_error();
		}
		free(sargs);
		// close unused pipes
		CloseHandle(sinf.hStdOutput);
		CloseHandle(sinf.hStdError);
		CloseHandle(sinf.hStdInput);
	}
#	else
	char **argv = (char**)alloc_private(sizeof(char*)*(val_array_size(vargs)+2));
	argv[0] = val_string(cmd);
	for(i=0;i<val_array_size(vargs);i++) {
		value v = val_array_ptr(vargs)[i];
		val_check(v,string);
		argv[i+1] = val_string(v);
	}
	argv[i+1] = NULL;
	int input[2], output[2], error[2];
	if( pipe(input) || pipe(output) || pipe(error) )
		neko_error();
	p = (vprocess*)alloc_private(sizeof(vprocess));
	p->pid = fork();
	if( p->pid == -1 ) {
		do_close(input[0]);
		do_close(input[1]);
		do_close(output[0]);
		do_close(output[1]);
		do_close(error[0]);
		do_close(error[1]);
		neko_error();
	}
	// child
	if( p->pid == 0 ) {
		close(input[1]);
		close(output[0]);
		close(error[0]);
		dup2(input[0],0);
		dup2(output[1],1);
		dup2(error[1],2);
		execvp(val_string(cmd),argv);
		fprintf(stderr,"Command not found : %s\n",val_string(cmd));
		exit(1);
	}
	// parent
	do_close(input[0]);
	do_close(output[1]);
	do_close(error[1]);
	p->iwrite = input[1];
	p->oread = output[0];
	p->eread = error[0];
#	endif
	{
		value vp = alloc_abstract(k_process,p);
		val_gc(vp,free_process);
		return vp;
	}
}