First cut at sql support via sqlite3. Including preliminary varargs support
for internal functions, and returning values from functions in the compiler.
This commit is contained in:
@@ -110,6 +110,21 @@ ast *make_fndefint(char *identifier, long num)
|
|||||||
return elem;
|
return elem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ast *make_fndefint_v(char *identifier, long num)
|
||||||
|
{
|
||||||
|
ast *elem = safe_malloc(sizeof(ast));
|
||||||
|
ast_list *list = NULL;
|
||||||
|
|
||||||
|
elem->tag = node_ast;
|
||||||
|
elem->info.node.tag = kind_fndefint_v;
|
||||||
|
list = make_list(make_integer(num), list);
|
||||||
|
list = make_list(make_string(identifier), list);
|
||||||
|
elem->info.node.head = list;
|
||||||
|
elem->lineno = yylineno;
|
||||||
|
|
||||||
|
return elem;
|
||||||
|
}
|
||||||
|
|
||||||
ast *make_constant(char *identifier, long num)
|
ast *make_constant(char *identifier, long num)
|
||||||
{
|
{
|
||||||
ast *elem = safe_malloc(sizeof(ast));
|
ast *elem = safe_malloc(sizeof(ast));
|
||||||
@@ -297,13 +312,13 @@ ast *make_case_statement_number(long num)
|
|||||||
return elem;
|
return elem;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast *make_return_statement(void)
|
ast *make_return_statement(ast *expression)
|
||||||
{
|
{
|
||||||
ast *elem = safe_malloc(sizeof(ast));
|
ast *elem = safe_malloc(sizeof(ast));
|
||||||
|
|
||||||
elem->tag = node_ast;
|
elem->tag = node_ast;
|
||||||
elem->info.node.tag = stmt_return;
|
elem->info.node.tag = stmt_return;
|
||||||
elem->info.node.head = NULL;
|
elem->info.node.head = make_list(expression, NULL);
|
||||||
elem->lineno = yylineno;
|
elem->lineno = yylineno;
|
||||||
|
|
||||||
return elem;
|
return elem;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ ast_list *reverse_list(ast_list *);
|
|||||||
ast *make_list_node(ast_list *);
|
ast *make_list_node(ast_list *);
|
||||||
ast *make_function(char *, ast_list *, ast_list *);
|
ast *make_function(char *, ast_list *, ast_list *);
|
||||||
ast *make_fndefint(char *, long);
|
ast *make_fndefint(char *, long);
|
||||||
|
ast *make_fndefint_v(char *, long);
|
||||||
ast *make_constant(char *, long);
|
ast *make_constant(char *, long);
|
||||||
ast *make_realconstant(char *, float);
|
ast *make_realconstant(char *, float);
|
||||||
ast *make_fndefext(char *);
|
ast *make_fndefext(char *);
|
||||||
@@ -22,6 +23,6 @@ ast *make_case_statement_number(long);
|
|||||||
ast *make_case_statement_variable(char *);
|
ast *make_case_statement_variable(char *);
|
||||||
ast *make_break_statement();
|
ast *make_break_statement();
|
||||||
ast *make_default_statement();
|
ast *make_default_statement();
|
||||||
ast *make_return_statement();
|
ast *make_return_statement(ast *);
|
||||||
|
|
||||||
void ast_dump(ast *);
|
void ast_dump(ast *);
|
||||||
|
|||||||
@@ -95,10 +95,14 @@ struct instr *instr_tail = NULL;
|
|||||||
#define VAR_ARG 1
|
#define VAR_ARG 1
|
||||||
#define VAR_REAL 2
|
#define VAR_REAL 2
|
||||||
|
|
||||||
|
#define FN_TYPE_BASE 0xff
|
||||||
|
|
||||||
#define FN_INT 1
|
#define FN_INT 1
|
||||||
#define FN_STR 2
|
#define FN_STR 2
|
||||||
#define FN_LOCAL 3
|
#define FN_LOCAL 3
|
||||||
|
|
||||||
|
#define FN_VARARGS 0x100
|
||||||
|
|
||||||
int fnconst;
|
int fnconst;
|
||||||
int nargs;
|
int nargs;
|
||||||
int local_variable_count = -1;
|
int local_variable_count = -1;
|
||||||
@@ -146,7 +150,7 @@ void output_functions_action(struct hashentry *ptr)
|
|||||||
{
|
{
|
||||||
int len, pad;
|
int len, pad;
|
||||||
|
|
||||||
if (ptr->flags == FN_LOCAL) {
|
if ((ptr->flags & FN_TYPE_BASE) == FN_LOCAL) {
|
||||||
len = strlen(ptr->name) + 1 + 16;
|
len = strlen(ptr->name) + 1 + 16;
|
||||||
pad = (4 - (len % 4)) % 4;
|
pad = (4 - (len % 4)) % 4;
|
||||||
output_int(len+pad);
|
output_int(len+pad);
|
||||||
@@ -311,7 +315,7 @@ void create_function(char *fnname, int type, int num)
|
|||||||
compiler_error("Function already exists");
|
compiler_error("Function already exists");
|
||||||
|
|
||||||
if (output_asm) {
|
if (output_asm) {
|
||||||
switch (type) {
|
switch (type & FN_TYPE_BASE) {
|
||||||
case FN_INT:
|
case FN_INT:
|
||||||
printf("%%fnint %s %d\n", fnname, num);
|
printf("%%fnint %s %d\n", fnname, num);
|
||||||
break;
|
break;
|
||||||
@@ -644,12 +648,14 @@ void codegen(ast *node)
|
|||||||
case node_ast:
|
case node_ast:
|
||||||
switch (node->info.node.tag) {
|
switch (node->info.node.tag) {
|
||||||
case kind_fndefint:
|
case kind_fndefint:
|
||||||
|
case kind_fndefint_v:
|
||||||
assert(sp == 0);
|
assert(sp == 0);
|
||||||
assert(node->info.node.head != NULL);
|
assert(node->info.node.head != NULL);
|
||||||
assert(node->info.node.head->next != NULL);
|
assert(node->info.node.head->next != NULL);
|
||||||
|
|
||||||
create_function(node->info.node.head->elem->info.string,
|
create_function(node->info.node.head->elem->info.string,
|
||||||
FN_INT,
|
FN_INT | ((node->info.node.tag ==
|
||||||
|
kind_fndefint_v) ? FN_VARARGS : 0),
|
||||||
node->info.node.head->next->elem->info.integer);
|
node->info.node.head->next->elem->info.integer);
|
||||||
break;
|
break;
|
||||||
case kind_constant:
|
case kind_constant:
|
||||||
@@ -771,20 +777,36 @@ void codegen(ast *node)
|
|||||||
|
|
||||||
// printf("savedsp = %d\n", savedsp);
|
// printf("savedsp = %d\n", savedsp);
|
||||||
|
|
||||||
|
nargs = 0;
|
||||||
|
|
||||||
/* Evaluate the arguments first */
|
/* Evaluate the arguments first */
|
||||||
for (ptr =
|
for (ptr =
|
||||||
node->info.node.head->next->elem->info.node.head;
|
node->info.node.head->next->elem->info.node.head;
|
||||||
ptr; ptr = ptr->next) {
|
ptr; ptr = ptr->next) {
|
||||||
codegen(ptr->elem);
|
codegen(ptr->elem);
|
||||||
|
nargs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// printf("sp = %d\n", sp);
|
// printf("sp = %d\n", sp);
|
||||||
|
|
||||||
|
if (!lookup_function(node->info.node.head->elem, &fn))
|
||||||
|
compiler_error("Function not found");
|
||||||
|
|
||||||
|
if (fn.type & FN_VARARGS) {
|
||||||
|
/*
|
||||||
|
* The last argument is the number of
|
||||||
|
* arguments to expect in the case
|
||||||
|
* of variable argument length.
|
||||||
|
* This is something only supported for
|
||||||
|
* builtin functions at present.
|
||||||
|
*/
|
||||||
|
emit_instr_immediate(OP_PUSH, nargs);
|
||||||
|
sp++;
|
||||||
|
}
|
||||||
|
|
||||||
emit_instr_immediate(OP_ALLOC, 1);
|
emit_instr_immediate(OP_ALLOC, 1);
|
||||||
sp++;
|
sp++;
|
||||||
|
|
||||||
if (!lookup_function(node->info.node.head->elem, &fn))
|
|
||||||
compiler_error("Function not found");
|
|
||||||
switch (fn.type) {
|
switch (fn.type) {
|
||||||
case FN_INT:
|
case FN_INT:
|
||||||
emit_instr_immediate(OP_CALLNUM, fn.num);
|
emit_instr_immediate(OP_CALLNUM, fn.num);
|
||||||
@@ -1147,8 +1169,12 @@ void codegen(ast *node)
|
|||||||
emit_instr_label(OP_B, breaklabel);
|
emit_instr_label(OP_B, breaklabel);
|
||||||
break;
|
break;
|
||||||
case stmt_return:
|
case stmt_return:
|
||||||
assert(node->info.node.head == NULL);
|
if (node->info.node.head) {
|
||||||
|
/* Return value */
|
||||||
|
codegen(node->info.node.head->elem);
|
||||||
|
emit_instr_imm_const(OP_STORE, sp, fnconst);
|
||||||
|
sp--;
|
||||||
|
}
|
||||||
emit_instr_imm_const(OP_POP, sp, fnconst);
|
emit_instr_imm_const(OP_POP, sp, fnconst);
|
||||||
emit_simple_instr(OP_RET);
|
emit_simple_instr(OP_RET);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ char *string_buf_ptr;
|
|||||||
|
|
||||||
function return TOKFUNCTION;
|
function return TOKFUNCTION;
|
||||||
fndefint return TOKFNDEFINT;
|
fndefint return TOKFNDEFINT;
|
||||||
|
fndefint_v return TOKFNDEFINT_V;
|
||||||
fndefext return TOKFNDEFEXT;
|
fndefext return TOKFNDEFEXT;
|
||||||
constant return TOKCONSTANT;
|
constant return TOKCONSTANT;
|
||||||
while return TOKWHILE;
|
while return TOKWHILE;
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%token TOKFUNCTION TOKFNDEFINT TOKFNDEFEXT TOKCONSTANT
|
%token TOKFUNCTION TOKFNDEFINT TOKFNDEFINT_V TOKFNDEFEXT TOKCONSTANT
|
||||||
%token TOKWHILE TOKIF TOKELSE TOKSWITCH TOKCASE TOKDEFAULT
|
%token TOKWHILE TOKIF TOKELSE TOKSWITCH TOKCASE TOKDEFAULT
|
||||||
%token TOKBREAK TOKRETURN TOKEQ TOKNE TOKAND TOKOR STRING
|
%token TOKBREAK TOKRETURN TOKEQ TOKNE TOKAND TOKOR STRING
|
||||||
|
|
||||||
@@ -86,6 +86,7 @@ int main(int argc, char *argv[])
|
|||||||
%type <Tast> fndefint
|
%type <Tast> fndefint
|
||||||
%type <Tast> fndefext
|
%type <Tast> fndefext
|
||||||
%type <Tast> statement
|
%type <Tast> statement
|
||||||
|
%type <Tast> fndefint_v
|
||||||
%type <Tast> assignment
|
%type <Tast> assignment
|
||||||
%type <Tast> expression
|
%type <Tast> expression
|
||||||
%type <Tast> realconstant
|
%type <Tast> realconstant
|
||||||
@@ -142,6 +143,7 @@ fn_list:
|
|||||||
fn_list_inner:
|
fn_list_inner:
|
||||||
fn_list_inner function { $$ = make_list($2, $1); }
|
fn_list_inner function { $$ = make_list($2, $1); }
|
||||||
| fn_list_inner fndefint { $$ = make_list($2, $1); }
|
| fn_list_inner fndefint { $$ = make_list($2, $1); }
|
||||||
|
| fn_list_inner fndefint_v { $$ = make_list($2, $1); }
|
||||||
| fn_list_inner fndefext { $$ = make_list($2, $1); }
|
| fn_list_inner fndefext { $$ = make_list($2, $1); }
|
||||||
| fn_list_inner constant { $$ = make_list($2, $1); }
|
| fn_list_inner constant { $$ = make_list($2, $1); }
|
||||||
| fn_list_inner realconstant { $$ = make_list($2, $1); }
|
| fn_list_inner realconstant { $$ = make_list($2, $1); }
|
||||||
@@ -158,6 +160,11 @@ fndefint:
|
|||||||
{ $$ = make_fndefint($2, $3); }
|
{ $$ = make_fndefint($2, $3); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
fndefint_v:
|
||||||
|
TOKFNDEFINT_V IDENTIFIER NUMBER ';'
|
||||||
|
{ $$ = make_fndefint_v($2, $3); }
|
||||||
|
;
|
||||||
|
|
||||||
constant:
|
constant:
|
||||||
TOKCONSTANT IDENTIFIER NUMBER ';'
|
TOKCONSTANT IDENTIFIER NUMBER ';'
|
||||||
{ $$ = make_constant($2, $3); }
|
{ $$ = make_constant($2, $3); }
|
||||||
@@ -319,8 +326,11 @@ statement_case:
|
|||||||
;
|
;
|
||||||
|
|
||||||
statement_return:
|
statement_return:
|
||||||
|
TOKRETURN expression
|
||||||
|
{ $$ = make_return_statement($2); }
|
||||||
|
|
|
||||||
TOKRETURN
|
TOKRETURN
|
||||||
{ $$ = make_return_statement(); }
|
{ $$ = make_return_statement(NULL); }
|
||||||
;
|
;
|
||||||
|
|
||||||
statement_break:
|
statement_break:
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
||||||
kind_fndef, kind_fndefint, kind_fndefext, kind_constant,
|
kind_fndef, kind_fndefint, kind_fndefint_v, kind_fndefext,
|
||||||
kind_assign, kind_list, kind_call, kind_array,
|
kind_constant, kind_assign, kind_list, kind_call, kind_array,
|
||||||
|
|
||||||
op_plus, op_minus, op_times, op_divide,
|
op_plus, op_minus, op_times, op_divide,
|
||||||
op_gt, op_lt, op_ge, op_le, op_eq, op_ne,
|
op_gt, op_lt, op_ge, op_le, op_eq, op_ne,
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
PREFIX?= /usr/local
|
PREFIX?= /usr/local
|
||||||
|
|
||||||
OBJS= main.o vm.o plugins.o dmx.o midi.o beatdetect.o fft.o map3d.o mouse.o \
|
OBJS= main.o vm.o plugins.o dmx.o midi.o beatdetect.o fft.o map3d.o mouse.o \
|
||||||
cmdsocket.o
|
cmdsocket.o sql.o
|
||||||
SRCS= main.c vm.c plugins.c dmx.c midi.c beatdetect.c fft.c map3d.c mouse.c \
|
SRCS= main.c vm.c plugins.c dmx.c midi.c beatdetect.c fft.c map3d.c mouse.c \
|
||||||
cmdsocket.c
|
cmdsocket.c sql.c
|
||||||
|
|
||||||
OBJS+= abi.o
|
OBJS+= abi.o
|
||||||
SRCS+= abi.c
|
SRCS+= abi.c
|
||||||
@@ -14,10 +14,13 @@ COMMONOBJS= mem.o hash.o
|
|||||||
COMMONDIR= ../common
|
COMMONDIR= ../common
|
||||||
|
|
||||||
INCDIR= ../include
|
INCDIR= ../include
|
||||||
|
SQLITEINCDIR= /usr/pkg/include
|
||||||
|
SQLITELIBDIR= /usr/pkg/lib
|
||||||
|
|
||||||
CFLAGS+= -Wall -Werror
|
CFLAGS+= -Wall -Werror
|
||||||
CPPFLAGS+= -I${INCDIR}
|
CPPFLAGS+= -I${INCDIR} -I${SQLITEINCDIR}
|
||||||
LDLIBS+= -lm
|
LDFLAGS+= -L${SQLITELIBDIR} -Wl,-R${SQLITELIBDIR}
|
||||||
|
LDLIBS+= -lm -lsqlite3
|
||||||
|
|
||||||
PROGOBJS= ${OBJS} ${COMMONOBJS:S/^/${COMMONDIR}\//}
|
PROGOBJS= ${OBJS} ${COMMONOBJS:S/^/${COMMONDIR}\//}
|
||||||
|
|
||||||
|
|||||||
@@ -49,3 +49,5 @@ int vm_intfn_cmdsocket_accept(void);
|
|||||||
int vm_intfn_cmdsocket_read(void);
|
int vm_intfn_cmdsocket_read(void);
|
||||||
int vm_intfn_cmdsocket_write(void);
|
int vm_intfn_cmdsocket_write(void);
|
||||||
int vm_intfn_cmdsocket_prefix(void);
|
int vm_intfn_cmdsocket_prefix(void);
|
||||||
|
int vm_intfn_sql_query(void);
|
||||||
|
int vm_intfn_sql_query_1s(void);
|
||||||
|
|||||||
@@ -38,6 +38,9 @@ function cmdsocket_accept
|
|||||||
function cmdsocket_read
|
function cmdsocket_read
|
||||||
function cmdsocket_write
|
function cmdsocket_write
|
||||||
function cmdsocket_prefix
|
function cmdsocket_prefix
|
||||||
|
/* NOT_YET function_v sql_query */
|
||||||
|
function sql_query
|
||||||
|
function sql_query_1s
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The ABI should be identified by a SHA1 hash of this file
|
* The ABI should be identified by a SHA1 hash of this file
|
||||||
|
|||||||
@@ -37,6 +37,13 @@ do_function()
|
|||||||
FNCOUNT=$((${FNCOUNT}+1))
|
FNCOUNT=$((${FNCOUNT}+1))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do_function_v()
|
||||||
|
{
|
||||||
|
echo " vm_intfn_${ARG1}," >>${ABI}
|
||||||
|
echo "fndefint_v ${ARG1} ${FNCOUNT};" >>${HEADER}
|
||||||
|
FNCOUNT=$((${FNCOUNT}+1))
|
||||||
|
}
|
||||||
|
|
||||||
cat <<EOF >${ABI}
|
cat <<EOF >${ABI}
|
||||||
/* abi.c */
|
/* abi.c */
|
||||||
/* autogenerated - do not edit */
|
/* autogenerated - do not edit */
|
||||||
@@ -69,6 +76,8 @@ do
|
|||||||
case "$TYPE" in
|
case "$TYPE" in
|
||||||
function) do_function
|
function) do_function
|
||||||
;;
|
;;
|
||||||
|
function_v) do_function_v
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
done <${INFILE}
|
done <${INFILE}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "vm.h"
|
#include "vm.h"
|
||||||
|
|
||||||
#define MOUSEDEVICE "/dev/wsmouse"
|
#define MOUSEDEVICE "/dev/wsmouse1"
|
||||||
|
|
||||||
char *events[] = {
|
char *events[] = {
|
||||||
"undefined",
|
"undefined",
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include "beatdetect.h"
|
#include "beatdetect.h"
|
||||||
#include "mouse.h"
|
#include "mouse.h"
|
||||||
#include "cmdsocket.h"
|
#include "cmdsocket.h"
|
||||||
|
#include "sql.h"
|
||||||
|
|
||||||
struct plugin plugins_table[] = {
|
struct plugin plugins_table[] = {
|
||||||
{"midi", midi_init, midi_close, 0},
|
{"midi", midi_init, midi_close, 0},
|
||||||
@@ -19,6 +20,7 @@ struct plugin plugins_table[] = {
|
|||||||
{"beatdetect", beatdetect_init, beatdetect_close, 0},
|
{"beatdetect", beatdetect_init, beatdetect_close, 0},
|
||||||
{"mouse", mouse_init, mouse_close, 0},
|
{"mouse", mouse_init, mouse_close, 0},
|
||||||
{"cmdsocket", cmdsocket_init, cmdsocket_close, 0},
|
{"cmdsocket", cmdsocket_init, cmdsocket_close, 0},
|
||||||
|
{"sql", sql_init, sql_close, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
int nplugins = (sizeof(plugins_table) / sizeof(struct plugin));
|
int nplugins = (sizeof(plugins_table) / sizeof(struct plugin));
|
||||||
|
|||||||
116
src/lsi/vm.c
116
src/lsi/vm.c
@@ -23,6 +23,7 @@
|
|||||||
#include "map3d.h"
|
#include "map3d.h"
|
||||||
#include "mouse.h"
|
#include "mouse.h"
|
||||||
#include "cmdsocket.h"
|
#include "cmdsocket.h"
|
||||||
|
#include "sql.h"
|
||||||
|
|
||||||
#define DEBUG 0
|
#define DEBUG 0
|
||||||
|
|
||||||
@@ -482,6 +483,121 @@ int vm_intfn_cmdsocket_write(void)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef NOT_YET
|
||||||
|
|
||||||
|
#define MIN(a, b) ((a < b) ? a : b)
|
||||||
|
|
||||||
|
#define MORE_QUERY_N(x, n) do { \
|
||||||
|
off = strncpy(buf+off, (x), MIN(VM_STRING_MAX-off, (n)) - buf;\
|
||||||
|
if (off >= VM_STRING_MAX) { \
|
||||||
|
printf("Excessive string length - can't perform query\n"); \
|
||||||
|
return 1; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define MORE_QUERY(x) MORE_QUERY_N((x), VM_STRING_MAX)
|
||||||
|
|
||||||
|
int vm_intfn_sql_query(void)
|
||||||
|
{
|
||||||
|
int nargs = stack_get(vm_current, 1);
|
||||||
|
int len = stack_get(vm_current, nargs+1);
|
||||||
|
char *fmt = stack_getstr(vm_current, len, nargs+1);
|
||||||
|
char buf1[VM_STRING_MAX];
|
||||||
|
char buf2[VM_STRING_MAX];
|
||||||
|
char buf[VM_STRING_MAX];
|
||||||
|
int off = 0;
|
||||||
|
int result;
|
||||||
|
int next;
|
||||||
|
char *p, *p1;
|
||||||
|
|
||||||
|
if (len > VM_STRING_MAX) {
|
||||||
|
printf("Excessive string length - can't perform query\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
strncpy(buf1, fmt, len);
|
||||||
|
buf1[len] = '\0';
|
||||||
|
|
||||||
|
p = buf1;
|
||||||
|
while (p1 = strchr(p, '%') {
|
||||||
|
if (p1) {
|
||||||
|
*p1 = 0;
|
||||||
|
}
|
||||||
|
if (p != buf1) {
|
||||||
|
switch(*p) {
|
||||||
|
case '%':
|
||||||
|
MORE_QUERY("%");
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
next = (len + sizeof(stkentry)-1) / sizeof(stkentry) + 1;
|
||||||
|
|
||||||
|
MORE_QUERY_N(stack_getstr(vm_current, slen, nargs));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MORE_QUERY(p);
|
||||||
|
if (p1)
|
||||||
|
p = p1;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sql_query(buffer, len, &result);
|
||||||
|
/* XXX what to do with an error here? */
|
||||||
|
stack_poke(vm_current, 0, result); /* return value */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int vm_intfn_sql_query(void)
|
||||||
|
{
|
||||||
|
int len = stack_get(vm_current, 1);
|
||||||
|
char *query = stack_getstr(vm_current, len, 1);
|
||||||
|
int result;
|
||||||
|
|
||||||
|
sql_query(query, len, &result);
|
||||||
|
/* XXX what to do with an error here? */
|
||||||
|
stack_poke(vm_current, 0, result); /* return value */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vm_intfn_sql_query_1s(void)
|
||||||
|
{
|
||||||
|
int len1, len2;
|
||||||
|
char buf1[VM_STRING_MAX];
|
||||||
|
char buf2[VM_STRING_MAX];
|
||||||
|
char query[VM_STRING_MAX];
|
||||||
|
char *arg1;
|
||||||
|
char *arg2;
|
||||||
|
int result;
|
||||||
|
int next;
|
||||||
|
|
||||||
|
next = 1;
|
||||||
|
|
||||||
|
len2 = stack_get(vm_current, next);
|
||||||
|
arg2 = stack_getstr(vm_current, len2, next);
|
||||||
|
|
||||||
|
next += (len2 + sizeof(stkentry)-1) / sizeof(stkentry) + 1;
|
||||||
|
|
||||||
|
len1 = stack_get(vm_current, next);
|
||||||
|
arg1 = stack_getstr(vm_current, len1, next);
|
||||||
|
|
||||||
|
if ((len1 > VM_STRING_MAX) || (len2 > VM_STRING_MAX)) {
|
||||||
|
printf("Excessive string length - can't perform query\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
strncpy(buf1, arg1, len1);
|
||||||
|
buf1[len1] = '\0';
|
||||||
|
strncpy(buf2, arg2, len2);
|
||||||
|
buf2[len2] = '\0';
|
||||||
|
|
||||||
|
snprintf(query, VM_STRING_MAX, buf1, buf2);
|
||||||
|
|
||||||
|
sql_query(query, strlen(query), &result);
|
||||||
|
|
||||||
|
/* XXX what to do with an error here? */
|
||||||
|
stack_poke(vm_current, 0, result); /* return value */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int vm_intfn_beatdetect_read(void)
|
int vm_intfn_beatdetect_read(void)
|
||||||
{
|
{
|
||||||
if (!beatdetect_read()) {
|
if (!beatdetect_read()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user