USER'S MANUAL FOR QB2C (QuasiBASIC)

qb2c: Quasi - Microsoft's (R) QuickBASIC (C) to ANSI C translator
QB2C home page: http://random.com.hr/products/qb2c/qb2c.html
Author:
  E-mail: sales@random.com.hr
Version: 4.98 24. Dec 2003.

Contents

QB2C is a package which makes possible execution of BASIC programs under most of the UNIX systems provided that a C compiler is available on the system. It essentially consists of the BASIC-to-C translator (qb2c) which translates BASIC code into C code, graphics included. The BASIC syntax largely follows Microsoft's (R) QuickBASIC (C) syntax. Normal BASIC graphics is now output to X11 console, therefore X11 is also required. Additional possibility to mix BASIC and C code within the single program file makes QB2C more than just a translator: it can serve as a tool for easy C programming, especially of small programs and compiled substitutes for shell scripts.

There is a great deal of X11-windows-based graphics built into the QB2C including dot, line and marker drawing, filling polygonal areas, mouse pointer and image manipulation, loading/saving GIF format on/from screen, simple animation, picture buffering etc. An extensive coverage of this topics is given in this manual.

Versions from 3.0 on can deal with more than one (up to 16) X-windows at a time.

Intrinsically qb2c understands only programs written in strict QuickBASIC syntax (BASIC keywords in capital, proper spacing...), but 'bcpp' syntax preprocessor can translate a variety of BASIC styles into QB format thus making the whole thing much more flexible. Currently, there is no support (preprocessing) for Visual Basic command style (such as 'While'...).

Scripts 'brun' (to run directly BASIC programs) and 'bcc' (to compile BASIC program and produce an executable) are also provided in order to make life easier. Script 'run' may be used to run directly C programs. In either case user must supply *only* the bare name (i.e. without the extension .c) of a file to be run or compiled. User may change these to suit his/her needs or system specifics.

BASIC is an easy-to-learn and user friendly programming language which is in principle known to everybody. One of ideas behind this project was to be able to use scripts made in BASIC as all-around tool for building user-made commands and interfaces to existing UNIX commands. It is true though that BASIC has a rather limited access to UNIX system, but QB2C allows to circumvent this problem by mixing BASIC and C text in a single program/file. (See the example at the end of the manual.)
With time and with addition of some X11-based graphic capabilities, QB2C proved to be an excellent tool for writing small, handy programs that execute on virtually any UNIX system, and as a help in writing C programs. Its graphics capabilities also grew to a level where they can be used to produce nontrivial programs with less effort when compared to some other programming tools.

QB2C itself can run on any system which has ANSI C installed. To make the executable qb2c available, just compile qb2c.c .

QB2C packet consists of:

qb2c qb2c translator;
bcpp BASIC -> C syntax preprocessor. One needs that when the
  input BASIC text is not exactly in QuickBASIC format;
calib Tool used to 'calibrate' key(board) codes of your UNIX
  system to match QB standard (see the DIFFERENCES section);
libqbX11.a QuickBasic's X11-based graphics library
bcc The BASIC compiler
brun The script to run BASIC programs in UNIX
run The script to run C programs
bcc4 The BASIC compiler (set suid version for OUT, INP functions)
brun4 The script to run BASIC programs in UNIX (set suid version)
run4 The script to run C programs (set suid version)
bhelp The script to display this short manual

and the following example files:

graphic.bas demonstrates the normal 1-window BASIC graphics
xtest.bas demonstrates multi-window graphics and mouse operation
request.bas demonstrates use of XREQST function to input text from graphics
getput.bas demonstrates PUT and GET picture manipulation commands
animate.bas demonstrates animation using XANIM
rotate.bas demonstrates the use of XROT, XTRAN, XSCAL and MRESET graph. cmds.
button.bas demonstrates creation and use of a simple mouse sensitive 3D button
xbutton.bas demonstrates more advanced button handling example

Any of these examples can be compiled and run with the 'brun' command e.g.: $ brun graphic

INSTALLATION

See the README file on how to install the QB2C.

QB2C MAIN ADVANTAGES

* There is no memory limitations of DOS, you can use all memory ou got on the system;

* Lines of code may be as long as 32868 characters;

* You may at any time DIMension, ERASE or REDIMension arrays.
When arrays are redimensioned, the old contents is kept to the extent possible and new space is initialized (to zero);

* Graphics allows the use of more than one graphics window (up to 16) and 265 colors in each the only limitation being the video card and its memory;

* On the same machine QB2C executables run considerably faster than those made by conventional BASIC's under MS DOS or MS Windows.

QB2C MAIN FEATURES

* Recognizes MAIN, SUBroutines and FUNCTIONs

* Declares variables (int, real, char) inside MAIN and inside every SUB. All arguments are passed to user-defined SUBroutines as pointers, so that SUBroutines can affect their values, as in QuickBASIC.
Arguments of a SUB are therefore not declared in the SUB.

* Takes care of SHARED variables.
If a variable is SHARED it is not declared inside the respective SUB, but as a global variable seen by every other FUNCTION, SUBroutine and main. A complete list of shared variables appears in preamble of the translated C program.

* Treats UNIX formatted ASCII (text) files as QuickBASIC would treat DOS formatted ASCII files. The difference between the two is that DOS line terminator is <newline><CR> while UNIX uses only <newline> character terminate a line of text.

* Translates logical expressions from BASIC form to C form

* Brakes up multiple lines (:) into single lines in C

* Keeps all original REMarks and places them intelligently. Does add a few remarks of its own (about shared variables in SUBs, and in preamble).

* Writes out C text neatly

* Recognizes and translates over 180 BASIC and extended BASIC keywords:

... the following BASIC commands and keywords:
o SUB ... END SUB
o EXIT SUB
o FUNCTION ... END FUNCTION
o STATIC (as a qualifier of SUB or FUNCTION)
o SHARED
o DEF FN
o CONST
o DECLARE
o DIM [DYNAMIC], REDIM, ERASE
o IF ... THEN ... [ELSEIF ... THEN] ... ELSE ... END IF
o SELECT CASE, CASE ELSE, END SELECT
o FOR ... TO ... STEP ... NEXT
o DO WHILE ... LOOP
o WHILE ... WEND
o GOTO
o GOSUB
o RETURN
o Labels
o DATA, READ, RESTORE
o CALL
o OPEN .. FOR mode AS #n
where 'mode' is INPUT, OUTPUT, APPEND
o CLOSE #n
o EOF
o LOF
o EXISTS
o PRINT #n
o PRINT
o PRINT USING
o LOCATE
o COLOR
o CLS
o LINE INPUT #n
o INPUT #n
o INPUT
o COMMAND$
o ENVIRON$
o ENVIRON
o INKEY$()
o STRING$()
o DATE$
o TIME$
o TIMER
o PAUSE, SLEEP
o RANDOMIZE
o SHELL
o REM
o LET
o GET (graphics)
o PUT (graphics)
o GET #n (file I/O)
o PUT #n (file I/O)
o DEFSTR, DEFINT, DEFDBL
o SOUND, BEEP
o END

... basic string processing functions:
o MID$, LEFT$, RIGHT$, LCASE$, UCASE$, STR$, ASTR$, CHR$, SPACE$, STRING$, LTRIM$, RTRIM$, TRIM$, SSCAN, TOKENS, HEX$, OCT$, ASC, VAL, LEN, INSTR

... mathematical functions:
o LOG, SIN, COS, TAN, ATN, SQR, ABS, EXP, SGN, RND, INT, CINT, MIN, MAX, MOD and power ^

... logical operators:
o =, <>, NOT, AND, OR, XOR

... quite a number of graphics statements:
o SCREEN, PALETTE, SET, PSET, PGET, LINE, CIRCLE, PLINE, FAREA, MARKER, PMARKER, XWINDOW, XTEXT, XLEN, XUPDATE, XCLS, XSELWI, SAVEGIF, LOADGIF, GIFINFO, GCGET, XPOINTER, XCURSOR, XTITLE, XREQST, XCLIP, XNOCLI, XWARP, GET, PUT, XANIM, GETCOL, XGETGE, XROT, XSCAL, XTRAN, MRESET, XBUF, XRMBUF, XRESIZE, XMOVE, SAVEPS, SAVEEPS, READGIF
(see the graphics section of this manual)

... and set of comands and functions for easy handling of buttons: o XDefineButton, XButtonFocus, XDrawButton, XDrawInputButton, XInputButton, XCheckButtons, XClickButton, XToggleButton, XGetButtonState%, XDestroyButton (see the graphics section of this manual).

* If a line cannot be translated an ERROR message is issued, the line and its number dumped at the screen and the translating process stopped. If a line can be translated but something seems odd to the translator it issues a WARNING + an explanation and translation continues.

* There are not many syntax or other errors which can be detected during translation. Translation assumes that the input QuickBASIC program is itself (almost) syntax error free. Preprocessor bcpp does some additional simple checks like brackets and double quotes balance etc.

REFERENCE MANUAL

