hBasic > hManual > Commands

hBasic Manual
Commands and Category changes

Console


Console commands
commands that affect the output console
Graphics


Graphics commands
commands that affect the graphics screen
HTML
commands that affect the web browser

HTML.OPEN
Decors Flag

HTML.TITLE
Title and Colors
Menu
 

MENU commands The action bar menu system
File/FTP File/FTP


TEXT.WRITELN Now stream based.

FILE.SAF commands Provides read/write access for external sdcards

FILE flags ok flags added to FILE Client commands

FILE.DELETE Recursive delete option added

FTP flags ok flags added to FTP Client commands

FTPS commands Controls hBasic's internal FTP server
System


DEVICE$ (..)
Gets specific device information as a string

VERSION$(0)
Gets the underlying master version

PROGRAM.Info
App information

Decors Flag Window items for  Graphics and HTML views.

Title and Colors
Subtitle and Colors
ActionBar Titles  and Colors for Console, Graphics and HTML
ActionBar Subtitles and Colors

Color Strings For various commands

DEBUG.DUMP.FN
Prints the function name(s) from the function stack
Hardware


SENSORS
upgraded

GPS
upgraded
Other


BUNDLE
Enhancements
Accept Multiple Input.
Bundle 'auto' Mode. (convenience loading for tags and variables)

CLIPBOARD upgraded

FN.DEF Functions can now return an array

FN.IMPORT Imports global variables into functions

INPUT Restrict INPUT to a single row

NOTIFY NOTIFY sub commands .STATUS and .CANCEL

OnORIENT
 and ORIENT.Resume  Interrupt

REDIM Re-Dimension existing arrays

SQL.PING Ping a database, table or column for existence

TEXT.INPUT Added Cancel flag.

SMS commands
All SMS commands removed since v2.60 (playstore compliance)

TEXT.WRITELN

Fixes
In legacy basic, this command was line-based using a buffer to collect continuation text.
In hBasic (since v.4.93) it is now stream based and the buffer is removed. This means all text is output directly.

This fixes the problem of a last line having continuation (";") and not being written. And also fixes the conflict of multiple output files sharing the only one buffer.

( For legacy programs, there should be no need to make any adjustments to the Basic code. )

Note: The final output still uses an internal buffer (which is not related to continuation). It is therefore still strongly advised that TEXT.CLOSE be called to ensure that any remaining text is wriiten and the file closed.

FTP.<XXX> Return Flags

An optional return flag was inserted into these FTP client commands.

FTP.OPEN   {ok_nvar,} <url_sexp>, <port_nexp>, <user_sexp>, <pw_sexp>
FTP.PUT    {ok_nvar,} <source_sexp>, <destination_sexp>
FTP.GET    {ok_nvar,} <source_sexp>, <destination_sexp>
FTP.DIR    {ok_nvar,} <list_nvar> {,<dirmark_sexp>}
FTP.CD     {ok_nvar,} <new_directory_sexp>
FTP.RENAME {ok_nvar,} <old_filename_sexp>, <new_filename_sexp>
FTP.DELETE {ok_nvar,} <filename_sexp>>
FTP.RMDIR  {ok_nvar,} <directory_sexp>
FTP.MKDIR  {ok_nvar,} <directory_sexp>
FTP.CLOSE  {ok_nvar}

If ok_nvar is not present, an error will stop with an error message (like legacy Basic).
If ok_nvar is present, the app will not stop with a run-time error.

if ok_nvar is 1 (true), the command was successful. There was no error.
if ok_nvar is 0, (false) there was an error. Further information may be contained in getERROR$().
FTPS Commands

These commands control the built-in ftp server.

    FTPS.SET rc_nvar { options}
                Configures the server. (must restart server after)

    FTPS.START rc_nvar { options}
                Starts the server.

    FTPS.STOP rc_nvar
                Stops the server.

Return codes

All commands return an exit code (not optional) which will be one of the following;

0
ok
1
could not start server
2
server already running
3
could not stop server
4
server already closed
5
bad port number (port number must be 1025 to 65535)
6
no internet permission

FTPS.SET return_code_nvar {,port_nexp} {,username_sexp} {,password_sexp} {,welcome_string_sexp}

Configures the server. (must restart server after)

port_nexp the server's control port (1025 to 65535)

default port : 2345
username_sexp the login user name from client to server

