Exemple #1
0
/**
	request : 'db -> sql:string -> 'result
	<doc>Executes the SQL request and returns its result</doc>
**/
HL_PRIM sqlite_result *HL_NAME(request)(sqlite_database *db, vbyte *sql ) {
	sqlite_result *r;
	const char *tl;
	int i,j;

	r = (sqlite_result*)hl_gc_alloc_finalizer(sizeof(sqlite_result));
	r->finalize = HL_NAME(finalize_result);
	r->db = db;
	
	if( sqlite3_prepare16_v2(db->db, sql, -1, &r->r, &tl) != SQLITE_OK ) {
		HL_NAME(error)(db->db, false);
	}

	if( *tl ) {
		sqlite3_finalize(r->r);
		hl_error("SQLite error: Cannot execute several SQL requests at the same time");
	}

	r->ncols = sqlite3_column_count(r->r);
	r->names = (int*)hl_gc_alloc(sizeof(int)*r->ncols);
	r->bools = (int*)hl_gc_alloc(sizeof(int)*r->ncols);
	r->first = 1;
	r->done = 0;
	for(i=0;i<r->ncols;i++) {
		int id = hl_hash_gen((uchar*)sqlite3_column_name16(r->r,i), true);
		const char *dtype = sqlite3_column_decltype(r->r,i);
		for(j=0;j<i;j++)
			if( r->names[j] == id ) {
				if( strcmp(sqlite3_column_name16(r->r,i), sqlite3_column_name16(r->r,j)) == 0 ) {
					sqlite3_finalize(r->r);
					hl_buffer *b = hl_alloc_buffer();
					hl_buffer_str(b, USTR("SQLite error: Same field is two times in the request: "));
					hl_buffer_str(b, (uchar*)sql);

					hl_error_msg(hl_buffer_content(b, NULL));
				} else {
					hl_buffer *b = hl_alloc_buffer();
					hl_buffer_str(b, USTR("SQLite error: Same field ids for: "));
					hl_buffer_str(b, sqlite3_column_name16(r->r,i));
					hl_buffer_str(b, USTR(" and "));
					hl_buffer_str(b, sqlite3_column_name16(r->r,j));
					
					sqlite3_finalize(r->r);
					hl_error_msg(hl_buffer_content(b, NULL));
				}
			}
		r->names[i] = id;
		r->bools[i] = dtype?(strcmp(dtype,"BOOL") == 0):0;
	}
	// changes in an update/delete
	if( db->last != NULL )
		HL_NAME(finalize_request)(db->last, false);
	
	db->last = r;
	return db->last;
}
Exemple #2
0
/**
	result_next : 'result -> object?
	<doc>Returns the next row in the result or [null] if no more result.</doc>
**/
HL_PRIM varray *HL_NAME(result_next)( sqlite_result *r ) {
	if( r->done )
		return NULL;
	switch( sqlite3_step(r->r) ) {
	case SQLITE_ROW:
		r->first = 0;
		varray *a = hl_alloc_array(&hlt_dyn, r->ncols);
		int i;
		for(i=0;i<r->ncols;i++)
		{
			vdynamic *v;
			switch( sqlite3_column_type(r->r,i) ) {
			case SQLITE_NULL:
				v = NULL;
				break;
			case SQLITE_INTEGER:
			{
				int vint = sqlite3_column_int(r->r, i);
				if (r->bools[i])
					v = hl_make_dyn(&vint, &hlt_bool);
				else
					v = hl_make_dyn(&vint, &hlt_i32);
				break;
			}
			case SQLITE_FLOAT:
			{
				double d = sqlite3_column_double(r->r, i);
				v = hl_make_dyn(&d, &hlt_f64);
				break;
			}
			case SQLITE_TEXT:
			{
				uchar *text16 = (uchar *)sqlite3_column_text16(r->r, i);
				v = hl_make_dyn(&text16, &hlt_bytes);
				break;
			}
			case SQLITE_BLOB:
			{
				vbyte *blob = (vbyte *)sqlite3_column_blob(r->r, i);
				v = hl_make_dyn(&blob, &hlt_bytes);
				break;
			}
			default:
				hl_error_msg(USTR("SQLite error: Unknown type #%d"), sqlite3_column_type(r->r,i));
			}
			hl_aptr(a, vdynamic*)[i] = v;
		}
		return a;
	case SQLITE_DONE:
		HL_NAME(finalize_request)(r, true);
		return NULL;
	case SQLITE_BUSY:
		hl_error("SQLite error: Database is busy");
	case SQLITE_ERROR:
		HL_NAME(error)(r->db->db, false);
	default:
		return NULL;
	}
	return NULL;
}
Exemple #3
0
static void HL_NAME(error)( sqlite3 *db, bool close ) {
	hl_buffer *b = hl_alloc_buffer();
	hl_buffer_str(b, USTR("SQLite error: "));
	hl_buffer_str(b, sqlite3_errmsg16(db));
	if ( close )
		sqlite3_close(db);
	hl_error_msg(hl_buffer_content(b, NULL));
}
Exemple #4
0
HL_PRIM int regexp_regexp_matched_pos( ereg *e, int m, int *len ) {
	int start;
	if( !e->matched )
		hl_error("Calling matchedPos() on an unmatched regexp"); 
	if( m < 0 || m >= e->nmatches )
		hl_error_msg(USTR("Matched index %d outside bounds"),m);
	start = e->matches[m*2];
	*len = e->matches[m*2+1] - start;
	return start;
}
Exemple #5
0
HL_PRIM ereg *regexp_regexp_new_options( vbyte *str, vbyte *opts ) {
	ereg *r;
	const char *error;
	int err_offset;
	int errorcode;
	pcre16 *p;
	uchar *o = (uchar*)opts;
	int options = 0;
	while( *o ) {
		switch( *o++ ) {
		case 'i':
			options |= PCRE_CASELESS;
			break;
		case 's':
			options |= PCRE_DOTALL;
			break;
		case 'm':
			options |= PCRE_MULTILINE;
			break;
		case 'u':
			options |= PCRE_UTF8;
			break;
		case 'g':
			options |= PCRE_UNGREEDY;
			break;
		default:
			return NULL;
		}
	}
	p = pcre16_compile2((PCRE_SPTR16)str,options,&errorcode,&error,&err_offset,NULL);
	if( p == NULL ) {
		hl_buffer *b = hl_alloc_buffer();
		hl_buffer_str(b,USTR("Regexp compilation error : "));
		hl_buffer_cstr(b,error);
		hl_buffer_str(b,USTR(" in "));
		hl_buffer_str(b,(uchar*)str);
		hl_error_msg(USTR("%s"),hl_buffer_content(b,NULL));
	}
	r = (ereg*)hl_gc_alloc_finalizer(sizeof(ereg));
	r->finalize = regexp_finalize;
	r->p = p;
	r->nmatches = 0;
	r->matched = 0;
	pcre16_fullinfo(p,NULL,PCRE_INFO_CAPTURECOUNT,&r->nmatches);
	r->nmatches++;
	r->matches = (int*)malloc(sizeof(int) * 3 * r->nmatches);
	limit.flags = PCRE_EXTRA_MATCH_LIMIT_RECURSION;
	limit.match_limit_recursion = 3500; // adapted based on Windows 1MB stack size
	return r;
}
Exemple #6
0
HL_PRIM void HL_NAME(zip_flush_mode)( fmt_zip *z, int flush ) {
	switch( flush ) {
	case 0:
		z->flush = Z_NO_FLUSH;
		break;
	case 1:
		z->flush = Z_SYNC_FLUSH;
		break;
	case 2:
		z->flush = Z_FULL_FLUSH;
		break;
	case 3:
		z->flush = Z_FINISH;
		break;
	case 4:
		z->flush = Z_BLOCK;
		break;
	default:
		hl_error_msg(USTR("Invalid flush mode %d"),flush);
		break;
	}
}
Exemple #7
0
HL_PRIM void *hl_dyn_call_obj( vdynamic *o, hl_type *ft, int hfield, void **args, vdynamic *ret ) {
	switch( o->t->kind ) {
	case HDYNOBJ:
		hl_fatal("TODO");
		break;
	case HOBJ:
		{
			hl_runtime_obj *rt = o->t->obj->rt;
			while( true ) {
				hl_field_lookup *l = hl_lookup_find(rt->lookup,rt->nlookup, hfield);
				if( l != NULL && l->field_index < 0 ) {
					vclosure tmp;
					vclosure_wrapper w;
					tmp.t = hl_get_closure_type(l->t);
					tmp.fun = rt->methods[-l->field_index-1];
					tmp.hasValue = 1;
					tmp.value = o;
					w.cl.t = ft;
					w.cl.fun = hlc_get_wrapper(ft);
					w.cl.hasValue = 2;
					w.cl.value = &w;
					w.wrappedFun = &tmp;
					return hl_wrapper_call(&w,args,ret);
				}
				rt = rt->parent;
				if( rt == NULL ) break;
			}
			hl_error_msg(USTR("%s has no method %s"),o->t->obj->name,hl_field_name(hfield));
		}
		break;
	default:
		hl_error("Invalid field access");
		break;
	}
	return NULL;
}
Exemple #8
0
HL_PRIM vdynamic* hl_call_method( vdynamic *c, varray *args ) {
	vclosure *cl = (vclosure*)c;
	vdynamic **vargs = hl_aptr(args,vdynamic*);
	void *pargs[HL_MAX_ARGS];
	void *ret;
	union { double d; int i; float f; } tmp[HL_MAX_ARGS];
	hl_type *tret;
	vdynamic *dret;
	vdynamic out;
	int i;
	if( args->size > HL_MAX_ARGS )
		hl_error("Too many arguments");
	if( cl->hasValue ) {
		if( cl->fun == fun_var_args ) {
			cl = (vclosure*)cl->value;
			return cl->hasValue ? ((vdynamic* (*)(vdynamic*, varray*))cl->fun)(cl->value, args) : ((vdynamic* (*)(varray*))cl->fun)(args);
		}
		hl_error("Can't call closure with value");
	}
	if( args->size < cl->t->fun->nargs )
		hl_error_msg(USTR("Missing arguments : %d expected but %d passed"),cl->t->fun->nargs, args->size);
	for(i=0;i<cl->t->fun->nargs;i++) {
		vdynamic *v = vargs[i];
		hl_type *t = cl->t->fun->args[i];
		void *p;
		if( v == NULL ) {
			if( hl_is_ptr(t) )
				p = NULL;
			else {
				tmp[i].d = 0;
				p = &tmp[i].d;
			}
		} else switch( t->kind ) {
		case HBOOL:
		case HUI8:
		case HUI16:
		case HI32:
			tmp[i].i = hl_dyn_casti(vargs + i, &hlt_dyn,t);
			p = &tmp[i].i;
			break;
		case HF32:
			tmp[i].f = hl_dyn_castf(vargs + i, &hlt_dyn);
			p = &tmp[i].f;
			break;
		case HF64:
			tmp[i].d = hl_dyn_castd(vargs + i, &hlt_dyn);
			p = &tmp[i].d;
			break;
		default:
			p = hl_dyn_castp(vargs + i,&hlt_dyn,t);
			break;
		}
		pargs[i] = p;
	}
	ret = hlc_static_call(cl->fun,cl->t,pargs,&out);
	tret = cl->t->fun->ret;
	if( !hl_is_ptr(tret) ) {
		vdynamic *r;
		if( tret->kind == HVOID )
			return NULL;
		r = hl_alloc_dynamic(tret);
		r->t = tret;
		r->v.d = out.v.d; // copy
		return r;
	}
	if( ret == NULL || hl_is_dynamic(tret) )
		return (vdynamic*)ret;
	dret = hl_alloc_dynamic(tret);
	dret->v.ptr = ret;
	return dret;
}