0 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: Random, random@random.com.hr Version: 4.76 04. Dec 2002. CONTENTS USER'S MANUAL FOR QB2C (QuasiBASIC) INSTALLATION QB2C MAIN ADVANTAGES QB2C MAIN FEATURES DIFFERENCES BETWEEN QB2C AND ANSI BASIC PREPROCESSING LIMITS to QB2C NUMBERS, STRINGS AND NAMES STRING PROCESSING FUNCTIONS BASIC COMMANDS GRAPHICS COMMANDS ABOUT THE FORMAT OF INPUT FILES TRANSLATOR OPTIONS AT COMPILE TIME ADDITIONAL NOTES ON SYNTAX IN QB2C RESTRICTIONS MIXING C AND QB2C CODE ACKNOWLEDGEMENTS QB2C manual version information 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 0 INSTALLATION See the README file on how to install the QB2C. 0 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. 0 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 while UNIX uses only 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 + 0 DIFFERENCES BETWEEN QB2C AND ANSI BASIC o / 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. o 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 o 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. o 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$ o 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 o 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. 0 PREPROCESSING o #if defined o #else o #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. o 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. 0 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. o DEFSTR o DEFINT o DEFDBL o DEF FNname(parameterlist) = expression This is equivalent of: FUNCTION name(parameterlist) name = expression END FUNCTION See also: FUNCTION o FUNCTION...END FUNCTION - a non-executable statement that declares the 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. 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 FN, SUB o SUB...END SUB - a procedure statement that declares the the body of a SUB procedure 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. 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 o 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$ ... o 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 statement o 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$ function 0 STRING PROCESSING FUNCTIONS o STRING$(n%, asc%) Function that returns a string of length n% whose characters all have given asc% ASCII code. See also: SPACE$ o SPACE$(n%) SPACE$ is a string processing function that returns a string of spaces of length n%. See also: STRING$ o 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 o 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 o 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 o 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$ o 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$ o 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$ o 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$ o 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$ o 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$ o 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 o 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$ o 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 o LEN(a$) LEN returns the number of characters in the string a$. o 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$ function, VAL function o 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$ function, VAL function o 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& o 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$ function o 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$ function o 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$ o 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$ o MATHEMATICAL FUNCTIONS o 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 o 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 o 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 o 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 o 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 o 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 o 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 o 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 o 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. o 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 o 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 o 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. o ARRAYS See the DIM statement. o 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. o 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. See also: ERASE, REDIM o 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 o 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 o 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 o 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 o 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 o 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 o 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. o 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. o 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" o 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$ o 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 WRITE 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 o 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 o LOF(filename$) LOF function returns file length in bytes. See also: DOF$ function o DOF$(filename$) DOF$ function returns a character which represents time of last modification of the file 'filename$'. See also: LOF function o 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. o 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 o 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 o 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 # o 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 o SELECT CASE ... [CASE ELSE] ... CASE END o 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; o 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 o 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. o 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. o LABELS A line may be labeled so that "GOSUB label" or "GOTO label" may jump to the line. Labels must be numbers only. A line may consist only of a label. 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. Currently, labels may be also alphanumeric, but non-numeric labels must contain a colon ":" at the end and form one physical line. Label examples: Good label: 1000 Good label: A1000: Bad labels: A1000 1000A Abcd 10A00 Bad label: A1000: REM This is a label Usage: 10 PRINT "This is line labeled 10" or: 10 PRINT "This is line after the line labeled 10" See also: GOTO, GOSUB o 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 o 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 o RETURN Return from a local subroutine. See also: GOSUB o 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. 0 BASIC COMMANDS o TIME$ Usage: a$ = TIME$ Returns time in the format hh:mm:ss o PAUSE sec o SLEEP sec Program execution pauses 'sec' sec. This is precise to a microsecond i.e. 1.000001 is a longer interval than 1. seconds. o SOUND, BEEP send a standard beep through the PC speaker. o 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 USING, EPRINT o 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 o 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 o 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. o 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. o SHELL commands$ SHELL executes.... 0 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. o 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 colour 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. o XWINDOW (x, y)[, width, height[, title$]] o 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 colour 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: SCREEN command. o PALETTE color_index%, r%, g%, b% 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.) o 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. o PSET (x, y)[, color%] Draws one point of a given colour 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 LCOL, PGET, LINE o PGET (x, y), color% Gets the colour index color%, according to the current PALETTE, of a point at the location (x, y). See also: PSET o 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 COLOR statement details and the SCREEN statement details for information about how to specify a color number in different screen modes. 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: PSET, PLINE o 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. o 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. o 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 (colour) and SET PMTS (type and size) commands. Examples. o 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 o 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 colour 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 TFON, XLEN o 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 TFON, XTEXT, LEN o 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. o 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 o 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 o 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 o 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 o 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% meaning 1 left button pressed 11 left button released 2 middle button pressed 12 middle button released 3 right button pressed 13 right button released. Input parameters are: typ% (mouse type) = 0 previous type mode% (request mode) = 0 Request 1 Tracking cross 1 Sample. 2 Cross-hair (default mode = 0) 3 Rubber circle 4 Rubber band 5 Rubber rectangle. (default type = 0) NOTE: User should normally use this mouse-reading function only if program uses only 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. See also: XPOINTER, XCURSOR o XPOINTER (x%, y%), win%, answ%[, typ%[, mode%]] Get pointer (mouse) position. The function waits until the mouse is moved or a mouse button pressed or released. After one of these events has happened, the function returns the following: Output parameters: (x%, y%) = the position of of the pointer; win% = window on which the pointer is logically positioned; answ% = 1 left button pressed 11 left button released 2 middle button pressed 12 middle button released 3 right button pressed 13 right button released. Input parameters are: typ% (mouse type) = 1 Tracking cross mode% (request mode) = 0 Request (default = 1) 2 Cross-hair (default = 1) 1 Sample 3 Rubber circle 2 Check 4 Rubber band 5 Rubber rectangle In Request and Sample modes 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 Check 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 -256. This makes possible further execution of the program. If a key is pressed, XPOINTER returns a window number of the active window (active window s recognized by its border color) and answ% equals to +char_code (key pressed) or -char_code (key depressed). Character codes at the moment are not understood well and are probably not portable.... See also: GCGET, XCURSOR o 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 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... o 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 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 , , , , or - where is a character key, from .. and from ... 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 or - is pressed. If key is pressed, function terminates, and text$ remains unchanged. The only difference in ending the call to XREQST by or - 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 1 call was terminated by pressing 2 terminated by mouse click outside the button 3 call was terminated by pressing 4 call was terminated by pressing 5 call was terminated by pressing 65-90, 97-122 call was terminated by pressing - and status has the meaning of ASCII code of the , except for and 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 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 o SAVEGIF filename$ Saves contents of the current graphics window into a GIF87a file. o 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. o SAVEEPS filename$ o 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. o 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 o 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 o 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. o 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. o 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 o 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 DRMD 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. o XANIM (x%, y%), array?, w%, h%[, (xs%, ys%)[, sw%, sh%]] Animate series of images stored in arrays. Similar to PUT command. XANIM is similar to PUT command, but unlike the PUT command it remembers the last image drawn. With each call XANIM performs two actions: 1) draw the old picture (if one exists), and 2) draw a new picture (specified in the array). If the drawing mode is set to 2 (SET DRMD 2) this performs animation. Other drawing modes can be also useful to achieve visual effects. For parameters description, please refer to the command PUT. Animation is achieved by a series of calls to XANIM with different arrays. You are allowed to change all of parameters in every call. At the end of animation, XANIM *must* be called once more with 0 or NULL as the array name, in order to free the memory which is not used anymore and to reset the animation for a fresh new start. Values of the other parameters then have no effect. For example: XANIM (0, 0), 0, 0, 0 . Before doing that, drawing mode may be changed to obtain a desired effect. Set DRMD to the following value: SET DRMD effect 0 leave the last image as it is (usually xor with the background) 1 overwrite the area with the last image 2 erase the last image, leaving background 3 invert the last image and overwrite the area with it Related topics: PUT, GET, PALETTE, GETCOL, SET DRMD NOTE: see the example program animate.bas o XBUF [win%] Create a buffer plane for a window win%, or the current window if the parameter win% is omitted, and copy the current window contents into the buffer. Subsequent graphics output to the window is redirected to the buffer. Buffer is flushed on the window with every call to XUPDATE Redirection of graphics output affects: LINE, PLINE, PSET, MARKER, PMARKER, FAREA, CIRCLE, XTEXT, XANIM, PUT and LOADGIF. See also: XRMBUF, XUPDATE o XRMBUF [win%] Destroy buffer associated with the window win%, or the current window if parameter is not specified. This releases memory allocated for the buffer. Such buffer may be created with XBUF. If buffer does not exist (either it was never created or is already destroyed) command has no effect. See also: XBUF, XUPDATE o XRESIZE width%, height% Resize curent window. Please note that contents of the window is set to the current background. The previous content is lost. See also: XSELWI o XMOVE (x%, y%), [win%] Move the window win% to position (x%, y%). If win% is omited then move the current window. See also: XSELWI o SET LCOL cindex% (or SET PLCI cindex%) Sets line color to the 'cindex%' defined by PALETTE; o SET LWID n% sets line width in pixels; o SET DMOD d1[, d2[, d3[, ... ]]...] Sets dashing style for lines. If there is only one argument, the dashing style is as follows: 0 = full line 1 = dashed line (6,6) 2 = dashed-dotted line (6,3,1,3) 3 = dotted line (1,6) 4 = densely dotted line (1,3) Other dashing styles may be obtained supplying more than one argument (max. 10 arguments). For example SET DMOD 6, 3, 1, 3 will produce a dashed-dotted line of 6 drawn pixels followed by 3 blank pixels, 1 drawn pixel and 3 blank pixels. (Note that a reasonable description always has an even number of arguments.) o SET DRMD mode% Set the drawing mode for drawing src to dest as follows. Set the drawing mode: mode% = 0 Keep the previous mode mode% = 1 Copy src (i.e. overwrite dest) mode% = 2 src XOR dest mode% = 3 NOT src (i.e. invert) mode% = 4 src AND dest mode% = 5 NOT (src XOR dest) o SET PMTS type%, width% sets marker type and width in pixels. This settings will be used in subsequent calls to MARKER and PMARKER; type%: 0 or 20 = filled circle 1 or 21 = filled box 2 or 22 = filled triangle pointing up 3 or 23 = filled triangle pointing down 4 or 24 = hollow circle 5 or 25 = hollow box 6 or 26 = hollow triangle pointing up 7 or 27 = hollow triangle pointing down o SET PMCI cindex% sets marker color index as defined by PALETTE; o SET TXCI cindex% sets XTEXT color index as defined by PALETTE; o SET TFON font$ SET TFON font[, size%, [enc$]] sets font used by XTEXT. There are two distinct syntaxes. SET TFON font$ The font$ is the full X font name. These X fonts can be seen with the UNIX command 'xfontsel'. The default font, set by the call to the SCREEN command is: "-misc-fixed-medium-r-normal-*-20-140-*-100-c-100-iso8859-1". A nicer font is, for example, Adobes' Helvetica: "-adobe-helvetica-medium-r-normal-*-14-0-100-100-p-*-iso8859-1". The number '14' there is the pixelsize and should be scaled if font of a different size is needed. SET TFON font[, size, [enc]] Here, 'font' is a keyword defining the font to be used. Optional second and third parameters define the size and encoding (see below). All parameters MUST be explicit constants (keywords) because true font name is substituted at compilation time. To make selection of frequently used fonts easier, there is a limited set of font keyword names as follows: __________________________________________________________________ | Abbreviated name | Font description | +-----------------------+-----------------------------------------+ | Hel | Helvetica | | HelB | Helvetica bold | | HelI | Helvetica italic | | HelBI | Helvetica bold italic | | Tim | Times | | TimB | Times bold | | TimI | Times italic | | TimBI | Times bold italic | | Sym | Symbol | | SymB | Symbol bold | | SymI | Symbol italic | | SymBI | Symbol bold italic | | Fix | Courier (fixed width) | | FixB | Courier bold (fixed width) | | FixI | Courier italic (fixed width) | | FixBI | Courier bold italic (fixed width) | +-----------------------+-----------------------------------------+ The default value of the second parameter is: size = 20 pixels. The default value of the third parameter, encoding is: enc = iso8859-1 You can specify other sizes and encodings if they are supported by your X server. EXAMPLES. SET TFON "-adobe-helvetica-medium-r-normal-*-20-0-100-100-p-*-iso8859-1" SET TFON Hel SET TFON Hel, 20 SET TFON Hel, 20, iso8859-1 All these examples invoke the same font - Adobe Helvetica, of the height of 20 pixels and encoding iso8859-1. o SET TXAL h%, v% set XTEXT alignment h% = 0 left (default) v% = 0 down (default) 1 left 1 down 2 middle 2 middle 3 right 3 up o SET FASI style%[, hatch%] Sets fill area style. Description: style% = 0 interior is not filled style% = 1 interior is filled with solid of a given (SET FACI) color style% = 3 interior is hatched with hatch% type. Valid numbers for hatch% are 0...25, there are that many different hatch types. If hatch% not specified, the default is 0 . o SET FACI cindex% sets fill area colour index. o SET BG cindex% set the background color for the current window, but do not clear the window. See also: XCLS, XBgCol% o XSELWI win% Select and rise the window to which the subsequent graphics output will be send. Window must exist or error will occur. o XUPDATE Update the current X11 window. Normally every drawing command will update the X11 screen. However, if -u flag is specified during translation no update is made other than with XUPDATE command. It may greatly improve the speed if XUPDATE is used only once in the while, for example when drawing of the whole scene (or a bigger portion) is done. See also: XBUF o XCLOSE [win%] Close the window win%. If the window win% doesn't exist, the command has no effect. If win% not specified, close the current window. If win% is the last existing window, XCLOSE also closes the graphics mode altogether (XCLOSEDS). To open it again you must call the SCREEN function. o XCLOSEDS Delete all windows and close connection to the X server. To open the graphics mode again you must call the SCREEN function. o XCLS [icol%] If icol% is not specified, clear the current X11 graphics window according to the current background of that window. If icol% specified, set the new background color to color icol% and then clear the window. The icol% is the color index as defined with PALETTE. See also: SET BG, XBgCol% o XBgCol% function NOT YET DONE ! Syntax: XBgCol%(win%) XBgCol% is a function that returns the color index of the background of the window win%. If win% is set negative, then XBgCol% returns the color index of the currently active window. See also: XCLS, SET BG o XCLIP (x1%, y1%)-(x2%, y2%), win% Set clipping rectangular region in the window win%. The clipping rectangle is defined with upper left (x1%, y1%) and lower right (x2%, y2%) points. Nothing could be drawn outside the clipping region of the window. To disable this, do XNOCLI win%. It is possible to set only one clipping rectangle per window with this command. See also: WINDOW, XNOCLI o XNOCLI win% Unset any clipping region for the window win%. See also: XCLIP, WINDOW o XWARP (x%, y%) Move graphical cursor (pointer) to the position (x%, y%) in the current window. o XGETGE (x%, y%), w%, h%, win% Get geometry of a window win%. The window position is written to (x%, y%), window width and height are written to w% and h% respectively. If win%=-1 get geometry of the root window. NOTE: This command works even if graphics has not been opened with the SCREEN command. In such a case it is only possible to get geometry of the root window. o BUTTONS (section) As of the version 4.55 there is a whole new set of commands to ease up definition and use of graphics buttons. The names of these commands are case sensitive. Maximum number of buttons defined on all windows is 255. If buttons are used then color indexes 14 and 15 are reserved: 14 is used as color index of the light rim color, 15 is dark rim color. Current background color is used as the button basic color. Extensive set of examples is found in the example file xbutton.bas that came with this package. o XDefineButton win%, id%, (x%, y%), width%, height% Define a general button (Action or Text input button). This only defines button in the memory, nothing is drawn yet. Use XDrawButton or XDrawInputButton commands to actually draw buttons. win% id number of the window in which the button is defined (window need not to exist at the time of function call) id% arbitrary identification number for a button, must be in the range 1-255. There can not be two buttons with the same identification number. If button id% already exists, the previous button is replaced and a warning message issued at run time (x%, y%) coordinate of the (outer) left upper corner of the button width% width of the button height% height of the button See also: XDrawButton, XDrawInputButton, XInputButton, XDestroyButton o XDestroyButton id% Erase previously defined button id%. id% identification number of a prevoiusly defined button (see XButtonDefine), must be in the range 1-255. If button id% does not exist, no action is taken. See also: XDefineButton o XButtonFocus id%, action$ Use this command to define what happens when the pointer is placed on top of a button. The button is identified by id% and must be already defined (via XDefineButton). Possible actions are explained below. id% identification number of a prevoiusly defined button (see XButtonDefine) action$ a string defining the type of action. The default value is "none". Possible values are: Value Meaning ---------+-------------------------------------- "none" | No action taken "up" | Lift button up "down" | Push button down "square" | Draw dashed square within the button ---------+-------------------------------------- See also: XDefineButton o XDrawButton id%, text$[, state$] Draw an action button. Action buttons are the simplest buttons. They generally have three states: up, flat or down (pressed) and may contain a text or a picture inside them. If you want a picture inside a button just draw the picture and then use XDrawButton to draw a button around (on top of) it. id% identification number of a prevoiusly defined button (see XButtonDefine) text$ a string that is to be drawn inside the button. If you do not need a text, use an empty string: "". The text is drawn using the current text font and color. It gets refreshed every time an action defined in XButtonFocus happens. state$ a string that determins how the button is drawn. There are three options: "up", "down" and "flat". Default value is "up". See also: XButtonDefine, XGetButtonState% o XDrawInputButton id%, text$ Draw a text line input button. This command only draws a text line input button and draws the text text$ in it (left aligned) but does not allow editing of the text. Note that txt$ MUST be a variable. The command is equivalent to: XInputButton id%, text$, status%, -1 where, in the context, status% is an unused output variable that will be set to 0. See also: XInputButton o XInputButton id%, text$, status%[, mode%] Draw a text line input button and allow editing of the text. This type of button lets you to write text in it and edit it by means of the keyboard and return this edited text as a string variable to the program. In order to write into the button area, you must first activate it by clicking on it (use left button on the mouse). A frame around the button will appear indicating that the window is active. When the window is active it locks the program execution until it is de-activated by one of the following actions: an exit key is pressed, clicking the pointer outside of the button area or by moving the pointer cursor outside the parent window. id% identification number of a prevoiusly defined button (see XButtonDefine) text$ string variable to which the input text is written after an or - is pressed. If key is pressed, function terminates, and text$ remains unchanged. The only difference in ending the call to XInputButton by or - is the value of the status on exit (see below). This allows user a more flexible programming. status% integer variable which is returned by the command. Its value indicates which exit key was used to de-activate the button. Status can get one of the following values: status meaning 0 button was de-activated by pressing or by clicking the pointer outside of the button area or by moving the pointer cursor outside the parent window 1 button was de-activated by pressing 65-90, 97-122 button was de-activated by pressing - and status has the meaning of ASCII code of the , except for and which has special meaning, namely deleting part of the input line from cursor to the end. mode% controls behavior of XInputButton. If not specified default is 0. mode meaning 0 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 with status 0 1 write the (nonempty) string text$ with right alignment and exit immediately with status 0 EXAMPLE See also: XDrawInputButton, XButtonDefine, XREQST o XCheckButtons (x%, y%), win%, id% Check which button is pressed on the specified window (win%) and return its id%. This is an essential command in button management. EXAMPLE. 10 XPOINTER (x%, y%), win%, answ% CALL CheckButtons(x%, y%, win%, id%) IF win% = ... and id% = ... THEN ... END IF GOTO 10 More examples are given in the xbutton.bas sample program. o XClickButton id%[, dt] Performs a single down/up (or up/down) motion of the button identified by the id%. dt is a pause between the two button positions in sec. If the button is initially raised it clicks down/up, if it is depressed it will click up/down and if it is flat it will click down/flat. id% identification number of a prevoiusly defined button (see XButtonDefine) dt dt is a pause between the two button positions in sec. Default = 0.1 sec o XGetButtonState% function Syntax: state% = XGetButtonState%(id%) Return current button state. id% identification number of a prevoiusly defined button (see XButtonDefine) state% 0 = flat, -1 = pressed, 1 = raised o XToggleButton id% Toggle button state (both logical and graphical) from either: up -> down down -> up flat -> flat. This changes logical state of the button (XGetButtonState%). If a button id% does not exist a warning message is issued at the run time. See also: XDrawButton, XGetButtonState%, XClickButton 0 ABOUT THE FORMAT OF INPUT FILES * A BASIC file input to qb2c must be in ASCII format (compressed QuickBASIC format is not acceptable). * In DOS, ASCII files have the carriage-return (Ctrl-M) character at the end of each line. Input BASIC files to QB2C may be either in UNIX format (i.e. without Ctrl-M's) or in DOS format. If a BASIC file to be translated originates from DOS, Ctrl-M's are automatically striped off prior to translation. However, all other files which are input to translated programs must be in UNIX format, ie. without CR's at the end of each line. 0 TRANSLATOR OPTIONS AT COMPILE TIME * Translator qb2c can be called with one or more of the following option flags: Option Meaning -i or -int assume variables with first letter i,j,k,l,m,n (upper or lower case) to be of the C type 'int' if not a string; -D assume variables starting with 'd' or 'D' be of C type 'double', if not a string; -b or -bcpp do not be sensitive about the case of QB command and function names or exact QB spacing of commands and variables. This actually turns on the bcpp preprocessor. (However, mixed case is not acceptable even with this option.); -c64 or -C64 this option should be used with the option '-b' since it is passed to bcpp. It switches on some syntax features specific to C-64 (Commodore 64); -l or -long all integer variables except those declared 'short integer' became of type 'long' and all real variables became are declared as type 'long'; -d or -double all float variables are declared as type 'double'; -p or -post do not perform post-processing which changes variable names like i%, i&, x#, a$, a? into C-acceptable forms: i_int, i_long, x_double, a_S, a_byte and adds headers to the C text. This is only useful for debugging output C code or qb2c itself; -c or -C this flag enables special handling of lines commented with "C", "CH " or "CM ". This makes possible direct insertion of lines written in C. For more information see the section "INSERTION OF LINES IN C" below; -m disallow logical expressions to combine with math. expressions (eg. i = (a = 1) AND (b <> 2) ); -w logical operators AND, OR operate bitwise; -n or -N disable SHELL "..." argument interpreter, i.e. the argument of SHELL command in the BASIC program will be send as it is to the system() command in the C translate. By default argument of the SHELL command is translated (for example: "dir" -> "ls -l" etc.); -u do not XUPDATE the X-window after every drawing command, such as LINE, PSET, BOX... This permits speedup of the drawing, if XUPDATE is used only once in the while, when necessary -r this option tells bcpp to replace every division " / " with " / (double)". This is to comply with BASIC's convention that division operator / always convert both left and right side to real numbers before dividing them, so that the result is also real. For example 5 / 8 equals 0.625 rahter than 0 This option is *NOT* a default. -s by default, QB2C changes the names of numerical variables, arrays and functions by replacing suffixes '%', '&', '#' and '?' with respectively '_int', '_long', '_double' and '_byte'. Specifying flag -s tells QB2C to strip off suffixes '%', '&', '#' and '?' instead. WARNING ! It is up to user to ensure that there are no variables with similar names in the program, which will become the same after stripping suffixes, for example 'a% and 'a'. In such a case, the translated code will be invalid. -g debug mode (experts only). Releases some debug output -A convert array arguments to integer (as in true BASIC) This is NOT a default. -L (length) set maximum string length. By default 1024 bytes is allocated for every string variable, or string array element. To change this default, specify `length' which must be between 1 and 32766. See also: CONST statement. -P treat PRINT as print to the current graphics screen NOT OPERATIONAL -I INKEY$ by default has an internal loop that waits until a key is pressed. If this flag is specified then there is no loop and INKEY$ samples the input every time when it is called -t or -T INKEY$ function is not compiled. Used for compatibility with hp-ux compiler which does not support termios -col default color for graphics commands such as LINE, PSET... is the foreground (else the last set color) -M erase Ctrl-M at the end of line read from the file with (LINE) INPUT #n commands. Files created in DOS have an extra Ctrl-M i.e. Carriage Return (code 13) at the end of every line. With this option translator produces a code that will erase such extra character if found at the end of a line; -B maximum compliance with BASIC: -A -r -b -P -I -col -w -O[x] optimization option(s) such as -O, -O2, -O4... passed to the C compiler; -h, -? print help message with short summary of options. -define label this enables conditional compilation as in C. This option is transfered to and processed by the bcpp preprocessor. Therefore it also recalls -b option. See the PREPROCESSING section of the manual. 0 ADDITIONAL NOTES ON SYNTAX IN QB2C Following pieces of syntax rules are a bit more restrictive than is common in various implementations of BASIC including QuickBASIC. We want to stress their importance since QB2C may produce a bad C code without warnings if they are not obeyed: * all used arrays must be explicitly declared (with DIM, or DIM DYNAMIC); * static array (DIM), constant or function declarations must occur first in a given module (MAIN, SUB...) ie. before any other expression or command or an error will occur. Exception are dynamically declared arrays (DIM DYNAMIC) declaration of which can occur anywhere in the program; * by default arguments to arrays must be explicit integers. However, you can change this using the option -A at the translation time; * all SHARED arrays must be declared in MAIN module (even if they are not used in the MAIN); * SHARED array names are passed with empty brackets eg. name(); * Files open in any module (MAIN, SUB or function) are "visible" from all other modules; * Return type of a FUNCTION is determined by its name, the rules are the same as for variables and arrays. 0 RESTRICTIONS * Type of a constant, variable or array is determined by suffix in its name. The "AS" statement in variable type definition is *not* supported. Here is the list of legal suffixes (as used by QuickBASIC) and their correspondence in C: QuickBASIC C $ -> string (or single character) char * % -> single integer int & -> long integer long # -> double float double ? -> single byte integer unsigned char _% -> 2 byte integer signed short int no suffix -> single float float Note two additional types which did not exist in original QuickBASIC: single byte integer, and two byte integer, both introduced to minimize memory usage in graphics applications. If a numerical constant contains "." or ends up with an "!" then it is a single float (example: 100 is integer, 100. and 100! are single floats). On top of that, user can modify types during translation (options -l, -d, -D) and/or using DEFxxx commands. * All arrays MUST be declared explicitly (static arrays: DIM, dinamic arrays: DIM DYNAMIC). In opposite case NO ERROR WILL BE DETECTED at translation time ! * The syntax must be strictly the one as written out by the QBASIC editor including case and spacing conventions. If not, preprocessor bcpp should be used on the file: bcpp infile outfile or the option -b used to the qb2c translator (see the option list). The bcc compiling script already uses -b option. The bcpp preprocessor may be run with one or more of the following option flags: -c64 or -C64 this option switches on recognition of some syntax features specific to C-64 (Commodore 64) -q bcpp works quietly (suppresses warnings but not errors). * There is practically no support for sound except directly from C. However, the BASIC keywords "SOUND" and "BEEP" are recognized and the standard beep is signaled through the speaker. * An array can be passed as an argument to SUB but cannot be passed to FUNCTION (yet) (see: SUB). Example: I) As a simple example you may put the following text into a file named test.bas: for i=1 to 5 print i, i^2 next Then do: bcpp -i -b test This will create the file test.c. Compile and run it with: cc -o test test.c -lm test The result should look like: 1 1 2 4 3 9 4 16 5 25 Instead of all this you may just have typed: brun test This will translate 'test.bas' to 'test.c', compile C code and run the resulting executable named a.out . 0 MIXING C AND QB2C CODE It is possible to mix BASIC and C. Lines written in C must be commented with "C " *at the beginning of a line* and -C option issued to qb2c translator. For example: pi = 3.1415 C printf("%f\n",pi); END is equivalent to: pi = 3.1415 PRINT pi END The first example must be translated with the -C option: qb2c -C name During translation names of variables, open file pointers and labels are changed in order to conform C conventions. This is done in the following way: Variables: "$" at the end of variable name becomes "_S", "%" becomes "_int", "&" becomes "_long", "#" becomes "_double", and "?" becomes "_byte". Open files: An open file identified in BASIC with number 'n', becomes identified with a pointer of name 'fp_n'. Labels: Label numbers are added "Lab_" prefix, for example "100" is renamed to "Lab_100". To make things more convenient it is possible to specify lines which are insert among the declaration lines of main routine with "CM " comment or in the overall header of the translated C program with "CH ". Variables and constants declared with "CH " are, of course, global. An example (the program asks for a word and then it prints out character codes and their squares): print "This is a small test of"; C printf("mixing BASIC and C\n"); REM We need to declare a variable in main: CM static char c; input "Say a word"; a$ for i%=1 to len(a$) C c=a_S[i_int-1]; C printf("%5d %.f\n",c, pow(c,2)); next C /* I have used a math library function (pow) only in C, therefore C a header will not be specified. I must do it myself */ CH #include end This program should be run in the following way: qb2c -b -C name run name ----------------------------------------------------------------------------- 0 ACKNOWLEDGEMENTS I wish to thank to E. Chernyaev for letting me use parts of his graphics code from various packages and his help in understanding this code. This has been a great help in development of the graphics library of QB2C. I also thank to many people around the globe who helped me with their suggestions, wishes and bug reports in past years of development of QB2C. I hope to have such encouragement to continue this work also in future. Finally, I hope you will have as much fun programming in QB2C as I had in developing it. ----------------------------------------------------------------------------- 0 QB2C manual version information First version: 04.Apr 1996.