default name : hbasic
password_sexp the login password from client to server

default password : hbasic
welcome_string_sexp The welcome string from server to client.
This must not contain newline characters.

default msg : "Welcome to the hBasic's FTP-Server"

e.g
FTPS.SET rc, "john", "mypass"
FTPS.SET rc, "john", p$, "Welcome to myApp's Server"
FTPS.SET ,,newpassword$


Use lowercase for all parameters.

The config does not take place until a new server starts. So do this before starting the server.

Do not put any newlines ("\n") inside the welcome string.
Note that some ftp-clients do not allow to have empty usernames and/or passwords.

FTPS.START return_code_nvar {,IP_svar}

Starts the server.

Returns IP_svar as the server's ip address plus the port number used as "d.d.d.d:port"
e.g    192.0.0.105:2345

e.g
FTPS.START rc, IP$
IF rc > 0 THEN PRINT "Error" ELSE PRINT "Server started on ";IP$

FTPS.STOP return_code_nvar

Stops the server.
e.g
FTPS.STOP rc
IF rc <> 0 THEN PRINT "Error" ELSE PRINT "Server stopped"
FILE.<XXX> Return Flag

An optional ok return flag was inserted into these FILE commands.

FILE.MKDIR  {ok_nvar,} <path_sexp>
FILE.DIR    {ok_nvar,} <path_sexp>, Array$[] {,<dirmark_sexp>}
FILE.RENAME {ok_nvar,} <old_path_sexp>, <new_path_sexp>
FILE.DELETE {ok_nvar,} <path_sexp>


If ok_nvar is not present, an error will stop with an error message (like legacy Basic).
If ok_nvar is present, the app will not stop with a run-time error.

if ok_nvar is 1 (true), the command was succesful. There was no error.
if ok_nvar is 0, (false) there was an error.

FILE.DELETE

The return flag ok_nvar is now optional
An option to delete recursively was added to this command.

FILE.DELETE {ok_nvar,} path_sexp {,recurse_nexp}

Becareful with the recurse option. A blank path will delete the default directory.

if ok_nvar is 1 (true), the command was succesful. The file/dir existed and was deleted.
if ok_nvar is 0, (false) there was an error. Either the file/dir did not exist or could not be deleted.

If <path_sexp> is a non-empty directory and recurse_nexp is false;
then the directory will not be deleted and ok_nvar is false.
If <path_sexp> is a non-empty directory and recurse_nexp is true
then the directory and all subdirectories and files will be deleted.
If succesful, ok_nvar is true.
FN_IMPORT

This command imports 'global' (main) variables into the function's local variable list as referenced variables with the same name.

Effectively, you can import main variables into the function with read/write access.

FN.IMPORT nvar | svar | array[] | array$[] { , ... }

e.g     FN.IMPORT a, foo$, b[], c$[]    % imports main variables a,foo$,b[] and c$[]

And here are the rules;

    1. You can only use FN.IMPORT inside a function.
    2. You can use the FN.IMPORT command anywhere inside a function, and even more than once.
    3. The import will only take effect after the fn.import command (not before).
    4. Variable(s) given will ONLY be searched in the main program namespace (no where else).
    5. Any changes to an imported variable will also change the main variable.
    6. You must import at least one variable.
    7. You cannot repeat variables during import or have the same name local variable in the function.
    8. You can only import variables, not functions nor any other literals.

Example
    fn.def test()
        % fn.import a,a     % error: var Duplicate: a

        fn.import b
        % fn.import b       % error: var Duplicate: b

        b=3
    fn.end

    a=1 : b=2
    test()
    print b
    end

Output:
3

Bundle Enhancements

Multiple Input
These are enhancements made to accept multiple input parameters instead of just one with the same command.

BUNDLE.PUT <pointer_nexp>, <key_sexp>, <val_nexp>|<val_sexp> {, <key, val>...}

puts one or more objects in a bundle.
e.g
bundle.put mybundle, "Key1",99, "Key2","RED", "Key3","Balloons"

BUNDLE.GET
<pointer_nexp>, <key_sexp>, <val_nvar>|<val_svar> {, <key, val>...}

gets one or more objects from a bundle.
e.g
bundle.get mybundle, "Key1",k1, "Key2",k2$

Bundle 'auto' Mode

This enhancement made to get or put variables with the same named tag as a convenience.
For 'auto' mode, you only have to specify the variable (the tag is matched with the variable).