DIFFERENCES BETWEEN QB2C AND ANSI BASIC


  • / the division operator
    In BASIC, for example 5 / 8 equals to 0.625 while in C this is equal to 0 (integer zero) because the binary operator "/" acts as the integer division operator when both operands are integer numbers. QB2C translator will by default also produce zero for such expressions unless they are written in one of the following ways:
    5. / 8., 5. / 8, 5 / 8., 5! / 8, 5 / 8!, 5! / 8!, (0.+ 5) / 8 etc. If you want QB2C to behave exactly like BASIC i.e. to convert both sides to float before dividing them you should specify options "-b -r" in which case the preprocessor bcpp is turned on in such a way that it replaces every division operator " / " with " / (double)". This is NOT a default.


  • DATE$ has more possible formats than in ANSI BASIC:
    DATE$ or DATE$(0) -> 12-27-1996 (the default QuickBASIC format)
    DATE$(1) -> 27.12.1996
    DATE$(2) -> 27/12/1996
    DATE$(3) -> 27-Dec-1996
    DATE$(4) -> Sun Dec 27 15:14:37 1996


  • INKEY$
    Usage: a$ = INKEY$
    This implementation of INKEY$ by default waits until a key is pressed and then returns a string associated to a character pressed. Unlike the INKEY$ in QuickBASIC it cannot return empty string (""). This should not cause any noticeable differences in operation of programs since INKEY$ is usually embedded in an outer loop which is exited when a key is pressed.

    It is possible to force INKEY$ to behave exactly like in ANSI BASIC by specifying the option -I at the compile time. In that case there is no loop and INKEY$ simply reads the first character from the keyboard buffer and exits immediately.

    According to QB, when a key is pressed, INKEY$ returns a string which corresponds to the key. Most keys return a string of length one (single character). Extended keys are represented with a string of length 2. Key codes of ordinary keys are emulated by QB2C exactly as they are in QuickBASIC whereas codes of extended keys are (hopefully insignificantly) different. The only difference is that the first code is 1 instead of 0.

    Here is the list of extended keys and their ASCII codes:

      Key   QB2C   QBASIC     Key     QB2C   QBASIC     Key          QB2C  QBASIC  
      F1    1 59   0 59       F9      1 67   0 67       End          1 79  0 79
      F2    1 60   0 60       F10     1 68   0 68       Page Down    1 81  0 81
      F3    1 61   0 61       F11     1 133  0 133      Cursor Up    1 72  0 72
      F4    1 62   0 62       F12     1 134  0 134      Cursor Left  1 75  0 75
      F5    1 63   0 63       Insert  1 82   0 82       Cursor Down  1 80  0 80
      F6    1 64   0 64       Home    1 71   0 71       Cursor Right 1 77  0 77
      F7    1 65   0 65       Page Up 1 73   0 73
      F8    1 66   0 66       Delete  1 83   0 83
    

    This is not all ! As different implementations of screen codes in UNIX are not unique, it is necessary to 'calibrate' your keyboard in some way. If you are going to use INKEY$ function you should definitely do this by running program calib. The program will ask you to press extended keys listed above and will create the file .kbcalib in your $HOME directory.


  • CONSTANTS

    Constant numbers may be represented with or without leading and/or trailing zeros, and in exponential notation. For example the following are equivalent:
    0.001
    .001
    000.001
    0.001000
    Exponential notation allows more convenient and compact writing of very large or very small numbers:
    1000000000 is equivalent to: 1E9, 1e9, 1E+9 or 1e+9 .
    .000000001 is equivalent to: 1E-9 or 1e-9 .

    Numbers, whether in ordinary or in exponential notation *must be written without any spaces*. For example, the following is invalid:
    a = 1 000 000
    b = 1E 9
    etc.

    When associated to a variable, constant numbers is always automatically converted to the variable type. For example:
    a = 1
    or
    a = 1
    is equivalent to:
    a = ((float) 1)
    in C.

    Like in C (but unlike BASIC) one can write constant numbers both in decimal and hexadecimal notation. Hexadecimal numbers are in the form of "0x" followed immediately with a hex number of appropriate length. For example:

      hex           decimal
      0xf           15
      0xa0          160
      0x378         888
      0x3e8         1000
    

    See also: CONST, HEX$


  • CONST constname=expression[, constname=expression]

    At compilation time every "constname" is replaced by appropriate "expression". An expression consists of literals (such as 1.0), other constants, or any of the arithmetic and logical operators except exponentiation (^). You may also use a single literal string such as "Error on input". You cannot use string concatenation, variables, user-defined functions, or intrinsic functions like SIN or CHR$ in expressions assigned to constants.

    Example:

      CONST ONE = 1, TWO = ONE + ONE
    

    The following example produces an error because the constant ONE is not defined before it is used to define TWO (constants are defined from left to right and from up to down):

      CONST TWO = ONE + ONE, ONE = 1
    

    In a program, nothing can be assigned to a constant and no variable can have the same name. Length of the name of a constant is limited to 80 characters.

    A special case of CONST usage is to redefine the default string length.

    Example:

      CONST LMAX=32000
    

    defines the default length of string variables to 32000 characters. Minimum value of LMAX is 1, maximum is 1048576 (1024x1024 bytes). If you attempt to set LMAX less than the minumum or more than the maximum it will be redefined to fit this range.

    See also: -L option


  • VARIABLES

    Names of variables can be composed of the alphanumeric characters and the underscore character, more precisely of: 'a' to 'z', 'A' to 'Z', '0' to '9' and '_'. Variable name may not coincide with any name of the BASIC library or user-defined function or subroutine.

    Variable name may not coincide an array name. For example, if you defined the array 'DIM a(100)' you may not use variable name 'a', but you still may use variable or array name a#, a%, a&, a? and a$.

    Variables' precision and length in memory.

    Type of a variable is defined by its name, more precisely by a suffix of a variable name. A space in memory occupied by
    a numeric variable of some type is somewhat dependent of a machine and C compiler in question. For Linux and gcc compiler for Intel X86 processors (and rather generally) the situation is summarized in the following table:

    Type range length suffix example
    integer -2 147 483 648 4 bytes % a%
      +2,147,483,647    
    long integer -2 147 483 648 4 bytes+ & a#
      +2,147,483,647    
    long long int -18446744073709551616 8 bytes && a&&
      +18446744073709551615    
    short integer -32768 to 32767 2 bytes _% a_%
    byte 0 to 255 1 byte ? a?
    float (see below) 4 bytes none a
    double (see below) 8 bytes # a#
    char (string)   1024 bytes* $ a$

    The same suffix convention applies also to array names and return values of functions (see DIM and FUNCTION).

    + On some machines long integer may be 8 bytes long.
    * This default can be changed via -L option or CONST statement.

    PREPROCESSING


  • #if defined

  • #else

  • #endif

    The bcpp preprocessor allows for conditional compilation by the use of "REM #if defined label", "REM #else" and "REM #endif" preprocessor directives similar to the C language syntax.
    An example program (sample.bas):

    REM #if defined Linux
        SCREEN (100,100), 300, 200
    REM #endif
    REM #if defined DOS
        SCREEN 12
    REM #endif
        LINE (10,10)-(100,100), 1
    END
    

    It is necessary that preprocessor directives start at the beginning of the line and follow exact spacings as in this example. At preprocessor level, lines enclosed in the label which is not defined are skipped and do not appear in the .bcp file.

    To obtain a Linux source, type:

      bcpp -define Linux sample
    

    and to obtain a DOS source type:

      bcpp -define DOS sample
    

    In both cases a file named 'sample.bcp' is the desired BASIC source. You can compile the sample program for Linux this way:

      bcc sample -define Linux
    

    If either Linux or DOS labels must be used, the above example could as well be written as:

    REM #if defined DOS
        SCREEN 12
    REM #else
        SCREEN (100,100), 300, 200
    REM #endif
        LINE (10,10)-(100,100), 1
    END
    

    In this example, by specifying no label (bcc sample) one obtains the Linux source whereas specifying the "DOS" label (bcc sample -define DOS) one obtains the DOS source.


  • #include

    Preprocessor statement that literally includes a specified QB2C file into the place where it appears.

    Syntax:

      REM #include filename
    

    where filename is a name of a single file containing QB2C code which is to be included at this place.
    It is necessary that preprocessor directive starts at the beginning of the line and follow exact spacings as in this example.

    IMPORTANT NOTICE:
    There may be any number of #include statements in the code. However, only the first layer of directives will be unfolded. That is if there are any #include directives in the included file they will be ignored unless they are C code.

    See also: #cinclude


  • #cinclude

    Preprocessor statement that literally includes a specified C source into the place where it appears.

    Syntax:

      REM #cinclude filename
    

    where filename is a name of a single file containing C code which is to be included at this place. This functions as follows: each line of text in the 'filename' is prepended with "C " and written at this place in the order of appearance.

    See also: #include


  • LOGICAL OPERATORS and
    BITWISE OPERATORS

    Supported logical operators are: NOT, AND, OR, XOR. By default, they operate as logical operators and not as bitwise operators.

    Bitwise operators are: ~ (bitwise complement), & (bitwise and), | (bitwise or), @ (bitwise xor) >> (right byte translation, division by 2^n) and << (left byte translation, multiplication by 2^n).

    For more details, refer to a manual section for every operator.

    LIMITS to QB2C NUMBERS, STRINGS AND NAMES

      What                                 Maximum               Minimum
      variable or function name length     40 characters         1 character
      string length                        1024  characters      0 characters
      integers                             32767                -32768
      long integers                        2 147 483 647        -2 147 483 648
      float numbers (positive)             3.402823 E+38         1.401298 E-45
      float numbers (negative)            -1.401298 E-45        -3.402823 E+38
      long float    (positive)
                              Maximum:     1.797693134862315 D+308
                              Minimum:     4.940656458412465 D-324
      long float    (negative)
                              Maximum:    -4.940656458412465 D-324
                              Minimum:    -1.797693134862315 D+308
    

    Limit to a line length in QB2C is 1023 characters (i.e 1024 including newline character). This can be changed by specifying CONST LMAX to a different value, or by use of the -L option to qb2c at compile time. Possible value is between 1 and 1048576.

    SPECIAL NAMES

    Special names that may be defined in some C languages are a tricky question. It is important to avoid using any names which may be defined in include files or you will get compile errors or unexpected program behavior. Following "usual" names are defined in the math.h header file and you should definitely avoid their use as variable or function names:

    name meaning
    PI Ludolf's number 3.14...
    y0 Bessel function Y(0,x)
    y1 Bessel function Y(1,x)
    yn Bessel function Y(n,x)
    j0 Bessel function J(0,x)
    j1 Bessel function J(1,x)
    jn Bessel function J(n,x)
    asin Inverse sine function
    acos Inverse cosine function

    File math.h is automatically included by QB2C if there is a need. Be careful.

    CONTROLLING IMPLICITE VARIABLE TYPES

    A few statements to controll implicite variable types according to a first letter in their names, are supported in the QB2C. These are:


  • DEFSTR

  • DEFINT

  • DEFDBL

    Syntax:

      DEFINT letterrange [,letterrange]...
      DEFDBL letterrange [,letterrange]...
      DEFSTR letterrange [,letterrange]...
    

    parameter meaning
    letterrange letterrange has the form: letter1[-letter2]
      where letter1 and letter2 are any of the uppercase or
      lowercase letters of the alphabet. The case of the letters
      in letterrange is not significant. If more than one
      letters appear in the letter1 or letter2 only the leftmost
      character counts.

    Names beginning with the letters in
    letterrange have the type specified by the last three letters of the statement: integer (INT), double precision (DBL), or string (STR).

    Example:

      ...
      DEFSTR A-e
      ...
    

    All variables starting with letters A-E will be treated as strings, in addition to the normal implicite rules (for example z$ will also be a string).

    In collision with default implicite names, the default ones are stronger, for example A% will nevertgeless be an integer, not a string.

    Examlpe:

    All of the following statements are equivalent:

     DEFINT A-e
     DEFINT a-E
     DEFINT auxc-ebic
    


  • DEF FNname(parameterlist) = expression

    This is equivalent of: FUNCTION name(parameterlist)
    name = expression
    END FUNCTION

    See also: FUNCTION


  • FUNCTION...END FUNCTION - a non-executable statement that declares the
    body of a FUNCTION procedure

    Syntax:

      FUNCTION name(parameterlist)
          [statements]
        name = expression
          [statements]
      END FUNCTION
    

    Part Description
    name The name of the function. FUNCTION names follow the
      same rules as QB2C BASIC variable names and can include
      a type-declaration character (%, &, #, _%, ? or $).
      The type of the name determines the type of
      value the function returns. For example, to create a
      function that returns a string, you would include a
      dollar sign in the name or give it a name defined as
      a string name by a DEFSTR statement.
    parameterlist The list of variables, separated by commas, passed
      to the FUNCTION. The parameters other than arrays
      are passed by value, so any change to a parameter's
      value inside the function has no effect to its value
      in the calling program. Arrays, however are passed
      as pointers, therefore any change to an array
      value in the subprogram also changes its value in
      the calling program. See below for a complete
      description of the syntax. It is only possible to
      pass 1-dimensional string arrays whose element length
      is equal to the default (LMAX).
    expression The return value of the function. Depending on the
      type of function expression may be numeric or string.
      If no value is assigned to the FUNCTION name, the
      FUNCTION returns a default value: a numeric
      function returns a value of zero, and a string
      function returns the null string ("").

    It is not a good idea that a QB2C FUNCTION calls itself, because because all implicitly declared variables are static.

    If you define any SUBroutine or FUNCTION, then the main program must end up with the statement END.

    EXAMPLE:

      DIM f(100)
      .....
      z = 0
      x = Integral(dx, f(), n%)
      .....
      END
    
      FUNCTION Integral(dx, f(), max%)
       s = 0
       FOR i% = 0 TO max%
        s = s + f(i%)
       NEXT
       func = dx * (s - (f(0) + f(max%)) / 2)
      END FUNCTION
    

    See also: DEF, SUB


  • SUB...END SUB - a procedure statement that declares the
    body of a SUB procedure (subprogram)

    Syntax:

      SUB name[(parameterlist)] [STATIC]
        [statements]
      [EXIT SUB]
        [statements]
      END SUB
    

    Part Description
    name A subroutine name up to 40 characters long. This name
      cannot appear in any other FUNCTION or SUB
      statement in the same program or the user library.
    parameterlist Contains the names of simple variables and arrays
      passed to the subprogram when the SUB is invoked.
      Each name is separated from the preceding name by
      a comma. Note that these variables and arrays are
      passed by reference, so any change to an argument's
      value in the subprogram also changes its value in
      the calling program. See below for a complete
      description of the syntax. It is only possible to
      pass 1-dimensional string arrays whose element length
      is equal to the default (LMAX).

    A subprogram is a separate procedure, like a FUNCTION. However, unlike a FUNCTION, a SUB cannot be used in an expression. SUB is uniquely executed by a CALL statement.

    Subroutine name has no type because a subroutine returns nothing itself.

    SUB and END SUB mark the beginning and end of a subprogram. You may also use the optional EXIT SUB statement to exit a subprogram.

    If you define any SUBroutine or FUNCTION, then the main program must end up with the statement END.

    EXAMPLE:

      DIM b(100)
      ...
      a = ...
      c% = ...
      CALL Sub(a, b(), c%)
      ...
      END
    
      SUB Sub(z, bc(), c%) 
       z = bc(0) + bc(10) - c%
      END SUB
    

    In this example, a subroutine Sub is called with three input/output parameters. Note that the local parameters names may differ from the names used in the calling statement. What is actually passed to the subroutine are the addresses in memory of the variables "a", "c%" and of the first array element "b(0)". The subroutine Sub identifies the array "bc" with "b". It is important to understand that the array "bc" actually does not exist as a separate location in memory. It is the same array "b" just it is referred to by another name. That is "bc(0)" is actually "b(0)", "bc(1)" is actually "b(1)" etc. The same goes for the simple variables "s" and "c%".

    Therefore, if a value of a parameter is changed within a subroutine, the change affects the parameter's value in the calling program.

    When passing an array to a subroutine, it is possible to make a shift in index. For example in the syntax:

      ....
      CALL Sub(a, b(10), c%)
      ....
    
      SUB Sub(z, bc(), c%) 
       z = bc(0) + bc(10) - c%
      END SUB
    

    the subroutine Sub sets the address of the local array element bc(0) to the address of b(10) which means that "b(0)" becomes "b(10)", "bc(1)" becomes "b(11)", etc.
    This syntax should be used with care: one should keep in mind that the subroutine expects an array rather than just an array element, as is suggested by the calling statement.

    See also: CALL, FUNCTION


  • COMMAND$

    If the COMMAND$ has been used anywhere in the main program, then an array of strings argv$() and integer number n_arg% are defined automatically by the QB2C compiler. The argv$() contains the list of arguments to the program which is being executed, while n_arg% says how many arguments there are. For example, your executable has the name "myprog" and is called with a three arguments:

      myprog -a 3 abc
    

    In this case n_arg% = 3, and argv$(1) equals "-a", argv$(2) equals "3" and argv$(3) equals "abc".

    If there is no arguments n_arg% is equal to zero. The argv$(0) contains the name with which the program has been run, in our example it would contain string "myprog".

    Example:

      ...
      c$ = COMMAND$
      ...
    


  • ENVIRON$(name$)

    An array of strings called the `environment' is made
    available to your program when it is run.

    ENVIRON$ function returns the environment string associated with the name name$ or an empty string if the name cannot be found.
    The argument name$ must be a string variable or a string constant.

    Common examples of environment names in UNIX are:

    USER The name of the logged-in user (used by some BSD-
      derived programs).
    LOGNAME The name of the logged-in user (used by some Sys-
      tem-V derived programs and Linux).
    HOME A user's login directory
    PATH The sequence of directory prefixes that shell and
      many other programs apply in searching for a file
      known by an incomplete path name. The prefixes are
      separated by `:'
    PWD The current working directory. Set by some shells.
    SHELL The file name of the user's login shell.
    TERM The terminal type for which output is to be pre-
      pared.
    OSTYPE Short name of the operating system, such as "Linux".

    Example:

      pwd$ = ENVIRON$("PWD")
    

    returns the full path of the current directory on most UNIX systems.

    See also: ENVIRON


  • ENVIRON stringexpression

    ENVIRON statement sets the system environment string variable.

    stringexpression must have the form:

      name$ = value$
    

    where name$ is the name of the environment variable and value$ is a string to be associated with the variable. Everything to the left of the equal sign or space is assumed to be a variable name, and everything to the right its new value which replaces the old one.

    For example:

      ENVIRON "DISPLAY" = "darkstar.linux.ch:0.0" 
    

    associates the environment variable DISPLAY to string "darkstar.linux.ch:0.0". The same could be, for example, obtained with:

      disp$ = "DISPLAY": ENVIRON disp$ = "darkstar.linux.ch:0.0"
    

    If the environment variable has not previously existed in the environment string table, it is appended to the end of the table. If the variable exists in the table when the ENVIRON statement is executed, it is deleted and the new variable is appended to the end of the table.

    See also: ENVIRON$

    STRING PROCESSING FUNCTIONS


  • STRING$(n%, asc%)

    Function that returns a string of length n% whose characters all have given asc% ASCII code.

    See also: SPACE$


  • SPACE$(n%)

    SPACE$ is a string processing function that returns a string of spaces of length n%.

    See also: STRING$


  • LEFT$(a$, n%)

    LEFT$ is a string processing function that returns a string consisting of the leftmost n% characters of the string a$.

    The argument n% is a numeric expression in the range 0-1024 indicating how many characters are to be returned. Natural limit to the number n% is 1024 since in QB2C the default storage for strings amounts 1024 characters. However, this can be overridden by the option -L at translation time (see the OPTIONS section of the manual).

    If n% is greater than the number of characters in stringexpression, the entire string is returned. To find the number of characters in a$ use LEN(a$).

    If n% is zero, the null string (length zero) is returned.

    See also: RIGHT$, MID$, CONST


  • RIGHT$(a$, n%)

    RIGHT$ is a string processing function that returns a string consisting of the rightmost n% characters of the string a$.

    The argument n% is a numeric expression in the range 0-1024 indicating how many characters are to be returned. Natural limit to the number n% is 1024 since in QB2C the default storage for strings amounts 1024 characters. However, this can be overridden by the option -L at translation time (see the OPTIONS section of the manual).

    If n% is greater than the number of characters in stringexpression, the entire string is returned. To find the number of characters in a$ use LEN(a$).

    If n% is zero, the null string (length zero) is returned.

    See also: LEFT$, MID$, CONST


  • MID$
    The MID$ keyword can be used either as a function or as a statement.

    Syntax 1 (function):
    MID$(a$, start%[, length%])

    MID$ is a string-processing function that returns a substring of a string.

    This function returns a string containing length% characters starting from start%-th character in the string a$.

    If the third argument (length) is omitted or start%+length% exceeds the length of the string a$, then function returns a string which starts at start%-th and goes to the end of the a$.

    Syntax 2 (statement):
    MID$(a$, start%[, length%]) = stringexpression

    MID$ is a string processing statement that replaces a portion of a string variable with another string.

    Argument Description
    stringvariable The string variable being modified.
    start A numeric expression giving the position in
      stringvariable where the replacement starts.
    length The length of the string being replaced. The
      length is a numeric expression.
    stringexpression The string expression that replaces part of the
      stringvariable.

    The arguments start and length are integer expressions. The argument stringvariable is a string variable, but stringexpression can be a string variable, string constant, or string expression.

    The optional length refers to the number of characters from the argument stringexpression that are used in the replacement. If length is omitted, all of stringexpression is used. However, regardless of whether length is omitted or included, the replacement of characters never goes beyond the original length of stringvariable.

    NOTE:
    Natural limit to start% and length%, both for function and statement, is 1024 since in QB2C the default storage for strings amounts 1024 characters. However, this can be overridden by the option -L at translation time (see the OPTIONS section of the manual).

    Related topics: LEFT$, RIGHT$, INSTR, CONST


  • INSTR([start%], string1$, string2$)
    a string processing function that returns the character
    position of the first occurrence of the string2$ in string1$. INSTR return type is integer. If not given, start% is assumed to be 1.

    The arguments string1 and string2 can be string variables
    or string constants but not string expressions.

    The value returned by INSTR depends on the following conditions:

    Condition Value Returned
    string2$ found in string1$ The position at which the string2$ is found
    start% > length of string1$ 0
    string1$ is null string 0
    string2$ is null string start (if given); otherwise, 1

    Related topics: MID$


  • LCASE$
    a string processing function that returns a string expression with all letters in lower-case.

    Syntax:

      variable$ = LCASE$(stringexpression)
    

    stringexpression may be a string constant, string variable, or string expression. It may refer to a fixed- or variable-length string.

    See also: UCASE$


  • UCASE$
    a string processing function that returns a string expression with all letters in uppercase.

    Syntax:

      variable$ = UCASE$(stringexpression)
    

    stringexpression may be a string constant, string variable, or string expression. It may refer to a fixed-length or variable-length string.

    See also: LCASE$


  • LTRIM$(variable$[, white$])
    a processing function that returns a copy of a string with leading (left-hand) white spaces (' ', '\t') removed. If white$ is specified then each character in it, and no other characters, are considered as a white space and are stripped from the left side of the variable$.

    Syntax:

      a$ = LTRIM$(z$)
      b$ = LTRIM$(z$, " ")
    

    See also: RTRIM$, TRIM$


  • RTRIM$(variable$[, white$])
    a string processing function that returns a copy of the variable$ with trailing (right-hand) white spaces (' ', '\t', '\015') removed. If white$ is specified then each character in it, and no other characters, are considered as a white space and are stripped from the right side of the variable$.

    Syntax:

      a$ = RTRIM$(z$)
      b$ = RTRIM$(z$, " ")
    

    See also: LTRIM$, TRIM$


  • TRIM$(variable$[, white$])
    a string processing function that returns a copy of the variable$ with the leading and trailing white space removed. The default white space characters are (' ', '\t', '\015'). If white$ is specified then each character in it, and no other characters, are considered as a white space and are stripped from the both sides of the variable$.

    Syntax:

      u$ = TRIM$(z$)
      u$ = TRIM$(z$, white$)
    

    See also: LTRIM$, RTRIM$


  • TOKENS w$, n%, tok$(), sep$

    Argument Description
    w$ - a string to be scanned through;
    n% - number of tokens found in w$;
    tok$() - array to which tokens are copied;
    sep$ - a string of character separators according to which a$
      is separated into tokens;

    TOKENS is a string processing function. It scans string w$ for tokens delimited by any of the characters found in the sep$ and save the n% resulting tokens in tok$(i) 1 <= i <= n%. Separators ',' and '\t' (comma and tab) are special: two adjacent will give an empty token. For example: "a,,b" gives 3 tokens: "a", "", "b". Parts of the string w$ placed within double quotes or in brackets () are not tokenized.

    Example:

      DIM tok$(10)
      ....
      w$ = " +abCd  ef, ,&,(b+c)d"
      TOKENS w$, n%, tok$(), " +"
      FOR i% = 1 TO n%
       PRINT i%, ":"; tok$(i%); ":"
      NEXT
    

    The result is:

     1             :abCd:
     2             :ef:
     3             ::
     4             :&:
     5             :(b+c)d:
    
    Note an empty string found between two commas.

    See also: SSCAN


  • ASC(a$)

    ASC is a string processing function that returns a numeric value that is the ASCII code of the first character in a string.

    See also: CHR$


  • CHR$(code)

    CHR$ is a string processing function that returns a one-character string whose ASCII code is the argument.

    CHR$ is commonly used to send a special character to the file or printer. For example, the "form feed" character CHR$(12)
    tells the printer or some editors editor to skip to a new page.

    CHR$ can also be used to include a double quote (") in a string:

      a$ = CHR$(34) + "Quoted string" + CHR$(34)
    

    This line adds a double-quote character to the beginning and the end of the string.

    See also: ASC


  • LEN(a$)

    LEN returns the number of characters in the string a$.


  • STR$(numeric_expression)

    STR$ is a string function that returns a string representation of the value of a numeric expression.
    If numeric_expression is positive, the string returned by the STR$ function contains a leading blank.

    See also: ASTR$, VAL


  • ASTR$(numeric_expression)

    ASTR$ is a string function that returns a string representation of the value of a numeric expression.
    If numeric_expression is positive, the string returned by the ASTR$ function does not contain a leading blank, ie. the first character is either '-' or a digit.

    See also: STR$, VAL


  • VAL(a$)

    VAL is a string-processing function that returns the numeric value of a string of digits. It returns a value of the maximum leftmost characters recognizable as a number. Return value is of the type double. Examples:

      x = VAL("123.456")        x = 123.456
      x = VAL(" 12A13B")        x = 12
      x = VAL("R34.56")         x = 0
      x = VAL(-1.23.45.67")     x = -1.23
    

    See also: STR$, HEXVAL&, OCTVAL&


  • HEXVAL&(a$)

    HEXVAL& is a string-processing function that returns the numeric value of a hexadecimal string of digits. The argument a$ is a string representing a nonnegative integer in the hexadecimal notation. Character-valued digits (A-F) may be in any case (upper, lower or mixed).
    HEXVAL& acts as the inverse of the HEX$ function.
    Return value is of the type long integer.
    Example:

      x = HEXVAL&("a0ef")       x = 41199
    

    See also: HEX$


  • OCTVAL&(a$)

    OCTVAL& is a string-processing function that returns the numeric value of a hexadecimal string of digits. The argument a$ is a string representing a nonnegative integer in the octal notation.
    OCTVAL& acts as the inverse of the OCT$ function.
    Return value is of the type long integer.
    Example:

      x = OCTVAL&("015")       x = 13
    

    See also: OCT$


  • HEX$(expression)

    HEX$ is a string function that returns a string that represents the hexadecimal value of the decimal argument expression.

    The argument expression is a numeric expression or a number. It is converted to a long integer by truncating a non-integer part before the HEX$ function evaluates it. Leading zeros are omitted.

    A string consists of only numbers and upper case letters. You may convert to lower case using LCASE$ function.

    See also: OCT$


  • OCT$(expression)

    OCT$ is a string function that returns a string that represents the octal value of the decimal argument expression.

    The argument expression is a numeric expression or a number. It is converted to a long integer by truncating a non-integer part before the OCT$ function evaluates it. Leading zeros are omitted.

    A string consists of only numbers and upper case letters. You may convert to lower case using LCASE$ function.

    See also: HEX$


  • MATHEMATICAL FUNCTIONS


  • SIN function
    Syntax: SIN(numeric_expression)

    SIN is a math function that returns the sine of an angle given in radians. Argument can be of any type. Value of the SIN is calculated to a double precision. Return type is the "signed double precision", which corresponds to a variable with suffix '#'.

    See also: COS, TAN, ATN


  • COS function
    Syntax: COS(numeric_expression)

    COS is a math function that returns the cosine of an angle given in radians. Argument can be of any type. Value of the COS is calculated to a double precision. Return type is the "signed double precision", which corresponds to a variable with suffix '#'.

    See also: SIN, TAN, ATN


  • TAN function
    Syntax: TAN(numeric_expression)

    TAN is a math function that returns the tangent of an angle given in radians. Argument can be of any type. Value of the TAN is calculated to a double precision. Return type is the "signed double precision", which corresponds to a variable with suffix '#'.

    See also: SIN, COS, ATN


  • ATN function
    Syntax: ATN(numeric_expression)

    ATN is a math function that returns the angle, measured in radians, tangent is the numeric_expression. Said in a words of a mathematician, ATN returns "arcus tangent" of its argument. The argument can be of any type. Value of the ATN is calculated to a double precision. Return type is the "signed double precision", which corresponds to a variable with suffix '#'.

    ATN is the only inverse trigonometric function in BASIC and can be used to perform other inverse functions using the following formulae:

    asin(x) = atn(x/SQR(1-x*x))
    acos(x) = atn(SQR(1-x*x)/x)

    See also: SIN, COS, TAN


  • EXP(numeric_expression)

    EXP is a math function that calculates the exponential function (that is Euler's number e=2.7182818284... raised to the power of a numeric expression). Inverse function of EXP is LOG.

    See also: LOG


  • LOG(numeric_expression)

    LOG is a math function that returns the natural logarithm of a numeric expression, ie. the logarithm with the base e=2.7182818284... Argument can be of any type and the return value is a double float.

    To convert to logarithm with base 10 simply divide with LOG(10). For example, the following function calculates the logarithm with base 10:

      FUNCTION log10(x)
       log10 = LOG(x) / LOG(10)
      END FUNCTION
    

    See also: EXP, FUNCTION


  • ABS(numeric_expression)

    The absolute value function returns the unsigned magnitude of its argument. For example, ABS(-1.23) and ABS(1.23) are both 1.23 Argument can be of any type and the return value is a double float.

    See also: SGN


  • RND[(n)]

    RND is a math function that returns a single-precision random number between [0, 1) ie. 0 included, 1 excluded.
    If the argument is omitted, the RND function returns the next number in the pseudorandom number sequence. The argument 'n' is a numeric expression of any type. The value of n determines how RND generates the next random number:

    Argument Return value
    0 or n omitted returns the next random number in the sequence
    n <> 0 returns the last number generated

    A tip:
    To produce random integers in a range between n1% and n2% both included, use the formula:

      INT((n2% - n1% + 1)*RND + n1%)
    

    For example, to simulate throwing a dice use n1% = 1, n2% = 6:

      INT(6 * RND) + 1
    

    NOTE:
    This implementation of RND uses C library function rand() to generate random numbers using the following formula:

      RND = rand()/((double) RAND_MAX))
    

    See also: RANDOMIZE


  • RANDOMIZE [expression]

    RANDOMIZE is a math statement that initializes (reseeds) the random-number generator. The expression may be any integer
    number between 0 and 65535. If not specified, the default
    value of 32767 is taken.

    If a number smaller than 0 or larger than 65535 is specified, then this number modulo 65536 is taken as a seed.

    If the random-number generator is not reseeded, the RND function returns the same sequence of random numbers each time the program is run. To change the sequence of random numbers every time the program is run, place a RANDOMIZE statement at the beginning of the program and change the argument with each run.

    A convenient way to initialize the random-number generator is to use the TIMER function as follows:
    RANDOMIZE TIMER
    Using TIMER ensures a new series of random numbers each time you run the program.


  • INT(expression)

    INT is a math function that returns the largest integer less than or equal to a numeric-expression. In other words, the INT function removes the fractional part of its argument. INT returns long integer, therefore the expression parameter must be in the range of the long integer i.e. -2 147 483 648 ... +2,147,483,647.

    See also: CINT


  • CINT(expression)

    CINT is a conversion function that converts a numeric expression to a long integer by rounding the expression. It is equivalent to INT(0.5 + expression).

    See also: INT


  • MOD
    Syntax
    numeric-expression1 MOD numeric-expression2

    The modulus or "remainder" operator. Divides one number by another (real values are rounded to integers) and returns the remainder. For example, 18 MOD 6.7 equals four.


  • ARRAYS
    See the DIM statement.


  • SYNTAX ERRORS

    Diagnostics of syntax and other errors at the translation time is not one of the greatest thing about QB2C but should be good enough in most cases. However, some errors are only detected at compilation time of the C translate. In that case, there is usually a very large number of errors complained by your C compiler. Errors detected at that level can be hard to back-trace to the original BASIC code. The tip is that you should always look only at the first error reported by the C compiler and correct for it before looking at any other error reports. Often the first reported error is the only error.


  • DIM [DYNAMIC] array(subscripts)[, array(subscripts) ...

    Reserve space in memory for arrays of variables. Array list is a list of arrays with specified dimensions delimited with comma. An array can be specified as a static or dynamic block of memory.

    Array dimensioned with statement DIM DYNAMIC occupy a dynamic block of memory. Space for such array is allocated at run time and can be freed (see ERASE) or redimensioned (see REDIM) at the run time.

    On the other hand, an array dimensioned with DIM statement occupy a static block of memory. Space for such array is predetermined at compile time and cannot be freed or change its size at the run time.

    The DIM DYNAMIC statement can occur anywhere in the program, and the space required by array(s) is requested from the system at the momen when the program execution encounters the statement.
    This is opposed to the DIM (static) statement which absolutely MUST be stated at the very beginning of the program (possibly after the CONST statement(s)), and which reserves the required array space immediately at the beginning of the program and does not free it until the program has stopped.

    Initial contents of both static and dynamic arrays are set to zero.

    KNOWN BUG:
    A line with two or more DIM statements is not correctly logged if non-first array is SHARED:
    DIM a(10): DIM b(10)
    REMEDY. use only one DIM statement per physical line:
    DIM a(10), b(10)

    See also: ERASE, REDIM


  • REDIM array(subscripts)

    Changes the size of the memory block pointed to by a dynamic array. The contents of the block will be unchanged to the minimum
    of the old and new sizes. Newly allocated memory will be
    uninitialized.
    NOTE: REDIM works correctly only for 1-dimensional arrays of numbers. Example:

      DIM DYNAMIC a(10)
      ...
      REDIM a(20)
    

    See also: DIM, ERASE


  • ERASE arraylist

    Clear and free the memory associated with dynamic arrays in the list. Arraylist is a list of bare array names separated by a comma. ERASEd can be only dynamic arrays previously created by the DIM DYNAMIC command.
    When an array is ERASEd, it's name cannot be reused in another DIM DYNAMIC command. This limitation may disappear in the future versions of QB2C.
    Example:

      DIM DYNAMIC a(10), b(100, 10)
      ...
      ERASE a, b
    

    See also: DIM, REDIM


  • CALL name[(argumentlist)]

    Call a user defined subroutine. Length of the name of the subroutine is limited to 80 characters, and it can not begin with a number (digit).

    Example.

      CALL Sub(100, a%, x(8)) 
    

    See also: SUB, FUNCTION


  • DATA constant[, constant]...

    DATA is a non-executable statement that defines an unique data block of numeric and/or string constants.

    Argument to DATA is the list of numeric or string data separated by comma. If a string constant contains commas, colons, or leading or trailing spaces you want to preserve in your program, you must enclose the string in double quotes.

    Names of symbolic constants (defined in a CONST statement) appearing in DATA statements are interpreted as strings, rather than names of constants. For example:

      CONST PI=3.141593
      .
      .
      .
      DATA 2.20, PI,45,7
    

    in this example, PI is interpreted as string "PI" rather than the number 3.141593.

    A DATA statement may contain as many constants as will fit on a line. A whole line including the DATA statement must not exceed 1023 characters (see LIMITS section).
    Several DATA lines add up data to the block in the order in which they appear in the program.

    Data from the DATA block are visible from the MAIN and all subroutines in the program file.

    See also: READ, RESTORE


  • READ variable[, variable]...

    READ is an I/O statement that reads values from the DATA block and assigns the values to variables

    Argument variablelist is made up of one or more variables, separated by commas, which are to receive the data. The variables may be string or numeric.

    When a READ statement is
    called for the first time, it reads data from the DATA block starting from the first one. It reads as many items as there are in the valiablelist. Every new call starts reading from the next item in the DATA block. To reset the reading to the first element, use RESTORE.

    During the READ, data are converted to the type as required/specified in the variablelist.

    See also: DATA, RESTORE


  • RESTORE [item%]

    RESTORE is an I/O statement that allows DATA block to be reread from a specified item. Items are counted from 1. If no argument is specified then DATA are reread from the first item.

    See also: DATA, READ


  • INP(port_number)

    INP is a device I/O function that returns a byte read from an I/O port.

    port_number is a numeric-expression which has an integer value between
      0 and 1023 (hexadecimal 0x000 to 0x3ff). It identifies the
      hardware address of the I/O port to read from.

    You must run the program as the superuser or have your program given suid permissions ("chmod u+s program_name", which again can be given only by the superuser) in order to use INP function.

    For example 889 is the address of 5 input lines of the parallel PC port.

    The INP function complements the OUT statement.

    See also: OUT

    IMPORTANT NOTICE:
    If you use either INP or OUT functions you must compile with bcc4, brun4 or run4 versions of the scripts.


  • OUT port_number, data

    OUT is a device I/O statement that sends a byte to a machine I/O port.

    port_number is a numeric-expression which has an integer value between
      0 and 1023 (hexadecimal 0x000 to 0x3ff). It identifies the
      hardware address of the I/O port to write to.
    data is a numeric expression that has an integer value between
      0 and 255, and is the data to be sent out the port.

    You must run the program as the superuser or have your program given suid permissions ("chmod u+s program_name", which again can be given only by the superuser) in order to use OUT statement.

    The OUT function complements the INP statement.

    The INP and OUT statements give a program direct control over the hardware in a system through the I/O ports. These statements must be used with care because they directly manipulate the system hardware.

    For example 888 is the address of 8 output lines of the parallel PC port. Address 890 contains 4 more output lines of the parallel port.

    Summary of the other base addresses:

         DOS        Linux          Address Hex     Dec
      +--------------------------------------------------+
      |             /dev/lp0               0x3bc   956   |
      |  LPT1       /dev/lp1               0x378   888 * |
      |             /dev/lp2               0x278   632   |
      |  COM1       /dev/ttyS0             0x2f8   760 * |
      |  COM2       /dev/ttyS1             0x3f8   1016* |
      |  COM3       /dev/ttyS2                           |
      |  COM4       /dev/ttyS3                           |
      +--------------------------------------------------+
    

    *- most common ports installed on PC's

    See also: INP

    IMPORTANT NOTICE:
    If you use either INP or OUT functions you must compile with bcc4, brun4 or run4 versions of the scripts.


  • INPUT ["promptstring"{;|,}] variablelist

    INPUT is a device I/O statement that reads input from the keyboard during program execution and stores it into a list of variables.

    variablelist - is one or more variables separated by commas

    Argument Description
    promptstring A string constant printed before the prompt character.
      If used, is displayed on the screen to tell the user of
      the program what to enter at the keyboard
    ; Print a question mark at the end of the promptstring
    , Print the promptstring without a question mark
    variablelist A list of variables, separated by commas, to accept
      the input values.

    The INPUT statement causes the program to pause and wait for data. You can then enter the required data at the keyboard.

    This implementation of input expects input numeric tokens to be delimited with "," and string tokens with ", ". In any case, there may be more white spaces. This allows you to pass strings which contain comma character. However, if input string contains white space it must be enclosed in double quotes. Example of a valid input:

      INPUT "Give one string and two numbers:"; a$, a, b, b$
      ....
    

    Execution looks like this:
    Give one string and two numbers: aa,bb ,2,3,"k l"

    Result: a$ = "aa,bb", a = 2, b = 3, b$ = "k l"


  • SSCAN a$; sep$; variablelist
    where:

    Argument Description
    a$ - a string to be scanned through;
    sep$ - a string of character separators according to which a$
      is separated into tokens;
    variablelist - a comma-separated list of variables (numeric and/or string).
      Each variable from this list is assigned a token found
      in a$ at the order of appearance.

    SSCAN is a string processing function. It scans string a$ for tokens delimited by any of the characters fount in the sep$. Each token is converted in the type of the corresponding variable from the variablelist and assigned to it. SSCAN operates on the string a$ in the similar way as READ operates on the DATA block. If variablelist contains more variables than there are tokens in a$, the overhead variables are left with their prevous values, and a run-time warning is isseed. At the exit, a$ and sep$ are not changed.

    Example 1:

      a$ = "Abcd, 12.34, efGh, -2" 
      SSCAN a$; ","; b$, x, c$, i%
      PRINT b$
      PRINT x
      PRINT c$
      PRINT i%
    

    scans a$ for string, real numnber, string and integer separated by comma and writes four results. The output will be:

      Abcd
      12.34
      efGh
      -2
    

    Example 2:
    If you want to scan a string according to either a tab or comma for example, do this:

      tab$ = ",_": MID$(tab$, 2, 1) = CHR$(9)
      SSCAN string$; tab$; .....
    

    Tip: in the above example you could also have defined tab$ like this:

      tab$ = "  "
    C tab_S[0]=','; tab_S[1]='\t';
    

    NOTE. You should use SSCAN when number and type of tokens are known. If the number of tokens is not known in advance, use TOKENS command.

    Related topics: TOKENS, TRIM$, LTRIM$, RTRIM$


  • OPEN filename$ FOR mode AS [#]filenumber

    OPEN - a file operation statement that enables input and/or output to a file.

    Argument Description
    filename$ a string or a string expression denoting the file to be
      opened
    filenumber a small positive integer: 0 is invalid, must be >=1.
      This number is used to identify an opened file to I/O
      commands like CLOSE, PUT #, GET #, etc.
    mode one of the following keywords: (C equivalent)
    INPUT Opens file for reading only. File is not changed. (r)
    OUTPUT Creates a new file and opens it for writing. If file of the
      same name exists, it is replaced with the new file. (w)
    APPEND Opens an existing file for writing at the end of the file.
      If the file does not exist, it is created. (a)
    RANDOM Opens a file for binary
    BINARY
    ACCESS
    READ
    WRITE
    READ WRITE

    Mode Description C equivalent
    INPUT Opens file for reading only. File is not changed. (r)
    OUTPUT Creates a new file and opens it for writing. If file
      of the same name exists, it is replaced with the new
      file. (w)
    APPEND Opens an existing file for writing at the end of the
      file. If the file does not exist, it is created. (a)
    RANDOM Opens a file for binary
    BINARY  
    ACCESS  
    READ  
    WRITE  
    READ WRIT TE

    NOTE. Full syntax is:

      OPEN filename$ FOR mode [ACCESS access] AS [#]filenumber [LEN=reclen]
    
    where ACCESS and LEN are read for compatibility with the QuickBASIC but are dummy.

    See also: CLOSE, SEEK, PUT, GET, INPUT, PRINT, EOF, LOF


  • CLOSE [[#]filenumber[,[#] filenumber]...]
    The filenumber is the number under which the file was opened. A CLOSE statement with no arguments closes all open files and devices.

    The association of a file with a file number ends when a CLOSE statement is executed. You may then reopen the file using the same or a different file number. Once you close a file, you may use that file's number for any unopened file.

    A CLOSE for a file or device that was opened for sequential output writes the final buffer of output to that file or device.

    CLOSE releases all buffer space associated with the closed file or files.

    The END statement closes all files automatically.

    See also: OPEN, EOF, LOF


  • LOF(filename$)

    LOF function returns file length in bytes.

    See also: DOF$


  • DOF$(filename$)

    DOF$ function returns a character which represents time of last modification of the file 'filename$'.

    See also: LOF


  • EOF(filenumber)

    EOF is a file I/O function that tests for the end-of-file condition.

    The EOF function returns TRUE (nonzero integer) if the end of a sequential file open for read has been reached or passed.
    IF EOF returns TRUE, further file reading by INPUT # or GET # commands is not possible and will produce an error. You may
    use EOF to prevent such error to occur.
    EOF recognizes 'stdin' as a special file descriptor: EOF(stdin).

    See also: stdin


  • GET #filenumber, [recordnumber], variable[, length]

    GET is file I/O statement that reads from an opened file into a variable.

    Argument Description
    filenumber - The number used in the OPEN statement to open the file.
    recordnumber - the number of the record to be read.
      The first record or byte position in a file
      corresponds to the recordnumber 1.
      For a numeric variable or array, length is the number
      of records to be read. If omitted, then length equals 1.
      For string variable or array, length is the number of bytes
      to be read in. If omitted, length equals the length of the
      string (see the function LEN).
      If you omit recordnumber, the next record or byte
      (the one after the last GET # or PUT #, or the one
      pointed to by the last SEEK) is read into the buffer.
      Each time something is read by GET #, the file pointer
      points to the next unread byte, or the end-of-file marker
      and the next GET # starts with that byte.
      The largest possible record number is 2^31 -1, or
      2,147,483,647.
    variable - A numeric variable used to receive input from the file,
      it can be single variable or element of an array.
    length - the number of records to be read in by the GET command.
      If omitted, the default is one record (see above).
      In case that a variable is a string, length is a number
      of bytes to be read in or, if omitted, the (current) length
      of the string as would be returned by the function LEN.

    Example.

      DIM b(10)       :REM Dimension an array of real numbers
      OPEN "file" FOR INPUT AS #2  :REM Open a file for reading
      ...
      GET #2,,i%      :REM Read one integer number (four bytes) into variable i%
      GET #2,,a?      :REM Read next byte into variable a?
      GET #2,,b(5)    :REM Read one real number into the array element b(5)
      GET #2,,b(6),5  :REM Read 5 real numbers into elements b(6)...b(10)
      ...
      CLOSE #2
    

    See also: PUT, SEEK, EOF


  • PUT #filenumber, [recordnumber], variable[, length]

    PUT is a file I/O statement that writes from a variable to an opened file.

    Arguments description is the sam as for the GET # statement except that the variable is written to the file rather than read from it.

    See also: GET, SEEK, EOF


  • SEEK [#]filenumber, position

    SEEK command sets the position of the pointer for file I/O to a specified position.

    The filenumber is an integer number used in the OPEN statement to open the file.

    The position is a numeric expression indicating the byte where the next read or write is to be done. The position must be in the range 1 to 2,147,483,647 (equivalent to 2^31 -1).
    The first byte in a file is 1. After a SEEK, the next file I/O operation starts at that byte in the file.

    Note: Record numbers specified in GET # or PUT # will override the file positioning done by SEEK.

    Example: see the GET # example.

    See also: PUT, GET


  • stdin

  • stdout

  • stderr

    When a C program (or a QB2C program) is started the operating system also opens three special files: standard input (stdin), standard output (stdout) and standard error output (stderr). There is nothing you must do to open them: they are already opened and ready fo use. There is probably nothing you can do th close them either: they are automatically closed on program exit.

    Currently QB2C supports writing to the standard output via PRINT command, writing to the standard error output vita the EPRINT command, and reading from the standard input using the file descriptor 'stdin' in the following commands/functions/statements: INPUT, INPUT #stdin, LINE INPUT #stdin, GET #stdin, EOF(stdin).

    Examples:
    ...
    WHILE NOT EOF(stdin)
    LINE INPUT #stdin, a$
    INPUT #stdin, a, b, c
    PRINT a$, a, b, c
    WEND
    ...

    Redirecting standard output to the file:
    myprog > file

    Redirecting both standard output and std. error to the file: myprog >& file

    Redirecting content of a file into the std. input:
    myprog < file
    or:
    cat file | myprog -

    Redirecting string into the standard input:
    echo "This goes into the standard input of the program myprog" | myprog

    See also: PRINT, EPRINT, INPUT, INPUT, LINE, GET, EOF()


  • IF
    A flow control command. Supported syntax:

    Inline:

       IF bool THEN expr
       IF bool THEN expr ELSE expr
       IF bool THEN expr ELSE IF expr THEN expr
       IF bool GOTO 100
       IF bool GOSUB 100
    
    In inline syntax, after THEN and ELSE may be only a label, for example:
       IF a = b THEN 100 ELSE 200
    

    Multiline:

       IF bool THEN
        expr
       [[ELSEIF bool THEN
        expr]
       [ELSE
        expr]]
       END IF
    

    In multiline IF statements you may add a remark in the form: REM ... only after the keywords THEN and ELSE and in that case the remark must not be separated by a colon ":".
    Example:

      IF a = 1 THEN REM Remark no. 1
       ...
      ELSE REM Remark no. 2
       ...
      END IF
    

    See also: SELECT


  • SELECT CASE ... [CASE ELSE] ... CASE END

  • CASE

    SELECT CASE is a control flow statement that executes one of several statement blocks depending on the value of the test expression.

    Syntax:

      SELECT CASE testexpression
      [CASE expressionlist1]
        [statementblock-1]
      [CASE expressionlist2
        [statementblock-2]] ...
    
      [CASE ELSE
        [statementblock-n]]
      END SELECT
    

    testexpression is any numeric or string expression;
    expressionlist contains one or more expressions of the same type as
      testexpression;
    statementblock consists of any number of statements on one or more
      lines;


  • LOCATE row, column
    A device I/O statement that moves the cursor to the specified position on a text-mode window.

    row The number of a row on the screen; row is a numeric
      expression returning an integer. If row is not specified,
      then the line (row) does not change.
    column The number of a column on the screen; column is a numeric
      expression returning an integer. If column is not
      specified, then the column location does not change.

    For normal text-mode screen the usefull ranges are:
    1<= row <= 80
    1<= column <= 25

    LOCATE is usually used just before the PRINT command in order to print the output starting at the specified position on the window. See also: PRINT, COLOR


  • COLOR [bg[, fg]]
    COLOR command appears reduced to its essence.
    The bg and fg may be numerical expressions. Useful ranges are: 0<= bg <= 31
    0<= fg <= 7
    For bg or fg out of specified ranges, modulo 32 and modulo 8 respectively are taken.
    The numeration of colors is different than in QuickBASIC, but all colors are there:
    Colors 0...7 are: black, red, green, yellow, blue, magenta, cyan, white
    colors 0...7 are half-bright. These are the only valid values for background;
    colors 8..15 are the same as 0...7 but of maximal brightness (i.e. "bold");
    colors 16..23 are the same as 0...7 but blinking;
    colors 24..31 are the same as 8..15 (bold) and blinking.

    If COLOR is called without arguments, the default colors are restored. In case something terrible happened, you may reset the terminal with SHELL "reset" from within a program, or type 'reset' at the prompt.


  • CLS
    clears the screen (alternatively, SHELL "clear" does the same). Syntax :
    CLS [n]
    Valid arguments are 0, 2 or none. 0 or none clears the whole screen and places cursor at home while 2 clears all but the last line.


  • LABELS

    A line may be labeled so that "GOSUB label" or "GOTO label" may jump to the line. Labels must be numbers only unless option "-lab" is not specified at compile-time in which case labels may additionally be alphanumeric. Non-numeric labels must contain a colon ":" at ther right end.
    It is not necessary that a label defined must be used, but a label used (by GOTO, GOSUB) must be defined or compile-time error will occur.

    Label examples:
    Good label: 1000
    Good label: A1000:
    Bad labels: A1000 1000A Abcd 10A00

    Labeling examples:

         GOTO 10
         ...
      10 PRINT "This is line labeled 10"
    

    or:

         GOTO 10
         ...
      10
         PRINT "This is line after the line labeled 10"
    

    or:

         GOTO A10
         ...
      A10:
         PRINT "This is line after the line labeled A10"
    

    or:

         GOTO start
         ...
      start: PRINT "This is line labeled start"
    

    See also: GOTO, GOSUB


  • GOTO label

    GOTO performs unconditional jump to a line labeled with 'label'. This line must be in the same procedure or subroutine as the GOTO statement. GOTO may be used to exit from loops.

    See also: LABELS, GOSUB


  • GOSUB label

    GOSUB...RETURN are a control flow statements that jumps to, and returns from a local subroutine. A local subroutine is a piece of code within the sam subroutine or the main program. GOSUB unconditionally jumps to a line labeled with 'label'. When a program flow enounters the RETURN statement for the first time it returns to the line immediately after the GOSUB statement.

    You may call a local subroutine any number of times in a program. You may also call a local subroutine from within another local subroutine. In QB2C the terminal GOSUB depth is 16 levels. Local subroutines that call themselves (recursive subroutines) can easily run out of stack space.

    GOSUB is very versatile because you may jump to different parts of a piece of code, which can contain more than one RETURN statements, returning from the first one that happens to be executed. However, this style of programming may be made very unclear and hard to debug even to its creator.

    See also: RETURN, LABELS, GOTO


  • RETURN

    Return from a local subroutine.

    See also: GOSUB


  • TIMER
    TIMER - a function of type double, which returns the number of seconds
      elapsed since midnight

    Syntax

      a = TIMER
      z# = TIMER
    

    TIMER returns a number of seconds down to a microsecond, i.e. 6 decimal places. However true timing accuracy is machine dependent and can be less than that.

    The TIMER function can be used with the RANDOMIZE statement to generate a random number. It can also be used to time programs or parts of programs.

    BASIC COMMANDS


  • TIME$
    Usage: a$ = TIME$
    Returns time in the format hh:mm:ss


  • PAUSE sec

  • SLEEP sec
    Program execution pauses 'sec' sec. This is precise to a microsecond i.e. 1.000001 is a longer interval than 1. seconds.


  • SOUND, BEEP
    send a standard beep through the PC speaker.


  • PRINT [outputlist]
    where outputlist is [string[,][;]] ...

    PRINT is a device I/O statement that outputs data to the screen.

    Print a string, string expression or number.
    IF outputlist is omitted then print an empty line.

    See also: PRINT, EPRINT


  • PRINT USING format$; outputlist
    where outputlist is [string[,][;]] ...

    PRINT USING is a device I/O statement that outputs formatted data to the screen.

    Print a string, string expression or number, under a control of format. Format may contain only characters "#" and/or ".". For example: PRINT USING "###.##"; a
    will print a as a float number which occupy exactly 6 places, and is print with precision to two decimal places.
    Example:

      i% = 123: j% = 123456: k% = 1
      h$ = "#####"
      PRINT USING h$; i%; j%; k%
    

    will print the string 15 characters wide, in which each of integer numbers i%, j%, k% will occupy at most 5 characters, other characters will be blank:

        12323456    1 
    

    See also: PRINT, EPRINT


  • EPRINT .......
    The same as PRINT command except that is prints to the standard error device (stderr) rather than to the standard output device (screen). Normally, output of the PRINT command can be redirected into a file like this:

      $ program > file
    

    However, the output of EPRINT will still appear on the screen. Thus, EPRINT is suitable for printing error messages. If you want to redirect both PRINT and EPRINT output use >& :

      $ program >& file
    

    If you want to redirect output of PRINT to file1 and EPRINT to file2:

      $ program > file2 2>&1 > file1
    

    See also: PRINT


  • expression-1 MOD expression-2
    Calculates remainder of division of expression-1 by expression-2. Before doing so, both expressions are rounded to nearest integer.

    EXAMPLE:

      1 + 2 * 19 MOD 6.7 + .5
      is equivalent to:
      1 + (CINT(2 * 19) MOD CINT(6.7)) + .5
    
    The result is 4.5.


  • EXISTS("filename")
    Function EXISTS returns TRUE if file or dircetory "filename" exists, FALSE if it doesn't exist. This function normally expands the ~ (tilda). String expression can also be passed as an argument.

    EXAMPLE:

       name$ = "myfile.dat"
       IF EXISTS("~/" + name$) THEN
        ...
       END IF
    
    The block ... will be executed if a file or a directory with the name "myfile.dat" exists.


  • SHELL commands$
    SHELL executes....

    GRAPHICS COMMANDS

    Set of graphics commands to work under X11 windows system is included. They are similar in syntax to the original Quick Basic commands, except for some intrinsic differences between DOS and X11 graphics display. For example, the 'SCREEN 10' command will open an 820x485 pixel X-window to which subsequent graphics will be sent. Both text and graphics screens live at the same time, so there is no need to switch between two modes ('SCREEN 0' is obsolete).

    There is a small demo program 'graphic.bas' included in this package. Try to compile it and understand how it works:
    bcc graphic
    graphic

    Below is the short review of syntax.


  • SCREEN (x, y)[, width, height[, title$[, Xfont_name$]]]
    SCREEN 10

    SCREEN command establishes connection to the X server, initializes graphics (colors, fonts, etc.) and opens an X11 graphic window with identifier ID = 0 at the position (x, y) pixels. It has two supported syntaxes.

    SCREEN 10
    Initializes graphics and opens an X11 graphic window of the size width=820; height=485 pixels using default title and font.

    SCREEN (x, y)[, width, height[, title$[, Xfont_name$]]]
    Initializes graphics and opens X11 graphic window with identifier ID = 0 at the position (x, y) pixels. The window ID number is used in commands like: XSELWI, XCLS etc.
    The optional width and height of the window are specified in pixels. If not specified, the default is: width=820, height=485.
    The default background color is white and foreground black. These may be changed (individually for each window) via SET BG or XCLS. The default global font is:
    "-misc-fixed-medium-r-normal-*-20-140-*-100-c-100-iso8859-1" and it fits exactly 80 rows and 25 columns in the default window size. Initial title for the window can be set via title$ parameter. By default title will be written in the form: title@hostname. To avoid printing of the hostname, start the title with "-". Title of an already open window can be redefined via XTITLE command, which behaves the same way.

    SCREEN must be the first graphics command and must be executed exactly once. If more than one X-windows are needed they may be opened via XWINDOW command.

    The background color of an already opened window can be changed via XCLS command.

    See also: XCLS, SET, XTITLE, BACKINGSTORE


  • BACKINGSTORE

    From the early days of the QB2C its graphics has been relying on so called "backing store" feature of the XFree86 servers. The backing store means that the content of every window is kept in a memory and that it can be pulled out when needed automatically, by the X-window server. For example if a window gets obscured by another window it is clear that the obscured part of its content isn't present anymore in the video memory. When the obscured part became exposed again, its content can be restored if a copy of the window content is kept at hand. The "backing store" feature means that such refreshing of a window content is done automatically: programmer does not have to bother with it. However, since XFree86 version 4.0.0 it has been decided that such a system creates too big a load for X server and the backing store is OFF by default ever since. Some server modules still allow to switch ON the backing store, but some window managers (notably KDE, KDM) do not behave properly when the backing store is ON.
    To switch ON the backing store on a typical Linux X-window system:

    startx -- -depth 16 +bs

    Note that "-depth 16" sets the color depth to 16 bits per pixel, which is the maximal color deepth for proper functioning of screen capturing commands such as: SAVEGIF, SAVEPS etc. The "+bs" option switches ON the backing store.

    The QB2C (since version 4.91) supports its own internal backing store which is invoked at time when program execution reaches the command BACKINGSTORE. It works well with all window managers.

    BACKINGSTORE is equivalent to switching ON the XBUF buffer for all currently active and future active windows.

    Example. See the program xbutton.bas which is a part of the QB2C package.

    See also: XBUF, XRMBUF


  • XWINDOW (x, y)[, width, height[, title$]]

  • win% = XWINDOW (x, y)[, width, height[, title$]]
    Open an X11 graphic window at the position (x, y) pixels. The window identification number is the next unused integer number and will be written to variable win% if specified. The first window (ID = 0) must be opened with the SCREEN command. The window ID number is used in commands as: XSELWI, XCLS etc.
    The optional width and height of the window are specified in pixels. If not specified, the default is: width=820, height=485.
    The default background color is white and foreground black. These may be changed (individually for each window) via SET BG or XCLS.

    The background color of an already opened window can be changed via XCLS command.

    See also: XCLS, SET, XTITLE, SCREEN, BACKINGSTORE


  • PALETTE color_index%, r%, g%, b%
    PALETTE statement sets one color in the palette (2 <= color_index <= 255), where r%, g%, and b% are the color intensities (red, green, blue) between 0 and 255 each.
    Color indexes 0 and 1 are used by the system for the window background and foreground colors respectively, when graphics is initialized (SCREEN) and should never be changed by user directly. You can alter the background of each opened window individually using XCLS and/or SET BG. (See LOADGIF for more details when GIF's are manipulated.)

    See also: SCREEN, LOADGIF


  • XTITLE title$[, win%]
    title$ = title
    win% = window identifier number
    Title of an already open window can be set via XTITLE command. By default title will be written in the form: title@hostname. To avoid printing of the hostname, start title with "-".
    If win% omitted, set the title of the current window.
    If window win% is not existing, command has no effect.

    See also: XWINDOW


  • PSET (x, y)[, color%]
    Draws one point of a given color index from the current PALETTE, and sets the most recent point to (x, y).
    If color index is omitted then the line is drawn in the current color. This can be overridden with '-col' option to the compiler, in which case the default color is the foreground color (color = 1).

    See also: SET, PGET, LINE


  • PGET (x, y), color%
    Gets the color index color%, according to the current PALETTE, of a point at the location (x, y).

    See also: PSET


  • LINE graphic command
      LINE (x1, y1)-(x2, y2)[, [color%][, [B[F]][,style%]]]
      LINE [[STEP] (x1,y1)]-[STEP] (x2,y2) [,[color][,[B[F]][,style]]]
      LINE - [STEP] (x, y)[, color%[, B[F]]
    
    /* Other uses of STEP keyword are not yet supported ! */
    Draws a line, where 'color' index is defined via PALETTE.
    If color index is omitted then the line is drawn in the current color. This can be overridden with '-col' option to the compiler, in which case the default color is the foreground color (color = 1).
    The dashing style may be set with SET DMOD command (see below).

    LINE Statement Details

    Syntax

      LINE [[STEP] (x1,y1)]-[STEP] (x2,y2) [,[color][,[B[F]][,style]]]
    

    The coordinates (x1,y1) and (x2,y2) specify the endpoints of the line; note that the order in which these endpoints appear is unimportant, since a line from (10,20) to (120,130) is the same as a line from (120,130) to (10,20).

    The STEP option makes the specified coordinates relative to the most recent point, instead of absolute, mapped coordinates. For example, if the most recent point referred to by the program is (10,10), then

      LINE -STEP (10,5)
    

    draws a line from (10,10) to the point with x coordinate equal to 10 + 10 and y coordinate equal to 10 + 5, or (20,15).

    You may establish a new most recent point by initializing the screen with the CLS and SCREEN statements. Using the PSET, PRESET, CIRCLE, and DRAW statements will also establish a new most recent point.

    Variations of the STEP argument are shown below. For the following examples, assume that the last point plotted was (10,10):

    Statement Description
    LINE -(50,50) Draws from (10,10) to (50,50)
    LINE -STEP(50,50) Draws from (10,10) to (60,60); that
      is, to 10 plus offset 50
    LINE (25,25)-STEP(50,50) Draws from (25,25) to (75,75); that
      is, to 25 plus offset 50
    LINE STEP(25,25)-STEP(50,50) Draws from (35,35) to (85,85); that
      is, from 10 plus offset 25 to that
      point plus offset 50
    LINE STEP(25,25)-(50,50) Draws from (35,35) to (50,50); that
      is, from 10 plus offset 25 to
      absolute 50

    The color is the number of the color in which the line is drawn. (If the B or BF options are used, the box is drawn in this color.) See the PALETTE statement details for information about how to specify a color.

    The B option draws a box with the points (x1,y1) and (x2,y2) specifying diagonally opposite corners.

    The BF option draws a filled box. This option is similar to the B option; BF also paints the interior of the box with the selected color.

    The style is a 16-bit integer mask used to put pixels on the screen. Using the style argument is called "line styling." With line styling, LINE reads the bits in style from left to right. If a bit is 0, then no point is plotted; if the bit is 1, a point is plotted. After plotting a point, LINE selects the next bit position in style.

    Because a 0 bit in style does not change the point on the screen, you may want to draw a background line before using styling so you can have a known background. Style is used for normal lines and boxes, but has no effect on filled boxes.

    When coordinates specify a point that is not in the current viewport, the line segment is clipped to the viewport.

    See also: SET, PALETTE, PSET, PLINE


  • PLINE n%, array_%[, color%]
    Connects first n% points given in the array 'array_%' with the straight line which attributes may be set with SET command (see below). See the notes about the array in PMARKER command. It works also for n% = 1 in which case a point is drawn.
    Color may both be specified by SET LCOL command or with the third argument, which is equivalent.

    See also: PMARKER, SET


  • MARKER (x, y)[, color%]
    Plots a marker at the point (x, y). Attributes of the marker may be set with the SET PMTS, SET PMCI command.

    See also: SET, SET


  • PMARKER n%, array_%[(j%)][, color%]
    Plots n% markers using points from the 2-dimensional array 'array_%' which must be of type single short (therefore the '_%' suffix) and must have the second dimension equal to 1, for example:
    DIM array_%(10, 1)
    Then the first three points are:
      (x0, y0) -> (array_%(0, 0), array_%(0, 1))
      (x1, y1) -> (array_%(1, 0), array_%(1, 1))
      (x2, y2) -> (array_%(2, 0), array_%(2, 1))
    
    etc.
    If an argument to array_% is omitted then only first n% points are drawn. If the argument j% is given then draw n% points starting from the j%-th point (points are counted from zero).
    Attributes of the marker may be set with the SET PMCI (color) and SET PMTS (type and size) commands.

    Examples.
    See also: SET


  • CIRCLE (x, y), radius, [,[color][,[start][,[end][,aspect]]]]
    Draws a circle (or ellipse) with the center at the position (x, y) and 'radius'. It is possible to give 'start' and 'end' angles in radians: they are connected in positive sense. For ellipses, horizontal radius is given by 'radius' while 'aspect' is the ratio of vertical to horizontal radius. Color of the circle may be also set via SET FACI. For filled circles and ellipses use ixarc routine directly from C: C ixarc(x, y, rx, ry, angle1, angle2, ifill);
    with all parameters being integers:
    (x, y) is the center;
    rx is the horizontal radius;
    ry is the vertical radius;
    angle1 start angle in degrees;
    angle1 end angle in degrees;
    ifill 0=hollow, 1=filled according to SET FASI (style) and
      SET FACI (color) attributes
    Examples.

    Draw a circle of radius 20, with the center at x=150, y=100 :

       CIRCLE (150, 100), 20, 1
    

    Draw an elipse with horizontal radius 20, vertical radius 10, and the center at x=150, y=100 :

       CIRCLE (150, 100), 20, 1, 0, 6.3, .5
    


  • XTEXT (x%, y%), text$[, angle[, magn]]
    Draws the text 'text$' at the position (x%, y%) with an 'angle' (in degrees) and magnification factor 'magn'.
    By default angle=0., magn=1. .
    By default the text is aligned to left lower (descenders') corner. Text alignment may be changed with SET TXAL command. Text color and font may be set with SET TXCI and SET TFON commands.
    NOTE: Use of a magnification factor different from default may cause the letters to look very crude. It is better to use a font of appropriate size.

    Related topics: SET, XLEN


  • XLEN(text$)
    Function XLEN retuns integer which corresponds to the length of the text$ in pixels in the current X11-font. In other words, if printed using command XTEXT, the text would have this length in pixels.

    Related topics: SET, XTEXT, LEN


  • FAREA n%, array_%[, color%]
    Fills polygonal area described by n% points the polygon. Fill area attributes may be set with SET FASI (style) and SET FACI (color). Polygonal line describing the area may not be closed: in such a case it is assumed that the last point is connected with the first one.


  • XTRAN (x%, y%)
    Set the graphics origin to the point (x%, y%) of the window. Subsequent graphics output will be drawn with respect to the new origin. The command MRESET among other things, sets the normal origin (0, 0).

    This command affects the following drawing commands:
    LINE, PLINE, PSET, MARKER, PMARKER, FAREA, CIRCLE, XTEXT.

    See also: XROT, XSCAL, MRESET


  • XROT [(x%, y%),] angle
    Rotate subsequent graphics output by an angle 'angle' in degrees around the central point (x%, y%). If only the angle is specified, rotation central point is left unchanged. MRESET resets rotation point to (0, 0). The 'XROT 0' command disables rotation, i.e. sets rotation angle to zero, but keeps rotation central point unchanged for further use.

    This command affects the following drawing commands:
    LINE, PLINE, PSET, MARKER, PMARKER, FAREA, CIRCLE (aspect=1 only), XTEXT.

    See also: XTRAN, XSCAL, MRESET


  • XSCAL sx, sy
    Scale subsequent graphics output. Scale x values by 'sx' and y values by y.
    The command MRESET among other things, sets scales to 1, 1.

    This command affects the following drawing commands:
    LINE, PLINE, PSET, MARKER, PMARKER, FAREA, CIRCLE, but not XTEXT.

    See also: XTRAN, XROT, MRESET


  • MRESET
    Reset graphics transformation matrix: set rotation angle to zero, rotation point to (0, 0) and scale to 1, 1. This is equivalent to: XTRAN (0, 0): XROT (0, 0), 0: XSCAL 1, 1

    Graphics transformations (XTRAN, XROT and XSCAL) are done using the following formula:

      x' = xT + cos(phi) * scalex * (x - xR) + sin(phi) * scaley * (y - yR)
      y' = yT - sin(phi) * scalex * (x - xR) + cos(phi) * scaley * (y - yR)
    

    where:
    (xT, yT) = new origin set by XTRAN
    (xR, yR) = rotation central point by XROT
    phi = rotation angle set by XROT
    scalex, scaley = scaling factors set by XSCAL

    That is, the object is first moved to the origin (xO, yO), then scaled by (scalex, scaley) and then rotated by an angle phi with respect to the origin (xO, yO).

    This command affects the following drawing commands:
    LINE, PLINE, PSET, MARKER, PMARKER, FAREA, CIRCLE, XTEXT.

    See also: XTRAN, XROT, XSCAL


  • GCGET (x%, y%), answ%[, typ%[, mode%]]
    Get pointer (mouse) position in the currently selected (see XSELWI) X-window. The position is written to (x%, y%) after a mouse button is pressed, released or mouse moved within the window.

    The answ% contains button information:
    answ% = 1 ( 1) left button pressed
    11 (-1) left button released
    2 ( 2) middle button pressed
    12 (-2) middle button released
    3 ( 3) right button pressed
    13 (-3) right button released.
    -1 ( 0) motion
    -1 ( 16) window entered
    -2 (-16) window left
    25 6*(ascii + 256*keycode) key pressed
    -25 6*(ascii + 256*keycode) key released
    Values in brackets are in case that bit number 1 (2^1) of mode% is set. Sensityvity to keyboard is in the case that bit number 4 (2^4) of mode% is set (see below).

    Input parameters are:
    typ% (mouse type) = 0 previous type mode% (request mode) = 1 Request mouse only
      1 Tracking cross   17 Request mouse or keyboard
      2 Cross-hair (default mode = 1)
      3 Rubber circle  
      4 Rubber band  
      5 Rubber rectangle.  
    (default type = 0)    

    In Request modes the GCGET statement blocks until an event
    (associated with the window where the mouse is placed) is received then removes it from the queue and returns the result.

    If a keyboard key is pressed answ% equals
    to +char_ascii_code (key pressed) or -char_ascii_code (key depressed) multiplied by 256.

    NOTE: User should normally use this mouse-reading function only if the program uses not more than one X-window, because GCGET can read only one window at a time. If more than one X-window is opened, XPOINTER should be used instead.

    OBSOLESCENCE NOTE. As of the version 4.92, function GCGET is obsolete. It is no longer mantained and is kept only for backwards compatibility. Users are strongly encouraged to use XEVENT function instead.

    See also: XEVENT, XPOINTER, XCURSOR


  • XPOINTER (x%, y%), win%, answ%[, typ%[, mode%]]
    Get pointer (mouse) position, keyboard and some other X11 events. Full description of both input and output parameters parameters is given in the manual section of XEVENT.
    A short (non-comprehensive) summary is given below.

    Output parameters:
    (x%, y%) = the position of of the pointer;
    win% = window on which the pointer is logically positioned;
    answ% = 1 ( 1) left button pressed
      11 (-1) left button released
      2 ( 2) middle button pressed
      12 (-2) middle button released
      3 ( 3) right button pressed
      13 (-3) right button released.
      -1 ( 0) motion
      -1 ( 16) window entered
      -2 (-16) window left
      0 ( 32) window resized
      0 ( 64) window obscured or exposed
      256*(ascii + 256*keycode) key pressed
      -256*(ascii + 256*keycode) key released
    Values in brackets are in case that bit number 1 (2^1) of mode% is set. Sensityvity to keyboard is in the case that bit number 4 (2^4) of mode% is set (see below).

    Input parameters are:
    typ% (mouse type) 1 Tracking cross mode% (report mode)
      2 Cross-hair bit 2^0 0=Request 1=Sample
      3 Rubber circle bit 2^1 set motion=0
      4 Rubber band bit 2^4 set keyboard on
      5 Rubber rectangle bit 2^5 set resize, expose on
      (default = 1) (default = 19)

    In Request mode the XPOINTER statement blocks until an event (associated with the window where the mouse is placed) is received then removes it from the queue and returns the result.

    In Sample mode it checks for an event in the queue (associated with the window where the mouse is placed) and if one is there removes it and return the result whereas if there is no such event it returns code 128. This makes possible further execution of the program.

    OBSOLESCENCE NOTE. As of the version 4.92, function XPOINTER is obsolete. It is no longer mantained and is kept only for backwards compatibility. Users are strongly encouraged to use XEVENT function instead.

    See also: XEVENT, GCGET, XCURSOR


  • XEVENT (x%, y%), win%, but%, asc%, key%[, typ%[, mode%]]
    Function XEVENT reads the next event from the X-event queue, deletes it and returns the result through its output parameters. Descriptions of both input and output parameters are given below. XEVENT superseeds obsolete GCGET and XPIINTER functions.

    Output parameters short summary:
    x%, y%= pointer coordinates
    win% = window to which the event referes; -1 if neither
    but% = code of (de)pressed mouse (-)(1,2,3)
    key or Enter/Leave +/-16 event
    window resized event +32
    window obscured/exposed event +64
    asc% = ascii code of (de)pressed keyboard key
    key% = keyboard code of the (de)pressed key
    (usefull for function or other non-alphanumeric keys)

    Input parameters short summary:
    typ% (mouse type) 1 Tracking cross mode% (report mode)
      2 Cross-hair bit 2^0 0=Request 1=Sample
      3 Rubber circle bit 2^1 set motion=0
      4 Rubber band bit 2^4 set keyboard on
      5 Rubber rectangle bit 2^5 set resize, expose on
      (default = 1) (default = 19)

    X server generates certain events and fills a special buffer called "X-event queue". XEVENT reads one event from the queue and removes it. XEVENT is aware of the following events: mouse button press/release, pointer motion, window resize, window obscure/expose, keyboard key press/release. Not all of these events are reported by XEVENT. Details of what gets reported are controled by mode% parameter.

    The mode% is an integer input parameter whose bits are seen as flags. Each flag can be set (1) or not set (0). Currently active bits are: 0, 1, 4, and 5.

    Bit 0 determins whether XEVENT operates in Sample (set) or Request (not set) mode. In Request mode the XEVENT statement blocks until an event (associated with the window where the mouse is placed) is received, then removes it from the queue and returns the result. In Sample mode it checks for an event in the queue (associated with the window where the mouse is placed) and if one is there removes it and return the result whereas if there is no such event it returns code 128. This makes possible further execution of the program.

    Bit 1 controls the way events are reported. This is summarized in the table below:
    window leaved => answ% = -16 -2
    window entered => answ% = 16 -1
    window resized => answ% = 32 0
    window obscured/exposed => answ% = 64 0
    mouse moved within the window => answ% = 0 -1
    button 1 pressed/released => answ% = 1/-1 1/11
    button 2 pressed/released => answ% = 2/-2 2/12
    button 3 pressed/released => answ% = 3/-3 3/13

    Bit 4 controls whether XEVENT reports keyboard events (bit set) or not (bit not set).

    Bit 5 controls whether window resized and window obscured/exposed events are reported (bit set) or not (bit not set).

    If a keyboard key is pressed, XEVENT returns a window number of the active window (active window s recognized by its border color) and answ% equals to +char_ascii_code (key pressed) or -char_ascii_code (key depressed) multiplied by 256. This is only efective if bit 4 of mode% is set. For example in mode 17 XEVENT will lock and wait for any mouse or keyboard or window event to happen.

    Table of codes of some keys:
    Key asc% key%
    A-Z 97-122 38-52
    a-z 65-90 38-52
    @ 64 11
    F1 0 67
    F2 0 68
    F3 0 69
    F4 0 70
    F5 0 71
    F6 0 72
    F7 0 73
    F8 0 74
    F9 0 75
    F10 0 76
    F11 0 95
    F12 0 96
    Insert 0 106
    Home 0 97
    PageUp 0 99
    Delete 0 107
    End 0 103
    PageDn 0 105
    Cursor Up 0 98
    Cursor Left 0 100
    Cursor Down 0 104
    Cursor Right 0 102
    Shift (Left) 0 50
    Ctrl (Left) 0 37
    Alt (Left) 0 64
    Shift (Right) 0 62
    Ctrl (Right) 0 109
    Alt (Right) 0 113
    MSWin (Left) 0 115

    NOTE. Window enter and leave events are sometimes not
    detected by the X11 system. Other events may be corrupted with some window managers (notably KDE).

    NOTE ON PERFORMANCE
    Modes with keyboard are some 60 percent slower than pure mouse modes.

    See also: XCURSOR


  • XCURSOR ctype%
    Defines cursor shape for the current window. The cursor for that particular window remains unchanged everafter, except if GCGET is called for this window. On the other hand, XPOINTER doesn't change windows' pointer. Cursor types are listed in <X11/cursorfont.h> file for the particular system. Quite standard are the following types:
    XC_X_cursor (SCREEN and XWINDOW default), XC_crosshair, XC_arrow, XC_left_ptr, XC_right_ptr, XC_hand1, XC_hand2, XC_watch,
    XC_based_arrow_down, XC_based_arrow_up, XC_boat, XC_bottom_left_corner, XC_bottom_right_corner, XC_bottom_side, XC_bottom_tee, XC_box_spiral, XC_center_ptr, XC_circle, XC_cross, XC_cross_reverse,
    XC_diamond_cross, XC_dot, XC_dotbox, XC_double_arrow etc...


  • XREQST (x%, y%), width%, height%, text$[, status%[, mode%]]
    Request input text at the position (x%, y%) in the current window, and optionally return status. The text input area is width% wide and height% high rectangle. Parameter text$ is a two way parameter (both input and output). If text$ is a nonempty string when calling the XREQST then its content is drawn into the input area. If mode% is zero then then the XREQST waits until either <Return>, <Esc>, <Tab>, <PageUp>, <PageDown> or <Ctrl>-<char> where <char> is a character key, from <a>..<z> and from <A>..<Z>. If mode% is nonzero, then XREQST only draws the string string$ into the editing area and exits immediately.

    Usual editing keys are active: cursors, Ins, Del, Ctrl-D etc. XREQST uses the current font.

    (x%, y%) point in the current window at which the cursor is drawn
      for input from the keyboard;
    text$ string variable to which the input text is written after
      an <Return> or <Alt>-<Return> is pressed. If <Esc> key is
      pressed, function terminates, and text$ remains unchanged.
      The only difference in ending the call to XREQST by
      <Return> or <Alt>-<Return> is the value of the status
      on exit. This allows user a more flexible programming.
    status% integer variable to which status flag is written if specified.
      Status can have one of the following values:
      status meaning
      0 call was terminated by pressing <Esc>
      1 call was terminated by pressing <Return>
      2 terminated by mouse click outside the button
      3 call was terminated by pressing <Tab>
      4 call was terminated by pressing <PageUp>
      5 call was terminated by pressing <PageDown>
      6 call was terminated by leaving the window
      65-90, 97-122 call was terminated by pressing <Ctrl>-<char>
      and status has the meaning of ASCII code
      of the <char>, except for <d> and <D> which
      has special meaning, namely deleting part
      of the input line from cursor to the end.
    mode% controls behavior of the XREQST.
      mode meaning
      0 (default) alow editing of the text and wait until a
      key is pressed and then exit
      -1 write the (nonempty) string text$ with
      left alignment and exit immediately
      1 write the (nonempty) string text$ with
      right alignment and exit immediately


  • SAVEGIF filename$
    Saves contents of the current graphics window into a GIF87a file.


  • SAVEPS filename$

    Saves contents of the current graphics window into a PostScript file. Figure is resized proportionally in width and height to fit the A4 paper.


  • SAVEEPS filename$

  • SAVEEPSL filename$

    Saves contents of the current graphics window into the file in Encapsulated PostScript format.
    Figure is resized proportionally in width and height to fit the A4 paper. SAVEPSL creates the same picture in Landscape orientation, also to fit the paper.


  • LOADGIF (x%, y%), filename$[, ipal%], bgcolor%]
    Loads a GIF from a file into the current graphics window, such that the upper left corner of a picture is placed at the pixel position x%, y% It works well for GIF87a and non-extended GIF89a file formats. If ipal% = 0 (default) then the picture is loaded using its own color palette, whether if ipal% = 1 the unique standard 6x6x6 palette is used. This language supports only 256 colors at the time.
    In the case ipal% = 0, palette occupies colors from 16 up to max 255. In the case ipal% = 1, palette occupies colors from 32 up to max 255. Therefore safe user-defined colors are from 2 - 15 (or 31) (see the SCREEN command).
    GIF's background can be specified by index 0 <= bgcolor% <= 255 in the palette which will be present after the GIF is loaded. Default is -1 which means GIF's own background. Specify bgcolor% = 0 to set GIF's background to the current window background.

    See also: READGIF


  • READGIF (x%, y%), filename$, array?[, ipal%], bgcolor%]
    Loads a GIF from a file into the array of bytes array?().
    User must make sure that array?() is large enough to hold the picture (one byte per pixel), or a run-time error will occur. It works well for GIF87a and non-extended GIF89a file formats. See LOADGIF for deatils about other parameters.

    See also: READGIF


  • GIFINFO filename$, width[, height[, ncolor]]
    Obtain width, height and number of colors used in the GIF file 'filename$' Variable types of width, height and ncolor may be any.


  • GET (x%, y%), array?, w%, h%
    Copy a rectangular area of the current window into an one-dimensional array of color pixels.
    Point (x%, y%) specifies the top-left corner of the rectangle, and w%, h% are width and height of the rectangle in pixels.
    User must make sure that the array has enough space to receive the image. Each pixel is represented with one byte of information. Number of bytes required to store image is w% * h%. The byte representing one pixel contains a value between 0 and 255 which is a code color of that pixel, corresponding to the current palette. Pixels are stored in the natural order i.e. pixel at the coordinate (x, y) of the rectangular is placed at the (x + w% * y)-th byte of the array.

    It is recommended to use byte-type array (suffix "?") if some kind of picture manipulation is intended by the user, since in this case one element of the array corresponds to exactly one pixel of image.

    NOTE: See the PUT and GETCOL commands and the example program getput.bas.


  • GETCOL icol%, r%, g%, b%
    Retrieve information about the color icol% in the current palette. Returns red (r%), green (g%) and blue (b%) components of the color icol%.

    Related topics: PALETTE, GET, PUT


  • PUT (x%, y%), array?, w%, h%[, (xs%, ys%)[, sw%, sh%]]
    Put contents of an color array onto the current window.
    Contents of the array is interpreted as a square image of the width w% and height h%. Pixels are retrieved in the natural order i.e. pixel at the coordinate (x%, y%) of the rectangular is placed at the (x% + w% * y%)-th byte of the array. A subimage of this is copied on the window. Subimage starts at the upper left corner (xs%, ys%) relative to the image stored in the array and has the width sw%, height sh%. The image is drawn on the window according to the current draw mode (SET DRMD).
    Parameters:
    (x%, y%) - point in the destination window where to put the image
    array? - name of the byte-type array of pixels (one byte per pixel)
    w%, h% - dimensions of the image stored in the array
    (xs%, ys%) - upper left corner of subimage to be copied, default = (0, 0)
    sw%, sh% - window dimensions, default = w% - xs%, h% - ys%

    Related topics: PUT, GET, PALETTE, GETCOL, SET

    NOTE: See the GET and GETCOL command for the additional information.
    NOTE: In order to produce correct image, color palette must not be
      changed between GET and PUT commands, since `array?' only contains
      color codes of pixels.
    NOTE: Using multiple PUT commands it is possible to achieve animation.
      However, simpler and faster way is to use XANIM command.