diff --git a/ChangeLog b/ChangeLog index acf1aaf7..08dbbbc8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,50 @@ +2020-07-16 (12.19) + COMMON: Fix 'Print #' on Windows to use Windows line endings + +2020-07-12 (12.19) + ANDROID: fix layout issue with samsung mobiles + ANDROID: save and restore the selected theme + ANDROID: fix access to external storage + +2020-06-14 (12.19) + UI: Use theme colours in main display #94 + UI: Added theme menu + +2020-06-14 (12.19) + FLTK: line numbers colours #93 + SDL: restore window size #95 + +2020-06-06 (12.19) + COMMON: minor performance tweak + +2020-05-11 (12.19) + ANDROID: complain when samsung keyboard detected + COMMON: fix compile warnings + +2020-05-11 (12.19) + FLTK: Fix compile warnings with updated gcc + +2020-05-10 (12.19) + COMMON: Fix ABSMIN/ABSMAX transposed #96 + +2020-05-09 (12.19) + COMMON: Fix crash when passing non-array to CHART + SDL: show icon in linux build + +2020-05-07 (12.19) + COMMON: Fix image.save() to array destination + +2020-05-04 (12.19) + COMMON: INPUT crash #99 + COMMON: Fix compile warnings with updated gcc + +2020-03-07 (12.19) + COMMON: implement DEFINEKEY undo #92 + UI: added R157 colour theme #94 + +2020-02-13 (12.19) + AUDIO: fix integration with latest version of miniaudio library + 2020-02-13 (0.12.18) Fix path for HOME constant diff --git a/configure.ac b/configure.ac index ea0dd25e..91490042 100644 --- a/configure.ac +++ b/configure.ac @@ -7,7 +7,7 @@ dnl This program is distributed under the terms of the GPL v2.0 dnl Download the GNU Public License (GPL) from www.gnu.org dnl -AC_INIT([smallbasic], [0.12.18]) +AC_INIT([smallbasic], [12.19]) AC_CONFIG_SRCDIR([configure.ac]) AC_CANONICAL_TARGET @@ -74,8 +74,8 @@ function checkDebugMode() { AC_MSG_RESULT([$with_debug]) if test "$with_debug" = "yes" || test "$with_debug" = "full" then - CFLAGS="${CFLAGS} -g -O0" - CXXFLAGS="${CXXFLAGS} -g -O0" + CFLAGS="${CFLAGS} -g -O0 -fstack-protector-all" + CXXFLAGS="${CXXFLAGS} -g -O0 -fstack-protector-all" AC_DEFINE(_DEBUG, 1, [debugging build enabled]) fi AC_SUBST(CFLAGS) @@ -204,6 +204,8 @@ function buildSDL() { PACKAGE_CFLAGS="${PACKAGE_CFLAGS} ${FONTCONFIG_CFLAGS}" + (cd images && xxd -i sb-desktop-128x128.png > ../src/platform/sdl/icon.h) + dnl backlinking support for modules PACKAGE_LIBS="${PACKAGE_LIBS} -ldl -no-pie" PACKAGE_LIBS="${PACKAGE_LIBS} ${FONTCONFIG_LIBS}" @@ -211,7 +213,7 @@ function buildSDL() { esac PACKAGE_CFLAGS="${PACKAGE_CFLAGS} `sdl2-config --cflags` `pkg-config freetype2 --cflags` -fno-exceptions" - CXXFLAGS="${CXXFLAGS} -fno-rtti -std=c++11" + CXXFLAGS="${CXXFLAGS} -fno-rtti -std=c++14" dnl preconfigured values for SDL build AC_DEFINE(_SDL, 1, [Defined when building SDL version]) @@ -343,7 +345,7 @@ function buildFLTK() { esac FLTK_CXXFLAGS="${PACKAGE_CFLAGS} `fltk-config --cxxflags`" - FLTK_CXXFLAGS="${FLTK_CXXFLAGS} -fno-exceptions -fno-rtti -std=c++11 -Wno-unknown-pragmas" + FLTK_CXXFLAGS="${FLTK_CXXFLAGS} -fno-exceptions -fno-rtti -std=c++14 -Wno-unknown-pragmas" PACKAGE_LIBS="${PACKAGE_LIBS} `fltk-config --ldstaticflags --use-images`" dnl do not depend on cygwin.dll under cygwin build @@ -441,6 +443,13 @@ echo ${TARGET} echo "CFLAGS=${CFLAGS}" echo "CXXFLAGS=${CXXFLAGS}" echo "PACKAGE_LIBS=${PACKAGE_LIBS}" + +if test x$ac_build_sdl = xyes; then + echo + echo "sdl2: `sdl2-config --version`" + echo "freetype: `pkg-config --version freetype2`" +fi + echo if test x$ac_build_dist = xyes; then diff --git a/debian/changelog b/debian/changelog index c3cd6ba9..26518299 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,8 @@ +smallbasic (0.12.19) unstable; urgency=low + * Various see web site + + -- Chris Warren-Smith Sun, 22 Mar 2020 09:45:25 +1000 + smallbasic (0.12.18) unstable; urgency=low * Various see web site diff --git a/samples/distro-examples/tests/input.bas b/samples/distro-examples/tests/input.bas new file mode 100644 index 00000000..a467bdd5 --- /dev/null +++ b/samples/distro-examples/tests/input.bas @@ -0,0 +1,3 @@ +v = "111111111111111111111111111111111111111111111111111111111111111111111111111" +sinput v; k +print k diff --git a/samples/distro-examples/tests/keymap.bas b/samples/distro-examples/tests/keymap.bas new file mode 100644 index 00000000..81d45897 --- /dev/null +++ b/samples/distro-examples/tests/keymap.bas @@ -0,0 +1,35 @@ +sub foo + ? "f" +end + +definekey 2, foo +definekey 1, foo +definekey 1, foo +definekey 1, foo +definekey 1, 1 +definekey 1, 2 +definekey 1, 3 +definekey 1, 2 +definekey 1, 3 +definekey 2, 0 +definekey 2, 0 +definekey 2, 0 +definekey 2, 0 + +definekey asc("x"), foo +definekey asc("x"), foo +definekey asc("y"), foo +definekey asc("z"), foo +definekey asc("f"), foo +definekey asc("x"), 0 +definekey asc("y"), 0 +definekey asc("z"), 0 + +if (instr(sbver, "SDL") <> 0) then + while 1 + ? "."; + delay 10 + wend +endif + +print "done" diff --git a/samples/distro-examples/tests/output/all.out b/samples/distro-examples/tests/output/all.out index caca2746..9a837c11 100644 --- a/samples/distro-examples/tests/output/all.out +++ b/samples/distro-examples/tests/output/all.out @@ -83,8 +83,8 @@ VIEW: WINDOW: WRITE: ABS:12.2222 -ABSMAX:1 -ABSMIN:9 +ABSMAX:9 +ABSMIN:1 ACOS:nan ACOSH:3.2010898763691 ACOT:0.0811223921009 diff --git a/samples/distro-examples/tests/output/input.out b/samples/distro-examples/tests/output/input.out new file mode 100644 index 00000000..79627b1d --- /dev/null +++ b/samples/distro-examples/tests/output/input.out @@ -0,0 +1 @@ +1.11111111111111E+74 diff --git a/samples/distro-examples/tests/output/keymap.out b/samples/distro-examples/tests/output/keymap.out new file mode 100644 index 00000000..19f86f49 --- /dev/null +++ b/samples/distro-examples/tests/output/keymap.out @@ -0,0 +1 @@ +done diff --git a/src/common/blib.c b/src/common/blib.c index 2825205b..d6b44d3a 100644 --- a/src/common/blib.c +++ b/src/common/blib.c @@ -530,7 +530,7 @@ void cmd_print(int output) { if (code_peek() == kwTYPE_EOC || code_peek() == kwTYPE_LINE) { // There are no parameters if (dev_fstatus(handle)) { - dev_fwrite(handle, (byte *) "\n", 1); + dev_fwrite(handle, (byte *)OS_LINESEPARATOR, sizeof(OS_LINESEPARATOR)); } else { err_fopen(); } @@ -642,7 +642,7 @@ void cmd_print(int output) { }; if (last_op == 0) { - pv_write("\n", output, handle); + pv_write(output == PV_FILE ? OS_LINESEPARATOR : "\n", output, handle); } } @@ -751,7 +751,7 @@ void cmd_input(int input) { inps = malloc(SB_TEXTLINE_SIZE + 1); if (prompt.v.p.ptr) { // prime output buffer with prompt text - int prompt_len = strlen(prompt.v.p.ptr); + int prompt_len = v_strlen(&prompt); int len = prompt_len < SB_TEXTLINE_SIZE ? prompt_len : SB_TEXTLINE_SIZE; strncpy(inps, prompt.v.p.ptr, len); inps[len] = 0; @@ -2835,14 +2835,20 @@ void cmd_definekey(void) { if (!prog_error) { par_getcomma(); - - if (code_peek() != kwTYPE_CALL_UDF) { - err_syntax(kwDEFINEKEY, "%I,%G"); - } else { + switch (code_peek()) { + case kwTYPE_INT: + prog_ip++; + keymap_remove(key, code_getint()); + break; + case kwTYPE_CALL_UDF: keymap_add(key, prog_ip); // skip ahead to avoid immediate call prog_ip += BC_CTRLSZ + 1; + break; + default: + err_syntax(kwDEFINEKEY, "%I,%G"); + break; } } v_free(&var); @@ -2902,7 +2908,7 @@ void cmd_call_vfunc() { if (code_peek() == kwTYPE_LEVEL_BEGIN) { code_skipnext(); } - v_func->v.fn.cb(map); + v_func->v.fn.cb(map, NULL); if (code_peek() == kwTYPE_LEVEL_END) { code_skipnext(); } diff --git a/src/common/blib_db.c b/src/common/blib_db.c index f0e52e5d..e8b619c9 100644 --- a/src/common/blib_db.c +++ b/src/common/blib_db.c @@ -725,7 +725,7 @@ void cmd_fsaveln() { for (int i = 0; i < v_asize(array_p); i++) { var_p = v_elem(array_p, i); fprint_var(handle, var_p); - dev_fwrite(handle, (byte *)"\n", 1); + dev_fwrite(handle, (byte *)OS_LINESEPARATOR, sizeof(OS_LINESEPARATOR)); } } else { // parameter is an string diff --git a/src/common/blib_func.c b/src/common/blib_func.c index da5e5e80..46938e19 100644 --- a/src/common/blib_func.c +++ b/src/common/blib_func.c @@ -122,19 +122,20 @@ void dar_next(long funcCode, var_t *r, var_t *elem_p) { v_set(r, elem_p); } break; - default: // numeric + default: + // numeric n = v_getval(elem_p); switch (funcCode) { case kwABSMIN: n = fabsl(n); - if (r->v.n < n) { + if (n < r->v.n) { r->v.n = n; } break; case kwABSMAX: n = fabsl(n); - if (r->v.n > n) { + if (n > r->v.n) { r->v.n = n; } break; @@ -145,8 +146,8 @@ void dar_next(long funcCode, var_t *r, var_t *elem_p) { case kwSUMSV: r->v.n += (n * n); break; - } // sw2 - } // sw1 + } + } } /* diff --git a/src/common/blib_graph.c b/src/common/blib_graph.c index f56ee869..54f1bfe7 100644 --- a/src/common/blib_graph.c +++ b/src/common/blib_graph.c @@ -884,36 +884,35 @@ void cmd_chart_fstr(var_num_t v, char *buf) { } /* - * draw a chart + * draw a chart * - * x1,y1-x2,y2 = the area to draw - * vals = the values - * count = the number of the values - * xvals, xcount = for ruler the xvalues (use NULL for default) - * chart = chart type (1=line chart, 0=bar chart, 5=points) - * marks = marks type (2 & ruler, 1 & marks) + * x1,y1-x2,y2 = the area to draw + * vals = the values + * count = the number of the values + * xvals, xcount = for ruler the xvalues (use NULL for default) + * chart = chart type (1=line chart, 0=bar chart, 5=points) + * marks = marks type (2 & ruler, 1 & marks) */ -void chart_draw(int x1, int y1, int x2, int y2, var_num_t *vals, int count, var_num_t *xvals, int xcount, - int chart, int marks) { - int *pts; - int rx1, dx, dy, i; - var_num_t vmin, vmax, lx, ly; +void chart_draw(int x1, int y1, int x2, int y2, var_num_t *vals, int count, + var_num_t *xvals, int xcount, int chart, int marks) { + var_num_t lx, ly; char buf[32]; int32_t color = 0; - - rx1 = x1; + int rx1 = x1; // ready dev_settextcolor(0, 15); - pts = (int *) malloc(sizeof(int) * count * 2); + int *pts = (int *) malloc(sizeof(int) * count * 2); - if (marks & 0x2) { // ruler + if (marks & 0x2) { + // ruler x1 += dev_textwidth("00000") + 1; y2 -= (dev_textheight("0") + 1); } if (marks & 0x1) { - if (chart == 1) { // line + if (chart == 1) { + // line x1 += 2; x2 -= 2; y1 += 2; @@ -921,12 +920,13 @@ void chart_draw(int x1, int y1, int x2, int y2, var_num_t *vals, int count, var_ } } - dx = (x2 - x1); - dy = (y2 - y1); + int dx = (x2 - x1); + int dy = (y2 - y1); // limits - vmin = vmax = vals[0]; - for (i = 1; i < count; i++) { + var_num_t vmin = vals[0]; + var_num_t vmax = vals[0]; + for (int i = 1; i < count; i++) { if (vmin > vals[i]) { vmin = vals[i]; } @@ -944,22 +944,22 @@ void chart_draw(int x1, int y1, int x2, int y2, var_num_t *vals, int count, var_ ly = ((var_num_t) dy) / (vmax - vmin); // calc points - for (i = 0; i < count; i++) { - pts[i * 2] = x1 + i * lx; - pts[i * 2 + 1] = y1 + (dy - ((vals[i] - vmin) * ly)); + for (int i = 0; i < count; i++) { + int x = x1 + i * lx; + int y = y1 + (dy - ((vals[i] - vmin) * ly)); + pts[i * 2] = x > 0 ? x : 0; + pts[i * 2 + 1] = y > 0 ? y : 0; } // draw ruler if (marks & 0x2) { - int fh, fw, n, y, x; - var_num_t v; - // vertical - fh = dev_textheight("0"); - n = dy / (fh * 1.5); + int fh = dev_textheight("0"); + int n = dy / (fh * 1.5); if ((n - 1) > 0) { - for (i = 0; i <= n; i++) { + for (int i = 0; i <= n; i++) { + var_num_t v; if (i == 0) { v = vmin; } @@ -970,8 +970,7 @@ void chart_draw(int x1, int y1, int x2, int y2, var_num_t *vals, int count, var_ } cmd_chart_fstr(v, buf); - y = y1 + (dy - ((v - vmin) * ly)); - + int y = y1 + (dy - ((v - vmin) * ly)); if (i != 0) { dev_setxy(rx1 + 1, y + 1, 0); } else { @@ -983,7 +982,7 @@ void chart_draw(int x1, int y1, int x2, int y2, var_num_t *vals, int count, var_ } // horizontal - fw = dev_textwidth("000"); + int fw = dev_textwidth("000"); n = -1; if (count <= 24) { if (count * (fw * 1.34) < dx) { @@ -995,7 +994,8 @@ void chart_draw(int x1, int y1, int x2, int y2, var_num_t *vals, int count, var_ n = dx / (fw * 1.5); } if ((n - 1) > 0) { - for (i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { + var_num_t v; if (i == 0) { v = 0; } else { @@ -1003,12 +1003,10 @@ void chart_draw(int x1, int y1, int x2, int y2, var_num_t *vals, int count, var_ } if (xvals) { // I have xvals - var_num_t x, dx; - var_num_t xmin, xmax; - - xmin = xvals[0]; - xmax = xvals[xcount - 1]; - dx = xmax - xmin; + var_num_t x; + var_num_t xmin = xvals[0]; + var_num_t xmax = xvals[xcount - 1]; + var_num_t dx = xmax - xmin; if (i == 0) { x = xmin; } else if (i == n) { @@ -1022,12 +1020,10 @@ void chart_draw(int x1, int y1, int x2, int y2, var_num_t *vals, int count, var_ ftostr(i + 1, buf); } - // buf[3] = '\0'; fw = dev_textwidth(buf); - x = x1 + v * lx; - + int x = x1 + v * lx; if (chart == 1 || chart == 5) { dev_setxy(x - fw, y2 + 1, 0); } else { @@ -1052,32 +1048,29 @@ void chart_draw(int x1, int y1, int x2, int y2, var_num_t *vals, int count, var_ // draw switch (chart) { - - case 1: // line chart - case 5: // points + case 1: + case 5: + // line chart + // points if (chart == 5) { - for (i = 0; i < count; i++) { + for (int i = 0; i < count; i++) { dev_setpixel(pts[i * 2], pts[i * 2 + 1]); } } else { - for (i = 1; i < count; i++) { + for (int i = 1; i < count; i++) { dev_line(pts[(i - 1) * 2], pts[(i - 1) * 2 + 1], pts[i * 2], pts[i * 2 + 1]); } } // draw marks if (marks & 0x1) { - for (i = 0; i < count; i++) { - int mx, my; - int fh, fw; - + for (int i = 0; i < count; i++) { cmd_chart_fstr(vals[i], buf); - fw = dev_textwidth(buf); - fh = dev_textheight(buf); - - mx = pts[i * 2] - fw / 2; - my = pts[i * 2 + 1]; + int fw = dev_textwidth(buf); + int fh = dev_textheight(buf); + int mx = pts[i * 2] - fw / 2; + int my = pts[i * 2 + 1]; if (my > (y1 + (y2 - y1) / 2)) { my -= fh; @@ -1090,15 +1083,17 @@ void chart_draw(int x1, int y1, int x2, int y2, var_num_t *vals, int count, var_ } dev_setxy(mx, my, 0); dev_print(buf); - dev_rect(pts[i * 2] - 2, pts[i * 2 + 1] - 2, pts[i * 2] + 2, pts[i * 2 + 1] + 2, 1); + dev_rect(pts[i * 2] - 2, pts[i * 2 + 1] - 2, + pts[i * 2] + 2, pts[i * 2 + 1] + 2, 1); } } break; - case 2: // bar chart + case 2: + // bar chart // draw rect color = 0; - for (i = 1; i < count; i++) { + for (int i = 1; i < count; i++) { if (os_color_depth > 2) { dev_setcolor(color); color++; @@ -1112,22 +1107,19 @@ void chart_draw(int x1, int y1, int x2, int y2, var_num_t *vals, int count, var_ if (os_color_depth > 2) { dev_setcolor(color); } - dev_rect(pts[(count - 1) * 2], pts[(count - 1) * 2 + 1], pts[(count - 1) * 2] + lx - 1, y2, 1); + dev_rect(pts[(count - 1) * 2], pts[(count - 1) * 2 + 1], + pts[(count - 1) * 2] + lx - 1, y2, 1); // draw marks if (marks & 0x1) { color = 0; - for (i = 0; i < count; i++) { - int mx, my; - int fh, fw; - + for (int i = 0; i < count; i++) { cmd_chart_fstr(vals[i], buf); - fw = dev_textwidth(buf); - fh = dev_textheight(buf); - - mx = pts[i * 2] + lx / 2 - fw / 2; - my = pts[i * 2 + 1]; + int fw = dev_textwidth(buf); + int fh = dev_textheight(buf); + int mx = pts[i * 2] + lx / 2 - fw / 2; + int my = pts[i * 2 + 1]; if (os_color_depth > 2) { if (my - fh >= y1) { @@ -1162,7 +1154,6 @@ void chart_draw(int x1, int y1, int x2, int y2, var_num_t *vals, int count, var_ break; }; - // free(pts); } @@ -1170,79 +1161,54 @@ void chart_draw(int x1, int y1, int x2, int y2, var_num_t *vals, int count, var_ // CHART // void cmd_chart() { - var_t *var_p, *elem_p; - int i, count; - var_num_t *vals; int32_t prev_fgcolor = dev_fgcolor; int32_t prev_bgcolor = dev_bgcolor; - - // parameters - int chart; - int marks = 0; - int x1 = 0, y1 = 0, x2 = os_graf_mx, y2 = os_graf_my; + int x1 = 0; + int y1 = 0; + int x2 = os_graf_mx; + int y2 = os_graf_my; // chart type - chart = par_getint(); - if (prog_error) - return; - - par_getcomma(); - if (prog_error) - return; + int chart = par_getint(); IF_PROG_ERR_RTN; + par_getcomma(); IF_PROG_ERR_RTN; // array - var_p = par_getvarray(); - if (prog_error) + var_t *var_p = par_getvarray(); IF_PROG_ERR_RTN; + if (!var_p || var_p->type != V_ARRAY) { + err_varisnotarray(); return; - count = v_asize(var_p); + } // optional labels-flag + int marks; if (code_peek() == kwTYPE_SEP) { - par_getcomma(); - if (prog_error) - return; - marks = par_getint(); - if (prog_error) - return; + par_getcomma(); IF_PROG_ERR_RTN; + marks = par_getint(); IF_PROG_ERR_RTN; // optional x1,y1,x2,y2 if (code_peek() == kwTYPE_SEP) { - par_getcomma(); - if (prog_error) - return; - x1 = par_getint(); - if (prog_error) - return; - par_getcomma(); - if (prog_error) - return; - y1 = par_getint(); - if (prog_error) - return; - par_getcomma(); - if (prog_error) - return; - x2 = par_getint(); - if (prog_error) - return; - par_getcomma(); - if (prog_error) - return; - y2 = par_getint(); - if (prog_error) - return; + par_getcomma(); IF_PROG_ERR_RTN; + x1 = par_getint(); IF_PROG_ERR_RTN; + par_getcomma(); IF_PROG_ERR_RTN; + y1 = par_getint(); IF_PROG_ERR_RTN; + par_getcomma(); IF_PROG_ERR_RTN; + x2 = par_getint(); IF_PROG_ERR_RTN; + par_getcomma(); IF_PROG_ERR_RTN; + y2 = par_getint(); IF_PROG_ERR_RTN; } + } else { + marks = 0; } // get array's values - vals = (var_num_t *) malloc(sizeof(var_num_t) * count); - for (i = 0; i < count; i++) { - elem_p = v_elem(var_p, i); + int count = v_asize(var_p); + var_num_t *vals = (var_num_t *) malloc(sizeof(var_num_t) * count); + for (int i = 0; i < count; i++) { + var_t *elem_p = v_elem(var_p, i); if (prog_error) { free(vals); return; } - switch (elem_p->type) { case V_INT: vals[i] = elem_p->v.i; @@ -1260,10 +1226,8 @@ void cmd_chart() { } } - // chart_draw(x1, y1, x2, y2, vals, count, NULL, 0, chart, marks); - // free(vals); dev_settextcolor(prev_fgcolor, prev_bgcolor); } diff --git a/src/common/brun.c b/src/common/brun.c index 58ed89b0..fcf62cc8 100644 --- a/src/common/brun.c +++ b/src/common/brun.c @@ -352,7 +352,7 @@ void cmd_chain(void) { if (var.type == V_STR) { if (access(var.v.p.ptr, R_OK) == 0) { // argument is a file name - int h = open(var.v.p.ptr, O_BINARY | O_RDONLY, 0644); + int h = open(var.v.p.ptr, O_BINARY | O_RDONLY); if (h != -1) { struct stat st; if (fstat(h, &st) == 0) { @@ -1144,7 +1144,7 @@ int brun_create_task(const char *filename, byte *preloaded_bc, int libf) { return search_task(fname); } // open & load - int h = open(fname, O_RDWR | O_BINARY, 0660); + int h = open(fname, O_RDWR | O_BINARY); if (h == -1) { panic("File '%s' not found", fname); } diff --git a/src/common/eval.c b/src/common/eval.c index 56d04d9a..3087c79c 100644 --- a/src/common/eval.c +++ b/src/common/eval.c @@ -19,17 +19,17 @@ #define IP prog_ip #define CODE(x) prog_source[(x)] #define CODE_PEEK() CODE(IP) -#define V_FREE(v) \ - if ((v) && ((v)->type == V_STR || \ - (v)->type == V_MAP || \ - (v)->type == V_ARRAY)) { \ - v_free((v)); \ +#define V_FREE(v) \ + if ((v) && ((v)->type == V_STR || \ + (v)->type == V_MAP || \ + (v)->type == V_ARRAY)) { \ + v_free((v)); \ } -#define V_FREE2(v) \ - if (((v)->type == V_STR || \ - (v)->type == V_MAP || \ - (v)->type == V_ARRAY)) { \ - v_free((v)); \ +#define V_FREE2(v) \ + if (((v)->type == V_STR || \ + (v)->type == V_MAP || \ + (v)->type == V_ARRAY)) { \ + v_free((v)); \ } /** @@ -379,7 +379,7 @@ static inline void oper_mul(var_t *r, var_t *left) { } else { err_matop(); } - } else if (op == '*') { + } else if (op == '*') { mat_mul(left, r); } else { err_matop(); @@ -748,6 +748,7 @@ static inline void eval_var(var_t *r, var_t *var_p) { if (prog_error) { return; } + switch (var_p->type) { case V_INT: r->type = V_INT; @@ -770,7 +771,7 @@ static inline void eval_var(var_t *r, var_t *var_p) { v_set(r, var_p); break; case V_FUNC: - var_p->v.fn.cb(r); + var_p->v.fn.cb(var_p, r); break; case V_NIL: r->type = V_NIL; @@ -1245,23 +1246,6 @@ void eval(var_t *r) { r->v.n = code_getreal(); break; - case kwTYPE_STR: - // string - constant - IP++; - V_FREE(r); - v_eval_str(r); - break; - - case kwTYPE_LOGOPR: - IP++; - oper_log(r, left); - break; - - case kwTYPE_CMPOPR: - IP++; - oper_cmp(r, left); - break; - case kwTYPE_ADDOPR: IP++; oper_add(r, left); @@ -1272,17 +1256,6 @@ void eval(var_t *r) { oper_mul(r, left); break; - case kwTYPE_POWOPR: - IP++; - oper_powr(r, left); - break; - - case kwTYPE_UNROPR: - // unary - IP++; - oper_unary(r); - break; - case kwTYPE_VAR: // variable V_FREE(r); @@ -1317,15 +1290,10 @@ void eval(var_t *r) { IP++; if (!eval_sp) { err_syntax_unknown(); - } else { - eval_sp--; - left = &eval_stk[eval_sp]; + return; } - break; - - case kwTYPE_EVAL_SC: - IP++; - eval_shortc(r); + eval_sp--; + left = &eval_stk[eval_sp]; break; case kwTYPE_CALLF: @@ -1334,48 +1302,80 @@ void eval(var_t *r) { eval_callf(r); break; + case kwTYPE_STR: + // string - constant + IP++; + V_FREE(r); + v_eval_str(r); + break; + + case kwTYPE_LOGOPR: + IP++; + oper_log(r, left); + break; + + case kwTYPE_CMPOPR: + IP++; + oper_cmp(r, left); + break; + + case kwTYPE_POWOPR: + IP++; + oper_powr(r, left); + break; + + case kwTYPE_UNROPR: + // unary + IP++; + oper_unary(r); + break; + + case kwTYPE_EVAL_SC: + IP++; + eval_shortc(r); + break; + case kwTYPE_CALL_UDF: eval_call_udf(r); break; - default: - // less used codes - switch (code) { - case kwTYPE_CALLEXTF: - // [lib][index] external functions - IP++; - eval_extf(r); - break; - - case kwTYPE_PTR: - // UDF pointer - constant - IP++; - eval_ptr(r); - break; + case kwTYPE_CALLEXTF: + // [lib][index] external functions + IP++; + eval_extf(r); + break; - case kwBYREF: - // unexpected code - err_evsyntax(); - break; + case kwTYPE_PTR: + // UDF pointer - constant + IP++; + eval_ptr(r); + break; - default: { - if (code == kwTYPE_EOC || - code == kwTYPE_SEP || - code == kwTO || - kw_check_evexit(code)) { - // restore stack pointer - eval_sp = eval_pos; + case kwBYREF: + // unexpected code + err_evsyntax(); + return; + + default: { + if (code == kwTYPE_LINE || + code == kwTYPE_SEP || + code == kwTO || + code == kwTHEN || + code == kwSTEP || + kw_check_evexit(code)) { + // restore stack pointer + eval_sp = eval_pos; - // normal exit - return; - } - rt_raise("UNKNOWN ERROR. IP:%d=0x%02X", IP, code); - if (!opt_quiet) { - hex_dump(prog_source, prog_length); - } - }}; - } + // normal exit + return; + } + rt_raise("UNKNOWN ERROR. IP:%d=0x%02X", IP, code); + if (!opt_quiet) { + hex_dump(prog_source, prog_length); + } + }}; } + // restore stack pointer eval_sp = eval_pos; } diff --git a/src/common/keymap.c b/src/common/keymap.c index 351175bb..ed4b7c72 100644 --- a/src/common/keymap.c +++ b/src/common/keymap.c @@ -30,7 +30,7 @@ struct key_map_s { int key; // key definition }; -key_map_s* keymap = 0; +key_map_s *keymap = 0; /** * Prepare task_t exec.keymap for keymap handling at program init @@ -42,7 +42,7 @@ void keymap_init() { /** * Handler for keymap_free() */ -void keymap_delete(key_map_s* km) { +void keymap_delete(key_map_s *km) { if (km) { keymap_delete(km->next); free(km); @@ -61,13 +61,13 @@ void keymap_free() { * DEFINEKEY command handler to add a keymap */ void keymap_add(uint32_t key, bcip_t ip) { - key_map_s* km = (key_map_s*) malloc(sizeof (key_map_s)); + key_map_s *km = (key_map_s *)malloc(sizeof(key_map_s)); km->next = 0; km->ip = ip; km->key = key; // add the new mapping onto the linked list - key_map_s* head = keymap; + key_map_s *head = keymap; if (!head) { keymap = km; } else { @@ -78,12 +78,38 @@ void keymap_add(uint32_t key, bcip_t ip) { } } +/** + * DEFINEKEY key, 0 + */ +void keymap_remove(uint32_t key, int level) { + key_map_s *head = keymap; + key_map_s *prev = head; + + while (head) { + if (head->key == key) { + key_map_s *current = head; + prev->next = head->next; + head = head->next; + free(current); + if (current == prev) { + prev = head; + } + if (current == keymap) { + keymap = head; + } + } else { + prev = head; + head = head->next; + } + } +} + /** * invokes the handler for the given key */ int keymap_invoke(uint32_t key) { int result = 0; - key_map_s* head = keymap; + key_map_s *head = keymap; while (head) { if (head->key == key) { bcip_t ip = prog_ip; // store current ip @@ -175,7 +201,7 @@ void timer_free(timer_s *timer) { } void timer_add(var_num_t interval, bcip_t ip) { - timer_s* timer = (timer_s*) malloc(sizeof (timer_s)); + timer_s *timer = (timer_s *)malloc(sizeof (timer_s)); timer->next = NULL; timer->ip = ip; timer->interval = interval; @@ -195,7 +221,7 @@ void timer_add(var_num_t interval, bcip_t ip) { } void timer_run(uint32_t now) { - timer_s* timer = prog_timer; + timer_s *timer = prog_timer; while (timer) { if (timer->value == 0) { // start timer diff --git a/src/common/keymap.h b/src/common/keymap.h index e8d50d71..8b7c070a 100644 --- a/src/common/keymap.h +++ b/src/common/keymap.h @@ -87,6 +87,7 @@ extern "C" { void keymap_init(); void keymap_free(); void keymap_add(uint32_t key, bcip_t ip); +void keymap_remove(uint32_t key, int level); int keymap_invoke(uint32_t key); int keymap_kbhit(); int keymap_kbpeek(); diff --git a/src/common/kw.c b/src/common/kw.c index 82399de0..989c9a13 100644 --- a/src/common/kw.c +++ b/src/common/kw.c @@ -10,32 +10,6 @@ #include "common/var.h" #include "common/scan.h" -/* - * valid exit codes from eval - */ -code_t kw_eval_validexit[] = { - kwTYPE_EOC, - kwTYPE_LINE, - kwTYPE_SEP, - kwFILLED, - kwCOLOR, - kwUSE, - kwTO, - kwIN, - kwSTEP, - kwFORSEP, - kwINPUTSEP, - kwINPUT, - kwOUTPUTSEP, - kwAPPENDSEP, - kwAS, - kwUSING, - kwTHEN, - kwDO, - kwBACKG, - 0 -}; - /* * functions without parameters */ @@ -53,31 +27,41 @@ bid_t kw_noarg_func_table[] = { 0 }; -// -int kw_check(code_t *table, code_t code) { - register int i; - - for (i = 0; table[i] != 0; i++) { - if (code == table[i]) { - return 1; - } - } - return 0; -} - -// +/* + * valid exit codes from eval + */ int kw_check_evexit(code_t code) { - return kw_check(kw_eval_validexit, code); + switch (code) { + case kwTYPE_EOC: + case kwTYPE_LINE: + case kwTYPE_SEP: + case kwFILLED: + case kwCOLOR: + case kwUSE: + case kwTO: + case kwIN: + case kwSTEP: + case kwFORSEP: + case kwINPUTSEP: + case kwINPUT: + case kwOUTPUTSEP: + case kwAPPENDSEP: + case kwAS: + case kwUSING: + case kwTHEN: + case kwDO: + case kwBACKG: + return 1; + default: + return 0; + } } -/* - */ int kw_getcmdname(code_t code, char *dest) { - int i; int found = 0; *dest = '\0'; - for (i = 0; keyword_table[i].name[0] != '\0'; i++) { + for (int i = 0; keyword_table[i].name[0] != '\0'; i++) { if (code == keyword_table[i].code) { strcpy(dest, keyword_table[i].name); found++; @@ -90,14 +74,11 @@ int kw_getcmdname(code_t code, char *dest) { return found; } -/* - */ int kw_getfuncname(bid_t code, char *dest) { - int i; int found = 0; *dest = '\0'; - for (i = 0; func_table[i].name[0] != '\0'; i++) { + for (int i = 0; func_table[i].name[0] != '\0'; i++) { if (code == func_table[i].fcode) { strcpy(dest, func_table[i].name); found++; @@ -110,14 +91,11 @@ int kw_getfuncname(bid_t code, char *dest) { return found; } -/* - */ int kw_getprocname(bid_t code, char *dest) { - int i; int found = 0; *dest = '\0'; - for (i = 0; proc_table[i].name[0] != '\0'; i++) { + for (int i = 0; proc_table[i].name[0] != '\0'; i++) { if (code == proc_table[i].pcode) { strcpy(dest, proc_table[i].name); found++; @@ -130,12 +108,8 @@ int kw_getprocname(bid_t code, char *dest) { return found; } -/* - */ int kw_noarg_func(bid_t code) { - int i; - - for (i = 0; kw_noarg_func_table[i] != 0; i++) { + for (int i = 0; kw_noarg_func_table[i] != 0; i++) { if (kw_noarg_func_table[i] == code) { return 1; } diff --git a/src/common/kw.h b/src/common/kw.h index fda521a1..e692796d 100644 --- a/src/common/kw.h +++ b/src/common/kw.h @@ -55,42 +55,42 @@ extern "C" { * special seperators too like INPUT, APPEND, FORSEP * and, of course, root commands like REPEAT-UNTIL, IF, etc */ -enum keyword { // line 50 +enum keyword { kwTYPE_INT = 0x1, /* 32b Integer */ kwTYPE_NUM, /* 64b Real */ - kwTYPE_STR, /* String */ - kwTYPE_LOGOPR, /* Logical operator */ - kwTYPE_CMPOPR, /* Comparation operator */ kwTYPE_ADDOPR, /* ADD/SUB operator */ kwTYPE_MULOPR, /* MUL/DIV/IDIV operator */ - kwTYPE_POWOPR, /* POW(x,y) operator */ - kwTYPE_UNROPR, /* Unary operator */ kwTYPE_VAR, /* Variable */ - kwTYPE_UDS_EL, /* Structure element */ - kwTYPE_SEP, /* Separator */ - kwTYPE_LINE, /* Debug info: SOURCE LINE */ kwTYPE_LEVEL_BEGIN, /* Parenthesis ( */ kwTYPE_LEVEL_END, /* Parenthesis ) */ - kwTYPE_EOC, /* End-Of-Command mark */ kwTYPE_EVPUSH, /* PUSH R */ kwTYPE_EVPOP, /* POP L */ - kwTYPE_EVAL_SC, /* Evalulation short-circuit begin */ kwTYPE_CALLF, /* Call a build-in function */ - kwTYPE_CALLP, /* Call a build-in procedure */ + kwTYPE_STR, /* String */ + kwTYPE_LOGOPR, /* Logical operator */ + kwTYPE_CMPOPR, /* Comparation operator */ + kwTYPE_POWOPR, /* POW(x,y) operator */ + kwTYPE_UNROPR, /* Unary operator */ + kwTYPE_EVAL_SC, /* Evalulation short-circuit begin */ kwTYPE_CALL_UDF, /* Call user defined function */ + kwTYPE_CALLEXTF, /* Call an external function */ + kwTYPE_PTR, /* Address pointer, eg f=@foo */ + kwBYREF, /* end eval switch block */ kwTYPE_CALL_UDP, /* Call user defined procedure */ kwTYPE_CALL_PTR, /* Call user defined procedure or function from address pointer */ kwTYPE_CALL_VFUNC, /* Call virtual function */ - kwTYPE_CALLEXTF, /* Call an external function */ kwTYPE_CALLEXTP, /* Call an external procedure */ kwTYPE_CRVAR, /* Create dynamic variable (PARAMETERS OR LOCALS) */ kwTYPE_RET, /* Return from UDF|UDP */ kwTYPE_PARAM, /* Parameters */ - kwTYPE_PTR, /* Address pointer, eg f=@foo */ + kwTYPE_CALLP, /* Call a build-in procedure */ + kwTYPE_EOC, /* End-Of-Command mark */ + kwTYPE_UDS_EL, /* Structure element */ + kwTYPE_SEP, /* Separator */ + kwTYPE_LINE, /* Debug info: SOURCE LINE */ kwLOCAL, /* Create local variables */ kwFUNC, /* USER DEFINED FUNCTION */ kwPROC, /* USER DEFINED PROCEDURE */ - kwBYREF, kwDECLARE, kwIMPORT, kwEXPORT, diff --git a/src/common/smbas.h b/src/common/smbas.h index 59823acd..ab463193 100644 --- a/src/common/smbas.h +++ b/src/common/smbas.h @@ -133,6 +133,9 @@ EXTERN char gsb_last_errmsg[SB_ERRMSG_SIZE + 1]; /**< last error message */ #include "common/units.h" #include "common/tasks.h" +#define IF_PROG_ERR_RTN if (ctask->error) { return; } +#define IF_PROG_ERR_BRK if (ctask->error) { break; } + // emulation #define prog_line ctask->line #define comp_line ctask->line diff --git a/src/common/sys.h b/src/common/sys.h index 413ea599..fa28742a 100644 --- a/src/common/sys.h +++ b/src/common/sys.h @@ -54,8 +54,10 @@ extern "C" { #if defined(_Win32) #define SB_VERSYS "Win" + #define OS_LINESEPARATOR "\r\n" #else #define SB_VERSYS "Unix" + #define OS_LINESEPARATOR "\r\n" #endif #if UINTPTR_MAX == 0xffffffff diff --git a/src/common/units.c b/src/common/units.c index 87e18f1b..a3b19202 100644 --- a/src/common/units.c +++ b/src/common/units.c @@ -147,7 +147,7 @@ int open_unit(const char *file) { } // open unit - h = open(unitname, O_RDWR | O_BINARY, 0660); + h = open(unitname, O_RDWR | O_BINARY); if (h == -1) { return -1; } @@ -218,18 +218,15 @@ int close_unit(int uid) { * @return 0 on success */ int import_unit(int uid) { - char buf[SB_KEYWORD_SIZE + 1];int i; - if (uid >= 0) { unit_t *u = &units[uid]; if (u->status == unit_loaded) { - for (i = 0; i < u->hdr.sym_count; i++) { - // build the name - // with any path component removed from the name + for (int i = 0; i < u->hdr.sym_count; i++) { + // build the name with any path component removed from the name + char buf[SB_KEYWORD_SIZE + SB_KEYWORD_SIZE + 1]; char *dir_sep = strrchr(u->hdr.base, OS_DIRSEP); sprintf(buf, "%s.%s", - dir_sep ? dir_sep + 1 : u->hdr.base, u->symbols[i].symbol); - + dir_sep ? dir_sep + 1 : u->hdr.base, u->symbols[i].symbol); switch (u->symbols[i].type) { case stt_function: comp_add_external_func(buf, uid | UID_UNIT_BIT); @@ -242,12 +239,10 @@ int import_unit(int uid) { break; }; } - } - else { + } else { return -2; } - } - else { + } else { return -1; } diff --git a/src/common/var.c b/src/common/var.c index 2dfad5ac..aa9983c6 100644 --- a/src/common/var.c +++ b/src/common/var.c @@ -767,15 +767,15 @@ void v_zerostr(var_t *r) { void v_input2var(const char *str, var_t *var) { v_free(var); - if (strlen(str) == 0) { + if (!str || str[0] == '\0') { // no data v_setstr(var, str); } else { - char buf[INT_STR_LEN]; int type; var_int_t lv; var_num_t dv; + char *buf = strdup(str); char *sb = strdup(str); char *np = get_numexpr(sb, buf, &type, &lv, &dv); @@ -787,6 +787,7 @@ void v_input2var(const char *str, var_t *var) { v_setstr(var, str); } free(sb); + free(buf); } } diff --git a/src/common/var_map.c b/src/common/var_map.c index cbe6f629..5e9946f2 100644 --- a/src/common/var_map.c +++ b/src/common/var_map.c @@ -90,7 +90,7 @@ int map_length(const var_p_t var_p) { var_p_t map_get(var_p_t base, const char *name) { var_p_t result; - if (base->type == V_MAP) { + if (base != NULL && base->type == V_MAP) { result = hashmap_get(base, name); } else { result = NULL; diff --git a/src/include/module.h b/src/include/module.h index 78f90415..abe94f4a 100644 --- a/src/include/module.h +++ b/src/include/module.h @@ -54,7 +54,7 @@ void sblib_close(void); * * plugin based event handling */ -int sblib_events(int wait_flag); +int sblib_events(int wait_flag, int *w, int *h); /** * @ingroup modlib @@ -130,7 +130,6 @@ int sblib_func_exec(int index, int param_count, slib_par_t *params, var_t *retva * * overrides for osd_xx functions */ -int sblib_events(int); int sblib_getpen(int code); int sblib_getx(); int sblib_gety(); diff --git a/src/include/var.h b/src/include/var.h index f5a2eadd..11819e4f 100644 --- a/src/include/var.h +++ b/src/include/var.h @@ -47,7 +47,7 @@ extern "C" { #endif struct var_s; -typedef void (*method) (struct var_s *self); +typedef void (*method) (struct var_s *self, struct var_s *retval); typedef struct var_s { union { diff --git a/src/lib/jsmn b/src/lib/jsmn index 7b6858a5..053d3cd2 160000 --- a/src/lib/jsmn +++ b/src/lib/jsmn @@ -1 +1 @@ -Subproject commit 7b6858a5855299d173c5ab2b46e611bf9961cbef +Subproject commit 053d3cd29200edb1bfd181d917d140c16c1f8834 diff --git a/src/lib/lodepng b/src/lib/lodepng index e34ac045..34628e89 160000 --- a/src/lib/lodepng +++ b/src/lib/lodepng @@ -1 +1 @@ -Subproject commit e34ac04553e51a6982ae234d98ce6b76dd57a6a1 +Subproject commit 34628e89e80cd007179b25b0b2695e6af0f57fac diff --git a/src/lib/miniaudio b/src/lib/miniaudio index df2903a0..b80f7f94 160000 --- a/src/lib/miniaudio +++ b/src/lib/miniaudio @@ -1 +1 @@ -Subproject commit df2903a0bcaf0126f9ad43d2b1238891b55bc2f6 +Subproject commit b80f7f949152f93a0af499b4d6d07b8e60d0e673 diff --git a/src/lib/stb b/src/lib/stb index f54acd4e..b42009b3 160000 --- a/src/lib/stb +++ b/src/lib/stb @@ -1 +1 @@ -Subproject commit f54acd4e13430c5122cab4ca657705c84aa61b08 +Subproject commit b42009b3b9d4ca35bc703f5310eedc74f584be58 diff --git a/src/platform/android/app/build.gradle b/src/platform/android/app/build.gradle index 4f2cb966..7918d71a 100644 --- a/src/platform/android/app/build.gradle +++ b/src/platform/android/app/build.gradle @@ -2,15 +2,15 @@ apply plugin: 'com.android.application' android { // app can use the API features included in this API level and lower. - compileSdkVersion 28 + compileSdkVersion 29 // can override some attributes in main/AndroidManifest.xml defaultConfig { applicationId 'net.sourceforge.smallbasic' minSdkVersion 16 targetSdkVersion 28 - versionCode 39 - versionName "0.12.17" + versionCode 40 + versionName "12.19" resConfigs "en" } diff --git a/src/platform/android/app/src/main/assets/main.bas b/src/platform/android/app/src/main/assets/main.bas index 42256323..4ef23fe2 100644 --- a/src/platform/android/app/src/main/assets/main.bas +++ b/src/platform/android/app/src/main/assets/main.bas @@ -1,19 +1,23 @@ -const app = "main.bas?" -const boldOn = chr(27) + "[1m" -const boldOff = chr(27) + "[21m" -const scrollHome = chr(27) + "m" +const boldOn = "\033[1m" +const boldOff = "\033[21m" +const scrollHome = "\033m" const char_h = txth("Q") const char_w = txtw(".") const lineSpacing = 2 + char_h -const idxEdit = 6 -const idxFiles = 7 -const colGrey = rgb(100, 100, 100) -const colBkGnd = rgb(31, 28, 31) -const colText = 2 -const colLink = 3 +const wnd = window() +const theme = wnd.theme +const colBkGnd = theme.background +const colText = theme.text5 +const colFile = theme.text2 +const colDir = theme.text3 +const colText2 = theme.text4 +const colNav = theme.text1 +const colNav2 = theme.text6 const menu_gap = -(char_w / 2) const is_sdl = instr(sbver, "SDL") != 0 const onlineUrl = "http://smallbasic.github.io/samples/index.bas" +const idxEdit = 6 +const idxFiles = 7 const saveasId = "__bn_saveas__" const renameId = "__bn_rename__" const deleteId = "__bn_delete__" @@ -37,7 +41,7 @@ func mk_bn(value, lab, fg) bn.value = value bn.label = lab bn.color = fg - mk_bn = bn + return bn end func mk_menu(value, lab, x) @@ -46,9 +50,9 @@ func mk_menu(value, lab, x) bn.y = ypos * char_h bn.value = value bn.label = "[" + lab + "]" - bn.color = colLink + bn.color = colNav bn.type = "link" - mk_menu = bn + return bn end func mk_scratch() @@ -72,7 +76,6 @@ func mk_scratch() tsave scratch_file, text result = true catch e - local wnd = window() logprint e wnd.alert("Failed to create: " + scratch_file) end try @@ -87,7 +90,7 @@ sub do_okay_button(bn_extra) button.label = "[Close]" button.x = (xmax - txtw(button.label)) / 2 button.y = ypos * char_h - button.color = colLink + button.color = colNav button.type = "link" if (ismap(bn_extra)) then frm.inputs << bn_extra @@ -117,7 +120,7 @@ sub do_about() print "__)| | |(_||||_)/--\__)|\_" endif print - color 7 + color colText print "Version "; sbver print print "Copyright (c) 2002-2020 Chris Warren-Smith" @@ -133,17 +136,17 @@ sub do_about() else bn_home.label = "https://smallbasic.github.io/pages/android.html" endif - bn_home.color = colLink + bn_home.color = colNav print:print - color colGrey + color colText2 print "SmallBASIC comes with ABSOLUTELY NO WARRANTY. "; print "This program is free software; you can use it "; print "redistribute it and/or modify it under the terms of the "; print "GNU General Public License version 2 as published by "; print "the Free Software Foundation." + chr(10) print - color 7 + color colText server_info() do_okay_button(bn_home) clear_screen() @@ -152,7 +155,7 @@ end sub do_setup() local frm - color 3, colBkGnd + color colText, colBkGnd cls print boldOn + "Setup web service port number." print boldOff @@ -161,7 +164,7 @@ sub do_setup() print "this screen without making any changes." print "The current setting is: " + env("serverSocket") print - color 15, 3 + color colText, colBkGnd input socket if (len(socket) > 0) then @@ -174,7 +177,7 @@ sub do_setup() env("serverToken=" + token) endif - color 3, colBkGnd + color colText, colBkGnd cls print "Web service port number: " + env("serverSocket") print @@ -196,7 +199,6 @@ sub do_setup() env("fontId=" + frm.inputs(0).selectedIndex) local msg = "You must restart SmallBASIC for this change to take effect." - local wnd = window() wnd.alert(msg, "Restart required") clear_screen() end @@ -293,9 +295,9 @@ end sub listFiles(byref frm, path, sortDir, byref basList) local lastItem, bn, abbr, gap, n, lab, name, txtcol, i - local name_col = 3 - local size_col = 3 - local date_col = 3 + local name_col = colNav + local size_col = colNav + local date_col = colNav if (right(path, 1) != "/") then path += "/" @@ -307,28 +309,28 @@ sub listFiles(byref frm, path, sortDir, byref basList) sort basList use filecmpfunc0(x,y) case 1 sort basList use filecmpfunc1(x,y) - name_col = 6 + name_col = colNav2 case 2 sort basList use filecmpfunc2(x,y) - size_col = 5 + size_col = colNav2 case 3 sort basList use filecmpfunc3(x,y) - size_col = 6 + size_col = colNav2 case 4 sort basList use filecmpfunc4(x,y) - date_col = 5 + date_col = colNav2 case 5 sort basList use filecmpfunc5(x,y) - date_col = 6 + date_col = colNav2 end select - bn = mk_bn(0, "Files in " + path, 7) + bn = mk_bn(0, "Files in " + path, colText) bn.type = "label" bn.x = 0 bn.y = -lineSpacing frm.inputs << bn - bn = mk_bn(backId, "[Go up]", 3) + bn = mk_bn(backId, "[Go up]", colNav) bn.type = "link" bn.x = 0 bn.y = -linespacing @@ -358,7 +360,7 @@ sub listFiles(byref frm, path, sortDir, byref basList) lastItem = len(basList) - 1 for i = 0 to lastItem node = basList(i) - txtcol = iff(node.dir, 3, 2) + txtcol = iff(node.dir, colDir, colFile) name = node.name if (abbr) then bn = mk_bn(path + name, name, txtcol) @@ -377,7 +379,7 @@ sub listFiles(byref frm, path, sortDir, byref basList) gap = 12 - len(str(node.size)) n = iff(gap > 1, gap, 1) - bn = mk_bn(0, node.size + space(n) + timestamp(node.mtime), colGrey) + bn = mk_bn(0, node.size + space(n) + timestamp(node.mtime), colText) bn.type = "label" bn.y = -1 gap = 29 - len(name) @@ -388,7 +390,7 @@ sub listFiles(byref frm, path, sortDir, byref basList) end sub manageFiles() - local f, wnd, bn_edit, bn_files, selectedFile + local f, bn_edit, bn_files, selectedFile func fileCmpFunc(l, r) local f1 = lower(l) @@ -425,7 +427,7 @@ sub manageFiles() bn_edit.y = char_h + 4 bn_edit.width = xmax bn_edit.type = "text" - bn_edit.color = "white" + bn_edit.color = colText2 bn_edit.resizable = TRUE bn_edit.help = "Enter file name, and then click New." bn_files.x = x1 @@ -518,7 +520,7 @@ sub manageFiles() else tload selectedFile, buffer wnd.graphicsScreen2() - color 7 + color colText cls len_buffer = len(buffer) - 1 for i = 0 to len_buffer @@ -569,7 +571,6 @@ sub manageFiles() createUI() reloadList(0) - wnd = window() wnd.showKeypad() while 1 @@ -606,7 +607,6 @@ func changeDir(s) chdir s return true catch e - local wnd = window() wnd.alert(e) return false end try @@ -695,17 +695,17 @@ sub main elif (frm.value == sortNameId) then cls sortDir = iff(sortDir==0,1,0) - env("sortDir="+sortDir) + env("sortDir=" + sortDir) frm = makeUI(path, sortDir) elif (frm.value == sortSizeId) then cls sortDir = iff(sortDir==3,2,3) - env("sortDir="+sortDir) + env("sortDir=" + sortDir) frm = makeUI(path, sortDir) elif (frm.value == sortDateId) then cls sortDir = iff(sortDir==5,4,5) - env("sortDir="+sortDir) + env("sortDir=" + sortDir) frm = makeUI(path, sortDir) fi wend diff --git a/src/platform/android/app/src/main/java/net/sourceforge/smallbasic/MainActivity.java b/src/platform/android/app/src/main/java/net/sourceforge/smallbasic/MainActivity.java index 95e93a85..fa2f7b7b 100644 --- a/src/platform/android/app/src/main/java/net/sourceforge/smallbasic/MainActivity.java +++ b/src/platform/android/app/src/main/java/net/sourceforge/smallbasic/MainActivity.java @@ -21,9 +21,11 @@ import android.media.AudioManager; import android.media.MediaPlayer; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.Handler; +import android.provider.Settings; import android.util.Base64; import android.util.DisplayMetrics; import android.util.Log; @@ -82,7 +84,7 @@ /** * Extends NativeActivity to provide interface methods for runtime.cpp * - * @author chrisws + * @author Chris Warren-Smith */ public class MainActivity extends NativeActivity { private static final String TAG = "smallbasic"; @@ -342,6 +344,12 @@ public boolean getUntrusted() { return this._untrusted; } + public int getWindowHeight() { + Rect rect = new Rect(); + findViewById(android.R.id.content).getWindowVisibleDisplayFrame(rect); + return rect.height(); + } + @Override public void onGlobalLayout() { super.onGlobalLayout(); @@ -586,11 +594,17 @@ public void onClick(DialogInterface dialog, int which) {} public void showKeypad(final boolean show) { Log.i(TAG, "showKeypad: " + show); final View view = getWindow().getDecorView(); + final Activity activity = this; runOnUiThread(new Runnable() { public void run() { InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); if (imm != null) { if (show) { + String id = Settings.Secure.getString(activity.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD); + if ("com.sec.android.inputmethod/.SamsungKeypad".equals(id)) { + String message = getResources().getString(R.string.samsung_keyboard); + Toast.makeText(activity, message, Toast.LENGTH_LONG).show(); + } imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT); } else { imm.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); @@ -771,6 +785,10 @@ private String getExternalStorage() { } else { result = path; } + } else if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + // https://commonsware.com/blog/2019/06/07/death-external-storage-end-saga.html + File[] dirs = getExternalMediaDirs(); + result = dirs[0].getAbsolutePath(); } else { result = getInternalStorage(); } diff --git a/src/platform/android/app/src/main/java/net/sourceforge/smallbasic/TextToSpeechAdapter.java b/src/platform/android/app/src/main/java/net/sourceforge/smallbasic/TextToSpeechAdapter.java index 0278028d..1ff45944 100644 --- a/src/platform/android/app/src/main/java/net/sourceforge/smallbasic/TextToSpeechAdapter.java +++ b/src/platform/android/app/src/main/java/net/sourceforge/smallbasic/TextToSpeechAdapter.java @@ -1,12 +1,12 @@ package net.sourceforge.smallbasic; -import java.util.Locale; - import android.content.Context; import android.speech.tts.TextToSpeech; import android.speech.tts.TextToSpeech.OnInitListener; import android.util.Log; +import java.util.Locale; + class TextToSpeechAdapter implements OnInitListener { private static final String TAG = "smallbasic"; private final TextToSpeech _tts; diff --git a/src/platform/android/app/src/main/res/values/strings.xml b/src/platform/android/app/src/main/res/values/strings.xml index e31bb091..bb11245f 100644 --- a/src/platform/android/app/src/main/res/values/strings.xml +++ b/src/platform/android/app/src/main/res/values/strings.xml @@ -1,6 +1,7 @@ SmallBASIC + Samsung keyboard not supported. Please use an alternative keyboard.