'auto' mode starts with a ' { ', followed by a list of comma separated variable names.
 and ends with a ' } '.

Variables must be numeric or strings. They cannot be arrays, array cells, literal numbers nor literal strings or you will get a syntax error.

The matching tags will be lower case with no spaces.    (Basic will always lower case all variable names)
The matching tags which are strings will also have the ending ' $ '.
 e.g'

BUNDLE.PUT mybundle, { v1, v2$, v3 }
puts tags "v1", "v2$", "v3"  and loads the bundle with content from variables v1,v2$,v3

BUNDLE.GET mybundle, { v1, v2$, v3 }
gets content from bundle using tags "v1","v2$","v3" into variables v1,v2$,v3

'auto' mode can also be mixed in with 'normal mode;

BUNDLE.PUT mybundle, "mytag0", v0,  { v1, v2$, v3 },  "mytag4", 44

Accept a Color String

For these existing commands, a color string (similar to console.set) may be used in place of the 4 decimal colors at the front of the command.

GR.OPEN { { {alpha}{, red}{, green}{, blue} | {color_sexp} } {, <statusBar_lexp>}{, <orientation_nexp>}}
GR.COLOR { { {alpha}{, red}{, green}{, blue} | {color_sexp} } {, style}{, paint}}

e.g
GR.OPEN "blue", 1,1

is the same as
GR.OPEN 255,0,0,255,1,1

Color strings may also be used with these commands

GR.TITLE                {title_sexp} {,textcolor_sexp}, {,backcolor_sexp}
CONSOLE.TITLE  ..
HTML.TITLE           ..

Color Strings may be either

A hexadecimal pre-fixed with a hash '#
6 digit hex
e.g "#112233"
8 digit hex
e.g "#FF112233"

A color name
e.g "Orange" (case insensitive with no spaces)

A color name postfixed with a decimal alpha channel using a dot '.'
eg. "Orange.255"

A color name postfixed with a hexadecimal alpha channel using a hash '#'
eg. "Orange#FF"

e.g
GR.OPEN "blue.200", 0    % do not show status bar, default to landscape


Color names are listed here or here.

Decors Flag for GR.OPEN and HTML.OPEN

GR.OPEN      {<color>} {,<decors_flags_nexp>} {,<orientation_nexp>}

HTML.OPEN                   {<decors_flags_nexp> {, <orientation_nexp>}}


The statusbar_flag_lexp has been replaced with decors_flags_nexp.

The first 3 bits control the visibilty of the system bars.

Bit
Set to mean
Default

Bit 0
statusbar_SHOW      1 = show

Bit 1
actionbar_SHOW 0 = hide

Bit 2
navbar_HIDE 0 = show

Bit 3
dark_Text 0 = light text
( only works for Android 11+ )

If you don't specify this flag (",,") the default is decors_flags=1 or bin ("001").
This shows the statusbar and navbar but hides the action bar.

This is different from legacy Basic which hides the statusbar by default.
The reason being that a hidden statusbar will affect the navbar color for Android 11+ using new APIs (see later).


Some examples;

actionbar hidden only, e.g Decors = bin ("001")     % i.e 1 *
statusbar hidden only, e.g Decors = bin ("010")     % i.e 2
navbar    hidden only, e.g Decors = bin ("111")     % i.e 7
statusbar shown  only, e.g Decors = bin ("101")     % i.e 5
navbar    shown  only, e.g Decors = bin ("000")     % i.e 0 *
show all bars          e.g Decors = bin ("011")     % i.e 3
hide all bars          e.g Decors = bin ("100")     % i.e 4


* The scheme is compatible with legacy programs which either sets the legacy flag to 0 or 1.

Example
Decors = bin("011")         % show all
GR.OPEN "blue", Decors, 1   % last param is portrait


Alternatively
nav=0 : act=1 : sta=1       % show all
GR.OPEN "blue", nav*4 + act*2 + sta*1, 1

or
nav=1 : act=1 : sta=1       % nav to be inverted to show
GR.OPEN "blue", (!nav)*4 + act*2 + sta*1, 1



Hidden Bars

If either the statusbar or navbar is hidden, then you need a swipe from the top or bottom edge to show it. It disappears after 3 secs.

