Beispiel #1
0
/**
	regexp_match : 'regexp -> string -> pos:int -> len:int -> bool
	<doc>Match [len] chars of a string starting at [pos] using the regexp.
	Return true if match found</doc>
**/
static value regexp_match( value o, value s, value p, value len ) {
	pcredata *d;
	int pp,ll;
	val_check_kind(o,k_regexp);
	val_check(s,string);
	val_check(p,int);
	val_check(len,int);
	pp = val_int(p);
	ll = val_int(len);
	if( pp < 0 || ll < 0 || pp > val_strlen(s) || pp + ll > val_strlen(s) )
		neko_error();
	d = PCRE(o);
	if( pcre_exec(d->r,NULL,val_string(s)+pp,ll,0,0,d->matchs,d->nmatchs * 3) >= 0 ) {
		if( pp > 0 ) {
			int i;
			for(i=0;i<d->nmatchs * 3;i++)
				d->matchs[i] += pp;
		}
		d->str = s;
		return val_true;
	} else {
		d->str = val_null;
		return val_false;
	}
}
Beispiel #2
0
/**
	file_write : 'file -> s:string -> p:int -> l:int -> int
	<doc>
	Write up to [l] chars of string [s] starting at position [p]. 
	Returns the number of chars written which is >= 0.
	</doc>
**/
static value file_write( value o, value s, value pp, value n ) {
	int p, len;
	fio *f;
	val_check_kind(o,k_file);
	val_check(s,string);
	val_check(pp,int);
	val_check(n,int);
	f = val_file(o);
	p = val_int(pp);
	len = val_int(n);
	if( p < 0 || len < 0 || p > val_strlen(s) || p + len > val_strlen(s) )
		neko_error();
	while( len > 0 ) {
		int d;
		POSIX_LABEL(file_write_again);
		d = (int)fwrite(val_string(s)+p,1,len,f->io);
		if( d <= 0 ) {
			HANDLE_FINTR(f->io,file_write_again);
			file_error("file_write",f);
		}
		p += d;
		len -= d;
	}
	return n;
}
Beispiel #3
0
static value key_from_pem(value data, value pub, value pass){
	mbedtls_pk_context *pk;
	int r, len;
	value v;
	unsigned char *buf;
	val_check(data, string);
	val_check(pub, bool);
	if (!val_is_null(pass)) val_check(pass, string);
	len = val_strlen(data)+1;
	buf = (unsigned char *)alloc(len);
	memcpy(buf, val_string(data), len-1);
	buf[len-1] = '\0';
	pk = (mbedtls_pk_context *)alloc(sizeof(mbedtls_pk_context));
	mbedtls_pk_init(pk);
	if( val_bool(pub) )
		r = mbedtls_pk_parse_public_key( pk, buf, len );
	else if( val_is_null(pass) )
		r = mbedtls_pk_parse_key( pk, buf, len, NULL, 0 );
	else
		r = mbedtls_pk_parse_key( pk, buf, len, (const unsigned char*)val_string(pass), val_strlen(pass) );
	if( r != 0 ){
		mbedtls_pk_free(pk);
		return ssl_error(r);
	}
	v = alloc_abstract(k_pkey,pk);
	val_gc(v,free_pkey);
	return v;
}
Beispiel #4
0
/**
	file_read : 'file -> s:string -> p:int -> l:int -> int
	<doc>
	Read up to [l] chars into the string [s] starting at position [p].
	Returns the number of chars readed which is > 0 (or 0 if l == 0).
	</doc>
**/
static value file_read( value o, value s, value pp, value n ) {
	fio *f;
	int p;
	int len;
	val_check_kind(o,k_file);
	val_check(s,string);
	val_check(pp,int);
	val_check(n,int);
	f = val_file(o);
	p = val_int(pp);
	len = val_int(n);
	if( p < 0 || len < 0 || p > val_strlen(s) || p + len > val_strlen(s) )
		neko_error();
	while( len > 0 ) {
		int d;
		POSIX_LABEL(file_read_again);
		d = (int)fread((char*)val_string(s)+p,1,len,f->io);
		if( d <= 0 ) {
			int size = val_int(n) - len;
			HANDLE_FINTR(f->io,file_read_again);
			if( size == 0 )
				file_error("file_read",f);
			return alloc_int(size);
		}
		p += d;
		len -= d;
	}
	return n;
}
Beispiel #5
0
EXTERN int val_compare( value a, value b ) {
	char tmp_buf[32];
	switch( C(val_type(a),val_type(b)) ) {
	case C(VAL_INT,VAL_INT):
		return icmp(val_int(a),val_int(b));
	case C(VAL_INT32,VAL_INT):
		return icmp(val_int32(a),val_int(b));
	case C(VAL_INT,VAL_INT32):
		return icmp(val_int(a),val_int32(b));
	case C(VAL_INT32,VAL_INT32):
		return icmp(val_int32(a),val_int32(b));
	case C(VAL_INT,VAL_FLOAT):
		return fcmp(val_int(a),val_float(b));
	case C(VAL_INT32,VAL_FLOAT):
		return fcmp(val_int32(a),val_float(b));
	case C(VAL_INT,VAL_STRING):
		return scmp(tmp_buf,sprintf(tmp_buf,"%d",val_int(a)),val_string(b),val_strlen(b));
	case C(VAL_INT32,VAL_STRING):
		return scmp(tmp_buf,sprintf(tmp_buf,"%d",val_int32(a)),val_string(b),val_strlen(b));
	case C(VAL_FLOAT,VAL_INT):
		return fcmp(val_float(a),val_int(b));
	case C(VAL_FLOAT,VAL_INT32):
		return fcmp(val_float(a),val_int32(b));
	case C(VAL_FLOAT,VAL_FLOAT):
		return fcmp(val_float(a),val_float(b));
	case C(VAL_FLOAT,VAL_STRING):
		return scmp(tmp_buf,sprintf(tmp_buf,FLOAT_FMT,val_float(a)),val_string(b),val_strlen(b));
	case C(VAL_STRING,VAL_INT):
		return scmp(val_string(a),val_strlen(a),tmp_buf,sprintf(tmp_buf,"%d",val_int(b)));
	case C(VAL_STRING,VAL_INT32):
		return scmp(val_string(a),val_strlen(a),tmp_buf,sprintf(tmp_buf,"%d",val_int32(b)));
	case C(VAL_STRING,VAL_FLOAT):
		return scmp(val_string(a),val_strlen(a),tmp_buf,sprintf(tmp_buf,FLOAT_FMT,val_float(b)));
	case C(VAL_STRING,VAL_BOOL):
		return scmp(val_string(a),val_strlen(a),val_bool(b)?"true":"false",val_bool(b)?4:5);
	case C(VAL_BOOL,VAL_STRING):
		return scmp(val_bool(a)?"true":"false",val_bool(a)?4:5,val_string(b),val_strlen(b));
	case C(VAL_STRING,VAL_STRING):
		return scmp(val_string(a),val_strlen(a),val_string(b),val_strlen(b));
	case C(VAL_BOOL,VAL_BOOL):
		return (a == b) ? 0 : (val_bool(a) ? 1 : -1);
	case C(VAL_OBJECT,VAL_OBJECT):
		if( a == b )
			return 0;
		{
			value tmp = val_field(a,id_compare);
			if( tmp == val_null )
				return invalid_comparison;
			a = val_callEx(a,tmp,&b,1,NULL);
		}
		if( val_is_int(a) )
			return val_int(a);
		return invalid_comparison;
	default:
		if( a == b )
			return 0;
		return invalid_comparison;
	}
}
Beispiel #6
0
value neko_append_strings( value s1, value s2 ) {
	int len1 = val_strlen(s1);
	int len2 = val_strlen(s2);
	value v = alloc_empty_string(len1+len2);
	memcpy((char*)val_string(v),val_string(s1),len1);
	memcpy((char*)val_string(v)+len1,val_string(s2),len2+1);
	return v;
}
Beispiel #7
0
/**
	escape : 'connection -> string -> string
	<doc>Escape the string for inserting into a SQL request</doc>
**/
static value escape( value o, value s ) {
	int len;
	value sout;
	val_check_kind(o,k_connection);
	val_check(s,string);
	len = val_strlen(s) * 2;
	sout = alloc_empty_string(len);
	len = mysql_real_escape_string(CNX(o)->m,val_string(sout),val_string(s),val_strlen(s));
	val_set_length(sout,len);
	return sout;
}
Beispiel #8
0
/**
	buffer_add_sub : 'buffer -> s:string -> p:int -> l:int -> void
	<doc>Add [l] characters of the string [s] starting at position [p]. An error occurs if out of string bounds.</doc>
**/
static value buffer_add_sub( value b, value v, value p, value l ) {
	val_check_kind(b,k_buffer);
	val_check(v,string);
	val_check(p,int);
	val_check(l,int);	
	if( val_int(p) < 0 || val_int(l) < 0 )
		neko_error();
	if( val_strlen(v) < val_int(p) || val_strlen(v) < val_int(p) + val_int(l) )
		neko_error();
	buffer_append_sub( (buffer)val_data(b), val_string(v) + val_int(p) , val_int(l) );
	return val_true;
}
Beispiel #9
0
/**
	socket_send_to : 'socket -> buf:string -> pos:int -> length:int -> addr:{host:'int32,port:int} -> int
	<doc>
	Send data from an unconnected UDP socket to the given address.
	</doc>
**/
static value socket_send_to( value o, value data, value pos, value len, value vaddr ) {
	int p,l,dlen;
	value host, port;
	struct sockaddr_in addr;
	val_check_kind(o,k_socket);
	val_check(data,string);
	val_check(pos,int);
	val_check(len,int);
	val_check(vaddr,object);
	host = val_field(vaddr, f_host);
	port = val_field(vaddr, f_port);
	val_check(host,int32);
	val_check(port,int);
	p = val_int(pos);
	l = val_int(len);
	dlen = val_strlen(data);
	memset(&addr,0,sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(val_int(port));
	*(int*)&addr.sin_addr.s_addr = val_int32(host);
	if( p < 0 || l < 0 || p > dlen || p + l > dlen )
		neko_error();
	POSIX_LABEL(send_again);
	dlen = sendto(val_sock(o), val_string(data) + p , l, MSG_NOSIGNAL, (struct sockaddr*)&addr, sizeof(addr));
	if( dlen == SOCKET_ERROR ) {
		HANDLE_EINTR(send_again);
		return block_error();
	}
	return alloc_int(dlen);
}
Beispiel #10
0
/**
	socket_recv : 'socket -> buf:string -> pos:int -> len:int -> int
	<doc>Read up to [len] bytes from [buf] starting at [pos] from a connected socket.
	Return the number of bytes readed.</doc>
**/
static value socket_recv( value o, value data, value pos, value len ) {
	int p,l,dlen,ret;
	int retry = 0;
	val_check_kind(o,k_socket);
	val_check(data,string);
	val_check(pos,int);
	val_check(len,int);
	p = val_int(pos);
	l = val_int(len);
	dlen = val_strlen(data);
	if( p < 0 || l < 0 || p > dlen || p + l > dlen )
		neko_error();
	POSIX_LABEL(recv_again);
	if( retry++ > NRETRYS ) {
		sock_tmp t;
		t.sock = val_sock(o);
		t.buf = val_string(data) + p;
		t.size = l;
		neko_thread_blocking(tmp_recv,&t);
		ret = t.ret;
	} else
		ret = recv(val_sock(o), val_string(data) + p , l, MSG_NOSIGNAL);
	if( ret == SOCKET_ERROR ) {
		HANDLE_EINTR(recv_again);
		return block_error();
	}
	return alloc_int(ret);
}
Beispiel #11
0
/**
	udpr_write : ENetPeer-> data:string -> Channel->Reliable:Bool->void
	Send a full string [data]
**/
static value udpr_write(value p, value data, value chan, value reliable)
{
	ENetPeer *peer;
	ENetPacket *packet;
	int c;
	val_check_kind(p,k_udprpeer);
	val_check(data,string);
	val_check(chan,int);
	val_check(reliable,bool);

	c = val_int(chan);
	peer = (ENetPeer *)val_data(p);
#ifdef ENET_DEBUG_FULL
	fprintf(stderr, "udpr_write: Writing packet '%s' to peer %x on channel %d\n", val_string(data), peer, c);
	fprintf(stderr, "peer state: %d peer channels: %d\n", peer -> state, peer->channelCount);
#endif
	if(peer == NULL || c < 0 || c > 255)
		neko_error();

	packet = enet_packet_create(
		val_string(data),
		val_strlen(data),
		val_bool(reliable) ? ENET_PACKET_FLAG_RELIABLE : 0);
    if(enet_peer_send(peer, c, packet)) {
#ifdef ENET_DEBUG
		fprintf(stderr, "ERROR: udpr_write: enet_peer_send error\n");
		fprintf(stderr, "peer state: %d peer channels: %d\n", peer -> state, peer->channelCount);
#endif
    	neko_error();
    }
	return val_true;
}
Beispiel #12
0
static value dgst_sign(value data, value key, value alg){
	const mbedtls_md_info_t *md;
	int r = -1;
	size_t olen = 0;
	value out;
	unsigned char *buf;
	unsigned char hash[32];
	val_check(data, string);
	val_check_kind(key, k_pkey);
	val_check(alg, string);

	md = mbedtls_md_info_from_string(val_string(alg));
	if( md == NULL ){
		val_throw(alloc_string("Invalid hash algorithm"));
		return val_null;
	}

	if( (r = mbedtls_md( md, (const unsigned char *)val_string(data), val_strlen(data), hash )) != 0 )
		return ssl_error(r);

	out = alloc_empty_string(MBEDTLS_MPI_MAX_SIZE);
	buf = (unsigned char *)val_string(out);
	if( (r = mbedtls_pk_sign( val_pkey(key), mbedtls_md_get_type(md), hash, 0, buf, &olen, mbedtls_ctr_drbg_random, &ctr_drbg )) != 0 )
		return ssl_error(r);

	buf[olen] = 0;
	val_set_size(out, olen);
	return out;
}
Beispiel #13
0
/**
        udpr_send : peer -> data:string -> pos:int -> len:int -> chan:int -> reliable:bool -> int
        Send up to [len] bytes from [buf] starting at [pos] over a connected socket on channel [chan]
        using reliable setting [reliable]
        Return the number of bytes sent.
**/
static value udpr_send( value p, value data, value pos, value len, value chan, value reliable ) {
	ENetPeer *peer;
	ENetPacket *packet;
	int pp,l,sLen,c;
	val_check_kind(p,k_udprpeer);
	val_check(data,string);
	val_check(pos,int);
	val_check(len,int);
	val_check(chan,int);
	val_check(reliable,bool);

	peer = (ENetPeer *)val_data(p);
	pp = val_int(pos);
	l = val_int(len);
	sLen = val_strlen(data);
	c = val_int(chan);
	if( peer == NULL || c < 0 || c > 255 || pp < 0 || l < 0 || pp > sLen || pp + l > sLen )
			neko_error();
	packet = enet_packet_create(
		val_string(data) + pp,
		l,
		val_bool(reliable) ? ENET_PACKET_FLAG_RELIABLE : 0);
	if(enet_peer_send(peer, c, packet))
		neko_error();
	return alloc_int(l);
}
Beispiel #14
0
value hxfcgi_print(value hreq,value msg) {
	val_check(msg,string);
	hxfcgi::Request *req = get_request(hreq);
	req->printHeaders();
	for (int i = 0; i < val_strlen(msg);i++)
		req->pchar(val_string(msg)[i]);
	return val_null;
}
Beispiel #15
0
/**
	escape : 'connection -> string -> string
	<doc>Escape the string for inserting into a SQL request</doc>
**/
static value escape( value o, value s ) {
	int len;
	value sout;
	val_check_kind(o,k_connection);
	val_check(s,string);
	len = val_strlen(s) * 2;
	sout = alloc_empty_string(len);
	len = mysql_real_escape_string(CNX(o)->m,val_string(sout),val_string(s),val_strlen(s));
	if( len < 0 ) {
		buffer b = alloc_buffer("Unsupported charset : ");
		buffer_append(b,mysql_character_set_name(CNX(o)->m));
		bfailure(b);
	}
	val_set_length(sout,len);
	val_string(sout)[len] = 0;
	return sout;
}
Beispiel #16
0
/**
	update_crc32 : crc:'int32 -> string -> pos:int -> len:int -> 'int32
	<doc>Update a CRC32 value with a substring</doc>
**/
static value update_crc32( value crc, value s, value pos, value len ) {
	val_check(crc,int);
	val_check(s,string);
	val_check(pos,int);
	val_check(len,int);
	if( val_int(pos) < 0 || val_int(len) < 0 || val_int(pos) + val_int(len) > val_strlen(s) )
		return alloc_null();
	return alloc_int32(crc32(val_int(crc),(Bytef*)(val_string(s)+val_int(pos)),val_int(len)));
}
Beispiel #17
0
// String access
int api_val_strlen(value  arg1)
{
	if (val_is_string(arg1))
	   return val_strlen(arg1);
	value l =  val_field(arg1,length_id);
	if (val_is_int(l))
		return val_int(l);
	return 0;
}
Beispiel #18
0
/**
	$sget : string -> n:int -> int?
	<doc>Return the [n]th char of a string or [null] if out of bounds</doc>
**/
static value builtin_sget( value s, value p ) {
	int pp;
	val_check(s,string);
	val_check(p,int);
	pp = val_int(p);
	if( pp < 0 || pp >= val_strlen(s) )
		return val_null;
	return alloc_int( (unsigned char)(val_string(s)[pp]) );
}
Beispiel #19
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;
}
Beispiel #20
0
/**
	$sfind : src:string -> pos:int -> pat:string -> int?
	<doc>
	Return the first position starting at [pos] in [src] where [pat] was found.
	Return null if not found. Error if [pos] is outside [src] bounds.
	</doc>
**/
static value builtin_sfind( value src, value pos, value pat ) {
	int p, l, l2;
	const char *ptr;
	val_check(src,string);
	val_check(pos,int);
	val_check(pat,string);
	p = val_int(pos);
	l = val_strlen(src);
	l2 = val_strlen(pat);
	if( p < 0 || p >= l )
		neko_error();
	ptr = val_string(src) + p;
	while( l - p >= l2 ) {
		if( memcmp(ptr,val_string(pat),l2) == 0 )
			return alloc_int(p);
		p++;
		ptr++;
	}
	return val_null;
}
Beispiel #21
0
/**
	$ssub : string -> p:int -> l:int -> string
	<doc>
	Return [l] chars starting at position [p] of a string.
	An error occurs if out of string bounds.
	</doc>
**/
static value builtin_ssub( value s, value p, value l ) {
	int pp , ll;
	val_check(s,string);
	val_check(p,int);
	val_check(l,int);
	pp = val_int(p);
	ll = val_int(l);
	if( pp < 0 || ll < 0 || pp + ll < 0 || pp + ll > val_strlen(s) )
		neko_error();
	return copy_string( val_string(s) + pp , ll );
}
Beispiel #22
0
/**
	sys_command : string -> int
	<doc>Run the shell command and return exit code</doc>
**/
static value sys_command( value cmd ) {
	val_check(cmd,string);
	if( val_strlen(cmd) == 0 )
		return alloc_int(-1);
#ifdef NEKO_WINDOWS
	return alloc_int( system(val_string(cmd)) );
#else
	int status = system(val_string(cmd));
	return alloc_int( WEXITSTATUS(status) | (WTERMSIG(status) << 8) );
#endif
}
Beispiel #23
0
/**
	regexp_match : 'regexp -> string -> pos:int -> len:int -> bool
	<doc>Match [len] chars of a string starting at [pos] using the regexp.
	Return true if match found</doc>
**/
static value regexp_match( value o, value s, value p, value len ) {
	pcredata *d;
	int pp,ll;
	val_check_kind(o,k_regexp);
	val_check(s,string);
	val_check(p,int);
	val_check(len,int);
	pp = val_int(p);
	ll = val_int(len);
	if( pp < 0 || ll < 0 || pp > val_strlen(s) || pp + ll > val_strlen(s) )
		return alloc_null();
	d = PCRE(o);
	if( pcre_exec(d->r,NULL,val_string(s),ll+pp,pp,0,d->matchs,d->nmatchs * 3) >= 0 ) {
		d->str = s;
		return alloc_bool(true);
	} else {
		d->str = alloc_null();
		return alloc_bool(false);
	}
}
Beispiel #24
0
/**
	regexp_match : 'regexp -> string -> pos:int -> len:int -> bool
	<doc>Match [len] chars of a string starting at [pos] using the regexp.
	Return true if match found</doc>
**/
static value regexp_match( value o, value s, value p, value len ) {
	pcredata *d;
	int pp,ll;
	val_check_kind(o,k_regexp);
	val_check(s,string);
	val_check(p,int);
	val_check(len,int);
	pp = val_int(p);
	ll = val_int(len);
	if( pp < 0 || ll < 0 || pp > val_strlen(s) || pp + ll > val_strlen(s) )
		neko_error();
	d = PCRE(o);
	if( do_exec(d,val_string(s),ll+pp,pp) ) {
		d->str = s;
		return val_true;
	} else {
		d->str = val_null;
		return val_false;
	}
}
Beispiel #25
0
static value key_from_der( value data, value pub ){
	mbedtls_pk_context *pk;
	int r;
	value v;
	val_check(data, string);
	val_check(pub, bool);
	pk = (mbedtls_pk_context *)alloc(sizeof(mbedtls_pk_context));
	mbedtls_pk_init(pk);
	if( val_bool(pub) )
		r = mbedtls_pk_parse_public_key( pk, (const unsigned char*)val_string(data), val_strlen(data) );
	else
		r = mbedtls_pk_parse_key( pk, (const unsigned char*)val_string(data), val_strlen(data), NULL, 0 );
	if( r != 0 ){
		mbedtls_pk_free(pk);
		return ssl_error(r);
	}
	v = alloc_abstract(k_pkey, pk);
	val_gc(v,free_pkey);
	return v;
}
Beispiel #26
0
value shaderSource( value shader, value string )
{
	const GLchar *s[] = {val_string( string )};
	GLint len[] = {val_strlen( string )};

	glShaderSource(
		(GLuint)val_int( shader ),
		(GLsizei)1,
		s,
		len );
	return alloc_null( );
}
Beispiel #27
0
/**
	string_split : s:string -> sep:string -> string list
	<doc>split the string [s] using separator [sep]</doc>
**/
static value string_split( value o, value s ) {
	value l, first;
	int ilen;
	int slen;
	int start = 0;
	int pos;
	val_check(s,string);
	val_check(o,string);
	ilen = val_strlen(o);
	slen = val_strlen(s);
	l = alloc_null();
	first = alloc_null();
	for(pos=slen?0:1;pos<=ilen-slen;pos++)
		if( memcmp(val_string(o)+pos,val_string(s),slen) == 0 ) {
			value ss = copy_string(val_string(o)+start,pos-start);
			value l2 = alloc_array(2);
			val_array_set_i(l2,0,ss);
			val_array_set_i(l2,1,alloc_null());
			if( val_is_null(first) )
				first = l2;
			else
				val_array_set_i(l,1,l2);
			l = l2;
			start = pos + slen;
			if( slen )
				pos = start - 1;
		}
	if( ilen > 0 && slen ) {
		value ss = start ? copy_string(val_string(o)+start,ilen-start) : o;
		value l2 = alloc_array(2);
		val_array_set_i(l2,0,ss);
		val_array_set_i(l2,1,alloc_null());
		if( val_is_null(first))
			first = l2;
		else
			val_array_set_i(l,1,l2);
	}
	return first;
}
Beispiel #28
0
/**
	unserialize : string -> #loader -> any
	<doc>Unserialize a stored value.
	Need a loader to look for modules if some bytecode functions have been serialized.
	</doc>
**/
static value unserialize( value s, value loader ) {
	sbuffer b;
	val_check(s,string);
	b.cur = (unsigned char*)val_string(s);
	b.pos = 0;
	b.olds = NULL;
	b.trefs = NULL;
	b.tsize = 0;
	b.nrefs = 0;
	b.size = val_strlen(s);
	b.totlen = 0;
	return unserialize_rec(&b,loader);
}
Beispiel #29
0
/**
	$sset : string -> n:int -> c:int -> int?
	<doc>
	Set the [n]th char of a string to ([c] & 255).
	Returns the char set or [null] if out of bounds.
	</doc>
**/
static value builtin_sset( value s, value p, value c ) {
	int pp;
	unsigned char cc;
	val_check(s,string);
	val_check(p,int);
	val_check(c,int);
	pp = val_int(p);
	if( pp < 0 || pp >= val_strlen(s) )
		return val_null;
	cc = (unsigned char)val_int(c);
	val_string(s)[pp] = (char)cc;
	return alloc_int(cc);
}
Beispiel #30
0
/**
	module_read_string : string -> loader:object -> 'module
	<doc>
	Read a module using the specified string datas.
	</doc>
**/
static value module_read_string( value str, value loader ) {
	neko_module *m;
	string_pos p;
	val_check(str,string);
	val_check(loader,object);
	p.p = val_string(str);
	p.len = val_strlen(str);
	m = neko_read_module(neko_string_reader,&p,loader);
	if( m == NULL )
		neko_error();
	m->name = alloc_string("");
	return alloc_abstract(neko_kind_module,m);
}