During this time, touches on the canvas will be blocked but the first touch-down event will get through.
Therefore it is advisable for programs to also wait for a touch-up if waiting for a tap.
Touches are not blocked during a swipe. Be sure to compensate for these touches.

Android 11+ Considerations

For Android 11+, If either the statusbar or navbar is hidden, their colors get tied to a hidden color which may clash with other colors.

Therefore if you need to hide either the statusbar or navbar, then it suggested to hide both.

The text color for a hidden status or navbar is light by default. If your device has a hidden bar with a light background, you may not be able to see the text. You can set the text to be dark by setting the 4th bit (Bit 3) of the decors flag.


Window Titles and Colors

GR.TITLE                {title_sexp} {,textcolor_sexp}, {,backcolor_sexp}

CONSOLE.TITLE {{title_sexp} {,textcolor_sexp}, {,backcolor_sexp}

HTML.TITLE           {title_sexp} {,textcolor_sexp}, {,backcolor_sexp}

Sets the actionbar title, text color and background color for the window.

Specify at least one argument. The commas are needed to seperate the args.

These commands can be used even if screens are not opened yet.

The color strings format is the same as for console.set.


Window Subitles and Colors

GR.SUBTITLE                {title_sexp} {,textcolor_sexp}

CONSOLE.SUBTITLE  {title_sexp} {,textcolor_sexp}

HTML.SUBTITLE           {title_sexp} {,textcolor_sexp}

Sets the actionbar subtitle (under the title) and/or text color for the window.

Specify at least one argument. The commas are needed to seperate the args.

These commands can be used even if screens are not opened yet.

The color strings format is the same as for console.set.


REDIM

Re-Dimensions an existing array with optional 'preserve contents' flag.

REDIM
{preserve_nexp, } Array[<nexp>{, <nexp> } ... ] ...

e.g

REDIM a[2,3]
REDIM b[4] , c$[5]
REDIM 1,d[6]            % ( with preserve )

Any references to a REDIMed array will be intact, e.g an array passed into a function
that executes a REDIM will not be un-dimmed, i.e it will still be the same array but re-dimensioned.
Arrays must exist before REDIMing.

The preserve flag is optional.

If the preserve flag is zero,
the array will be full of 0's or "".

If the preserve flag is non-zero,
the old contents will be preserved to the size of the old or new array, whichever was smallest. Any cells left-over will be 0's or "".

If there are no preserve flags, the default is to not preserve (0).

Preserve flags may be inserted anywhere in the arguments list.
Arrays following a preserve flag will honor that preserve flag until the next preserve flag.
e.g
REDIM 1,a[2,3],   0,b[4],   1,c[5],  d$[6]    %  b[]  will not be preserved.

Preserve flags may be numeric literals or numeric variables but they cannot be numeric array values e.g p[3] would be mis-interpreted as an array to be re-dimmed.


SQL.PING

SQL.PING <result_nvar>, <DB_pointer_nvar> {,<table_name_sexp> {,<column_name_sexp>}}

Ping a database, table or column for some info.

This is mainly used to test for existence of tables.

e.g
A) SQL.PING result, db         
% ping only the database
(B) SQL.PING result, db, "mytable"

% ping a table
(C) SQL.PING result, db, "mytable", "col1"
% ping a table and column

Returns the size (number of rows) of a database or table to result.
In case (A), this is the total number of user tables in the db.

The result code is as follows;

-1 = table name does not exist
-2 = table name exists but column does not exist in the table
  >=0 = The total number of tables in the database or rows in the table.
            In case (C), this also means both table and column exists.

PROGRAM.INFO

In addition to the standard info from Program.Info, these items were added :
Key
Description
example
PkgName The app's android Package Name e.g "com.rfo.hbasic"
SysPathC The full canonical path of app's private directory in internal storage.

This area was mainly for internal use only, although the app has (almost) full access here.

This is Primary Internal Private Storage.

e.g "/data/data/com.rfo.hasic"
BasePath The app's base path in External Storage.
This is where most commands can operate with full access and is where hBasic is scoped.

This is Primary External Private Storage

In the standard app, this can be changed via the Editor menu: Preferences > Base Drive.

(Also known as the Base Drive)


e.g "/storage/emulated/0/Android/data/
com.rfo.hbasic"
App_Path The main app directory after BasePath. It is the directory above source, data and databases.

Historically it is mis-named as a 'path', when in fact it is just the app's main directory name.
e.g "rfo-basic"
LibPath The full canonical path to where android puts native libraries.

Since api 29, this is the only area where you are allowed to execute libraries or native executables.
e.g /data/app/<something>/lib/arm



Some of these added info keys will return absolute paths.
Basic FILE commands were orginally designed for relative paths (from data/),
since v4.38, FILE commands will also accept absolute file paths beginning with a '/'.
But be aware that threre are many areas where your app will not have permission to access.

The above additions are mostly for advanced operations such as using the SYSTEM shell, special areas and/or native libraries access.

This code prints the app's package name.
e.g
PROGRAM.INFO b
BUNDLE.GET b , "PkgName", name$
PRINT name$

com.rfo.hbasic
 Note that FILE.root is the combination of BasePath, App_Path and "/data".
DEBUG.DUMP.FN

DEBUG.DUMP.FN {level_nexp}
Prints the function name from the function stack.
where
level is the optional maximum level (default is 1)
1 - print only the last level (current function)
2 - print two levels (last + previous caller)
..etc...
0 - print all levels
INPUT
INPUT {prompt_sexp}, result_nvar {,{default_exp}{,canceled_nvar}}{,extraFlags_nexp}
An optional extraFlags at the end of INPUT was added.
If this flag is 1, input is constrained to a single line.

Default is 0 = off.
TEXT.INPUT

A cancelled_nvar flag was added to inform whether the user cancelled the input via the backkey.

TEXT.INPUT  result$_svar{,text_sexp} {,title_sexp} {,cancelled_nvar}

If the user cancelled the input, the contents of <result$_svar> remain unchanged.

Example
TEXT.INPUT  store$, default$, Title$, cancelled
IF cancelled THEN PRINT "Do you wish to try again ?"


(Since v4.90+ The orientation of TEXT.INPUT will lock to the same orientation of the top most screen at the time the command is called.)
CLIPBOARD
Due to privacy issues, the clipboard has not been working since Android 10 so the code was upgraded (v4.60+).

Note that your app needs to be in focus in order to access the clipboard.

Even so, the clipboard is still unreliable for some devices / brands of phone.
It is recommended to insert a pause before getting from the clipboard;
e.g
PAUSE 100
CLIPBOARD.GET s$                    % get data from clipboard

print "input>";s$
r$=replace$(s$,"Hello","Goodbye")   % change it
print "output>";r$

if r$<>"" then CLIPBOARD.PUT r$     % put it back
NOTIFY sub-commands
NOTIFY.STATUS  <last_status_nvar>
NOTIFY.CANCEL
If the NOTIFY command is used with a 'wait' flag   e.g NOTIFY t$, s$, a$,1
the program waits until the notification is tapped, dismissed or system continued  (e.g backKey).

NOTIFY.STATUS will return the status of the last notification.
where last_status_nvar will be filled with;
0 = no wait (last NOTIFY was not waiting)
1 = system continued (e.g backkey)   notification not removed.
2 = tapped (user tapped notification)
3 = dismissed (user slides notification)
4 = cancelled (by NOTIFY.CANCEL)
NOTIFY.CANCEL will remove the notification.

e.g
NOTIFY "Title", "subTitle", "alert msg",1

NOTIFY.STATUS last_status
IF last_status = 2 THEN informed = 1    % tapped
IF last_status = 1 THEN NOTIFY.CANCEL   % continued

Note that notifications are always removed on program exit.
This command requires the permission POST_NOTIFICATIONS or else it will not display.
NOTIFY sub commands are used in the sample program h08_notify.bas.
OnORIENT .. ORIENT.RESUME

Interrupt to catch orientation changes.
Triggered if the device changes orientation.
The device must be in auto-rotate mode (by sensors) which can be set with CONSOLE.ORIENT -1.
You can get a simple report of the orientation with DEVICE$("Orient_Simple").
e.g
CONSOLE.ORIENT -1
do : pause 100 : until 0
END

OnORIENT
print DEVICE$("orient_simple")
ORIENT.Resume

-End


Leading Cloud Surveillance, Recording and Storage service; IP camera live viewing

Leading Enterprise Cloud IT Service; cloud file server, FTP Hosting, Online Storage, Backup and Sharing

Powered by FirstCloudIT.com, a division of DriveHQ, the leading Cloud IT and Cloud Surveillance Service provider since 2003.