FreeBASIC Manual
------------------------------------------------------------

This document last compiled : 2019-09-27 08:16:02
from https://www.freebasic.net/wiki/


-------------------------------------------------------------- PrintToc ----
Table of Contents

   Welcome to FreeBASIC
   Getting Help with FreeBASIC

Language Documentation

   .
      ...

   _
      __DATE__
      __DATE_ISO__
      __FB_64BIT__
      __FB_ARGC__
      __FB_ARGV__
      __FB_ARM__
      __FB_ASM__
      __FB_BACKEND__
      __FB_BIGENDIAN__
      __FB_BUILD_DATE__
      __FB_CYGWIN__
      __FB_DARWIN__
      __FB_DEBUG__
      __FB_DOS__
      __FB_ERR__
      __FB_FPMODE__
      __FB_FPU__
      __FB_FREEBSD__
      __FB_GCC__
      __FB_GUI__
      __FB_LANG__
      __FB_LINUX__
      __FB_MAIN__
      __FB_MIN_VERSION__
      __FB_MT__
      __FB_NETBSD__
      __FB_OPENBSD__
      __FB_OPTION_BYVAL__
      __FB_OPTION_DYNAMIC__
      __FB_OPTION_ESCAPE__
      __FB_OPTION_EXPLICIT__
      __FB_OPTION_GOSUB__
      __FB_OPTION_PRIVATE__
      __FB_OUT_DLL__
      __FB_OUT_EXE__
      __FB_OUT_LIB__
      __FB_OUT_OBJ__
      __FB_PCOS__
      __FB_SIGNATURE__
      __FB_SSE__
      __FB_UNIX__
      __FB_VECTORIZE__
      __FB_VER_MAJOR__
      __FB_VER_MINOR__
      __FB_VER_PATCH__
      __FB_VERSION__
      __FB_WIN32__
      __FB_XBOX__
      __FILE__
      __FILE_NQ__
      __FUNCTION__
      __FUNCTION_NQ__
      __LINE__
      __PATH__
      __TIME__

   #
      #assert
      #define
      #else
      #elseif
      #endif
      #endmacro
      #error
      #if
      #ifdef
      #ifndef
      #inclib
      #include
      #lang
      #libpath
      #line
      #macro
      #pragma
      #print
      #undef

   $
      $Dynamic
      $Include
      $Lang
      $Static

   ?
      ? (Shortcut For 'Print')
      ? # (Shortcut For 'Print #')
      ? Using (Shortcut For 'Print Using')

   A
      Abs
      Abstract (Member)
      Access
      Acos
      Add (Graphics Put)
      Alias (Name)
      Alias (Modifier)
      Allocate
      Alpha (Graphics Put)
      And
      AndAlso
      And (Graphics Put)
      Any
      Append
      As
      Asc
      Asin
      Asm
      Assert
      AssertWarn
      Atan2
      Atn

   B
      Base (Initialization)
      Base (Member Access)
      Beep
      Bin
      Binary
      Bit
      BitReset
      BitSet
      BLoad
      Boolean
      BSave
      Byref (Parameters)
      Byref (Function Results)
      Byref (Variables)
      Byte
      ByVal

   C
      Call
      CAllocate
      Case
      Cast
      CBool
      CByte
      CDbl
      cdecl
      Chain
      ChDir
      Chr
      CInt
      Circle
      Class
      Clear
      CLng
      CLngInt
      Close
      Cls
      Color
      Command
      Common
      CondBroadcast
      CondCreate
      CondDestroy
      CondSignal
      CondWait
      Const
      Const (Member)
      Const (Qualifier)
      Constructor
      Constructor (Module)
      Continue
      Cos
      CPtr
      CShort
      CSign
      CSng
      CsrLin
      CUByte
      CUInt
      CULng
      CULngInt
      CUnsg
      CurDir
      CUShort
      Custom (Graphics Put)
      Cva_Arg
      Cva_Copy
      Cva_End
      Cva_List
      Cva_Start
      CVD
      CVI
      CVL
      CVLongInt
      CVS
      CVShort

   D
      Data
      Date
      DateAdd
      DateDiff
      DatePart
      DateSerial
      DateValue
      Day
      Deallocate
      Declare
      DefByte
      DefDbl
      defined
      DefInt
      DefLng
      DefLongInt
      DefShort
      DefSng
      DefStr
      DefUByte
      DefUInt
      Defulongint
      DefUShort
      Delete (Statement)
      Destructor
      Destructor (Module)
      Dim
      Dir
      Do
      Do...Loop
      Double
      Draw
      Draw String
      DyLibFree
      DyLibLoad
      DyLibSymbol

   E
      Else
      ElseIf
      Encoding
      End (Block)
      End (Statement)
      End If
      Enum
      Environ Statement
      Environ
      EOF
      Eqv
      Erase
      Erfn
      Erl
      Ermn
      Err
      Error
      Event (Message Data From Screenevent)
      Exec
      ExePath
      Exit
      Exp
      Export
      Extends
      Extends Wstring
      Extends Zstring
      Extern
      Extern...End Extern

   F
      False
      Field
      FileAttr
      FileCopy
      FileDateTime
      FileExists
      FileLen
      Fix
      Flip
      For
      For...Next
      Format
      Frac
      Fre
      FreeFile
      Function
      Function (Member)
      Function (Pointer)

   G
      Get (Graphics)
      Get # (File I/O)
      GetJoystick
      GetKey
      GetMouse
      GoSub
      Goto

   H
      Hex
      HiByte
      HiWord
      Hour

   I
      If...Then
      IIf
      ImageConvertRow
      ImageCreate
      ImageDestroy
      ImageInfo
      Imp
      Implements
      Import
      Inkey
      Inp
      Input (Statement)
      Input (File I/O)
      Input #
      Input$
      InStr
      InStrRev
      Int
      Integer
      Is (Select Case)
      Is (Run-Time Type Information Operator)
      IsDate
      IsRedirected

   K
      Kill

   L
      LBound
      LCase
      Left
      Len
      Let
      Lib
      Line
      Line Input
      Line Input #
      LoByte
      LOC
      Local
      Locate
      Lock
      LOF
      Log
      Long
      LongInt
      Loop
      LoWord
      LPos
      LPrint
      LSet
      LTrim

   M
      Mid (Statement)
      Mid (Function)
      Minute
      MKD
      MkDir
      MKI
      MKL
      MKLongInt
      MKS
      MKShort
      Mod
      Month
      MonthName
      MultiKey
      MutexCreate
      MutexDestroy
      MutexLock
      MutexUnlock

   N
      Naked
      Name
      Namespace
      New (Expression)
      New (Placement)
      Next
      Next (Resume)
      Not
      Now

   O
      Object
      Oct
      OffsetOf
      On Error
      On...Gosub
      On...Goto
      Once
      Open
      Open Com
      Open Cons
      Open Err
      Open Lpt
      Open Pipe
      Open Scrn
      Operator
      Option()
      Option Base
      Option ByVal
      Option Dynamic
      Option Escape
      Option Explicit
      Option Gosub
      Option Nogosub
      Option NoKeyword
      Option Private
      Option Static
      Or
      Or (Graphics Put)
      OrElse
      Out
      Output
      Overload
      Override

   P
      Paint
      Palette
      pascal
      PCopy
      Peek
      PMap
      Point
      PointCoord
      Pointer
      Poke
      Pos
      Preserve
      PReset
      Print
      Print #
      Print Using
      Private
      Private: (Access Control)
      ProcPtr
      Property
      Protected: (Access Control)
      Pset (Statement)
      Pset (Graphics Put)
      Ptr (Shortcut For 'Pointer')
      Public
      Public: (Access Control)
      Put (Graphics)
      Put # (File I/O)

   R
      Random
      Randomize
      Read
      Read (File Access)
      Read Write (File Access)
      Reallocate
      ReDim
      Rem
      Reset
      Restore
      Resume
      Resume Next
      Return
      RGB
      RGBA
      Right
      RmDir
      Rnd
      RSet
      RTrim
      Run

   S
      SAdd
      Scope
      Screen
      Screen (Console)
      ScreenCopy
      ScreenControl
      ScreenEvent
      ScreenGLProc
      ScreenInfo
      ScreenList
      ScreenLock
      ScreenPtr
      ScreenRes
      ScreenSet
      ScreenSync
      ScreenUnlock
      Second
      Seek (Statement)
      Seek (Function)
      Select Case
      SetDate
      SetEnviron
      SetMouse
      SetTime
      Sgn
      Shared
      Shell
      Shl
      Short
      Shr
      Sin
      Single
      SizeOf
      Sleep
      Space
      Spc
      Sqr
      Static
      Static (Member)
      stdcall
      Step
      Stick
      Stop
      Str
      Strig
      String (Function)
      String
      StrPtr
      Sub
      Sub (Member)
      Sub (Pointer)
      Swap
      System

   T
      Tab
      Tan
      Then
      This
      ThreadCall
      ThreadCreate
      ThreadDetach
      ThreadWait
      Time
      Timer
      TimeSerial
      TimeValue
      To
      Trans (Graphics Put)
      Trim
      True
      Type (Alias)
      Type (Temporary)
      Type (Udt)
      TypeOf

   U
      UBound
      UByte
      UCase
      UInteger
      ULong
      ULongInt
      Union
      Unlock
      Unsigned
      Until
      UShort
      Using (Print)
      Using (Namespaces)

   V
      va_arg
      va_first
      va_next
      Val
      ValLng
      ValInt
      ValUInt
      ValULng
      Var
      VarPtr
      View Print
      View (Graphics)
      Virtual (Member)

   W
      Wait
      WBin
      WChr
      Weekday
      WeekdayName
      Wend
      While
      While...Wend
      WHex
      Width
      Window
      WindowTitle
      WInput
      With
      WOct
      Write
      Write #
      Write (File Access)
      WSpace
      WStr
      Wstring (Data Type)
      Wstring (Function)

   X
      Xor
      Xor (Graphics Put)

   Y
      Year

   Z
      ZString
   Operator List

   Variables and Data Types
      Variable Declarations
      User Defined Types
      Standard Data Types
      Standard Data Type Limits
      Converting Between Data Types

   Assignment operators
      Operator =[>] (Assignment)
      Operator &= (Concatenate And Assign)
      Operator += (Add And Assign)
      Operator -= (Subtract And Assign)
      Operator *= (Multiply And Assign)
      Operator /= (Divide And Assign)
      Operator \= (Integer Divide And Assign)
      Operator ^= (Exponentiate And Assign)
      Operator Let (Assignment)
      Operator Let() (Assignment)
      Operator Mod= (Modulus And Assign)
      Operator And= (Conjunction And Assign)
      Operator Eqv= (Equivalence And Assign)
      Operator Imp= (Implication And Assign)
      Operator Or= (Inclusive Disjunction And Assign)
      Operator Xor= (Exclusive Disjunction And Assign)
      Operator Shl= (Shift Left And Assign)
      Operator Shr= (Shift Right And Assign)

   Arithmetic operators
      Operator + (Add)
      Operator - (Subtract)
      Operator * (Multiply)
      Operator / (Divide)
      Operator \ (Integer Divide)
      Operator ^ (Exponentiate)
      Operator Mod (Modulus)
      Operator - (Negate)
      Operator Shl (Shift Left)
      Operator Shr (Shift Right)

   Conditional operators
      Operator = (Equal)
      Operator <> (Not Equal)
      Operator < (Less Than)
      Operator <= (Less Than Or Equal)
      Operator >= (Greater Than Or Equal)
      Operator > (Greater Than)
      Operator Is (Run-Time Type Information)

   Logical operators
      Operator And (Conjunction)
      Operator Eqv (Equivalence)
      Operator Imp (Implication)
      Operator Not (Complement)
      Operator Or (Inclusive Disjunction)
      Operator Xor (Exclusive Disjunction)

   Short circuit operators
      Operator Andalso (Short Circuit Conjunction)
      Operator Orelse (Short Circuit Inclusive Disjunction)

   Indexing operators
      Operator () (Array Index)
      Operator [] (String Index)
      Operator [] (Pointer Index)

   String operators
      Operator + (String Concatenation)
      Operator & (String Concatenation With Conversion)
      Operator Strptr (String Pointer)

   Preprocessor operators
      Operator # (Stringize)
      Operator ## (Concatenation)
      Operator ! (Escaped String Literal)
      Operator $ (Non-Escaped String Literal)

   Pointer operators
      Operator Varptr (Variable Pointer)
      Operator Strptr (String Pointer)
      Operator Procptr (Procedure Pointer)
      Operator @ (Address Of)
      Operator * (Value Of)

   Type or Class operators
      Operator . (Member Access)
      Operator -> (Pointer To Member Access)
      Operator Is (Run-Time Type Information)

   Memory operators
      Operator New Expression
      Operator New Overload
      Operator Placement New
      Operator Delete Statement
      Operator Delete Overload

   Iterating operators
      Operator For
      Operator Step
      Operator Next
      Operator Precedence
      Bitwise Operators & Truth Tables

   Statements
      Control Flow
      Procedures
      Modularizing

   Other
      Preprocessor
      Escape Sequences In String Literals
      Meta-statements
      Intrinsic Defines
      Error Handling
      Inline Asm

Runtime Library Reference
   Array Functions
   Bit Manipulation
   Console Functions
   Date and Time Functions
   Error Handling Functions
   File IO Functions
   Mathematical Functions
   Memory Functions
   Operating System Functions
   String Functions
   Threading Support Functions
   User Input Functions

Graphics Library Reference
   2D Drawing Functions
   User Input Functions
   Screen Functions
   Supported graphics drivers (backends)
   Keyboard Scan Codes
   Default Palettes

Tutorials

   Getting Started
      Hello World
      FreeBASIC Primer #1

   Source Files
      Source Files (.bas)
      Header Files (.bi)
      Using Prebuilt Libraries

   Lexical Conventions
      Comments
      Identifier Rules
      Literals
      Labels
      Line continuation

   Variables and Datatypes
      Coercion and Conversion
      Constants
      Variables

      Arrays
         Overview
         Fixed-length Arrays
         Variable-length Arrays
         Array Indexing
         Passing Arrays to Procedures

      Pointers
         Overview
         Pointer Arithmetic

   Declarations
      Implicit Declarations
      Initialization
      Storage Classes
      Variable Scope
      Simple Variable Lifetime vs Scope
      Dynamic Object and Data Lifetime
      Namespaces
      Variable and Procedure Linkage

   User Defined Types
      Overview
      Type Aliases
      Temporary Types
      Constructors and Destructors
      Member Procedures
      Properties
      Member Access Rights
      Operator Overloading
      Iterators
      New and Delete
      Types as Objects

   Statements and Expressions
      Operator Precedence
      Control Flow Statements

   Procedures
      Procedures Overview
      Passing Arguments to Procedures
      Returning a Value
      Calling Conventions
      Recursion
      Pointers to Procedures
      Variable Arguments

   Making Binaries
      Static Libraries
      Shared Libraries (DLLs)
      Profiling

   Preprocessor

   Other Topics
      ASCII
      Date Serials
      Radians
      FreeBASIC GfxLib overview
      Internal Graphics Formats
      Inline Asm
      Error Handling
      Intrinsic Defines
      C Standard Library Functions
      File I/O in FreeBASIC
   Community Tutorials
   Community Code Library

External Libraries Index

   Graphical/test-based user interfaces
      CGUI
      Curses
      GTK+
      IUP
      wxC
      Windows API
      X11

   Graphics
      Allegro
      DUGL
      caca
      Cairo
      DISLIN
      freeglut
      FreeImage
      Freetype2
      GD
      GIFLIB
      GLUT
      GLFW
      GRX
      IL (DevIL)
      japi
      jpeglib
      JPGalleg
      libpng
      OpenGL
      PDFlib
      SDL
      TinyPTC

   Music/Sound, Audio/Video
      BASS
      BASSMOD
      Flite
      FMOD
      MediaInfo
      mpg123
      Ogg
      OpenAL
      PortAudio
      sndfile
      VLC
      Vorbis

   Database
      GDBM
      MySQL
      PostgreSQL
      SQLite

   Development Helpers
      CUnit
      GDSL
      gettext (includes libintl)
      GNU ASpell
      libbfd

   Embeddable Languages
      JNI
      json-c
      libffi
      libjit
      Lua
      SpiderMonkey

   Cryptography
      cryptlib
      UUID

   Mathematics
      big_int
      Chipmunk
      GMP
      GSL
      Newton
      ODE

   Networking
      cgi-util
      curl
      FastCGI
      ZeroMQ

   eXtensible Markup Language (XML)
      Expat
      libxml
      libxslt
      Mini-XML

   Regular Expressions
      PCRE
      TRE

   Compression
      bzip2
      libzip
      liblzma
      LZO
      QuickLZ
      zlib

   System APIs
      C Runtime Library
      DOS API
      disphelper
      GLib
      Windows API
      X11

Using the FreeBASIC compiler
   Installing FreeBASIC
   Requirements
   Running FreeBASIC
   Using the Command Line

   Command Line Options
      @< file >
      -a < name >
      -arch < type >
      -asm < format >
      -b < name >
      -c
      -C
      -d < name=val >
      -dll
      -dylib
      -e
      -earray
      -eassert
      -edebug
      -edebuginfo
      -elocation
      -enullptr
      -ex
      -exx
      -export
      -forcelang <name>
      -fpmode < type >
      -fpu < type >
      -g
      -gen < backend >
      -i < name >
      -include < name >
      -l < name >
      -lang < name >
      -lib
      -m < name >
      -map < name >
      -maxerr < val >
      -mt
      -nodeflibs
      -noerrline
      -noobjinfo
      -nostrip
      -o < name >
      -O < level >
      -p < name >
      -pic
      -pp
      -prefix < path >
      -print < option >
      -profile
      -r
      -R
      -rr
      -RR
      -s < name >
      -showincludes
      -static
      -strip
      -t < value >
      -target < platform >
      -v
      -vec < level >
      -version
      -w < value >
      -Wa < opt >
      -Wc < opt >
      -Wl < opt >
      -x < name >
      -z < value >
   Debugging with FreeBASIC
   Compiler Error Messages
   Tools used by fbc
   Installing gcc for -gen gcc

FreeBASIC dialects and QBASIC
   FreeBASIC and Qbasic
   Differences from QB
   FreeBASIC Dialects

FAQs
   Compiler FAQ
   Graphics Library FAQ
   Runtime Library FAQ
   Xbox port FAQ
   DOS related FAQ
   Windows related FAQ
   Linux related FAQ

Miscellaneous
   Obsolete Keywords
   Glossary
   Miscellaneous Keywords
   C Standard Library Functions
   ASCII Character Codes
   Runtime Error Codes
   C/C++ vs. FreeBASIC syntax comparison
   C/C++ vs. FreeBASIC integer data type comparison

Hacking on FreeBASIC
   Developer's Table of Contents

------------------------------------------------------- CompilerWelcome ----
Welcome to FreeBASIC

Welcome to our world!  This page is an overview of our online warehouse of 
knowledge.  Enjoy your surfing and we hope this will be the first of many 
visits.

Introduction
   FreeBASIC is a free, BASIC compiler for Windows (32-bit and 64-bit), 32 
   bit protected-mode DOS (COFF executables, like DJGPP), and Linux (x86, 
   x86_64, and ARM).  It is open source and licensed under the GPL. It is 
   designed to be syntax compatible with QuickBASIC, while expanding on the 
   language and capabilities. It can create programs for MS-Windows, DOS 
   and Linux, and is being ported to other platforms. See About FreeBASIC 
   and Main Features.

Latest Version
   FreeBASIC is a beta release compiler and development is ongoing.  With 
   each full update, many features are added, and bugs from previous 
   releases are fixed.  To see the latest version available, visit 
   the News section on the forum.

Requirements and Installation
   Minimum hardware is listed on the Requirements page.  Visit our 
   Installation page for setting up FreeBASIC on your computer.

Running
   FreeBASIC is a compiler and as such is not packaged with an IDE 
   (Integrated Development Editor), although there are a few IDE's 
   available. For information on using FreeBASIC without an IDE, see Running
   .

Compatibility with QuickBASIC
   FreeBASIC is designed to be syntax compatible with QuickBASIC.  For best 
   code-compatibility with QuickBASIC, the QB dialect can be used when 
   compiling source code. See FreeBASIC Dialects and Differences from QB.

Documentation
   All official documentation can be found online in the wiki at 
   https://www.freebasic.net/wiki.  The online documentation is the most 
   up-to-date resource available.  In all cases it can be regarded as the 
   correct version.  The downloadable versions of the manual are snapshots 
   of the documentation available at a particular time and should be mostly 
   correct for a specific released version of the compiler.  However, we do 
   not maintain multiple versions of the documentation so there may be some 
   discrepancies.

Starting points in the Manual
   * Table of Contents
   * Getting Help with FreeBASIC
   * Programmer's Guide

Starting points on the Web
   * Official Website at https://www.freebasic.net
   * Official Forums at https://www.freebasic.net/forum

Thank you for using FreeBASIC.  Happy coding!



---------------------------------------------------------- CompilerHelp ----
Getting help with FreeBASIC

There are several options available for getting help with FreeBASIC.

The Manual
   This huge user's manual is full of information that can help you learn 
   to write programs using FreeBASIC.  

   The manual is available online at https://www.freebasic.net/wiki.  There 
   is a search box at the top of every page to help you find what you're 
   looking for.

   If you are unfamiliar with FreeBASIC or the documentation, you may find 
   these pages a good place to start:
      * Table of Contents
      * Programmer's Guide
      * Library Headers Index
      * Glossary
      * Compiler FAQ
      * Graphics Library FAQ
      * Runtime Library FAQ

   A downloadable manual (in CHM format) is available from the sourceforge 
   project page at https://sourceforge.net/projects/fbc which features a 
   full table of contents, searching capabilities, an index, plus all the 
   same content as the online version.

   Searching the manual on or offline is an excellent place to start 
   finding help about how to write and use FreeBASIC programs.

Examples and Source Code
   In the ./examples directory located where FreeBASIC was installed on 
   your system are hundreds of examples to be compiled and run.  Most of 
   the external library examples will need additional libraries to be 
   downloaded to allow them to work.  See Library Headers Index for a full 
   list.

Tutorials
   Community created tutorials about FreeBASIC can be found at 
   CommunityTutorials.  Some selected tutorials are included in this 
   manual.

FreeBASIC Forum
   An active community forum can be found at https://www.freebasic.net/forum
   with several sub-forums.  The forum has a search feature that can help 
   you find answers to questions or problems that may have already been 
   asked and solved.  First do a search for your problem, if you can't find 
   the answer then post a message in one of the sub-forums.

Chat
   IRC or Internet Relay Chat is a great way to chat with the developers 
   and other users, some of whom are very knowledgeable.  There are several 
   ways to connect to IRC, if you know what you're doing simply join 
   #freebasic on FreeNode.

   If you haven't the foggiest what IRC is and you have Java installed, you 
   can simply go here.

   If you're trying to get help, the most important thing is to be patient. 
   Sometimes you won't get a reply right away. Stick around or check back 
   and the Community will try and assist you.





============================================================================
  LANGUAGE DOCUMENTATION
  ----------------------



============================================================================
    .

------------------------------------------------------------- KeyPgDots ----
... (Ellipsis)

Used in place of procedure parameter to pass a variable number of 
arguments, or as the upper bound in an array declaration to denote that the 
number of elements will be determined by the initializer.

Syntax
   Declare { Sub | Function } proc_name cdecl ( param_list, ... )  { | [ 
   ByRef ] As return_type }

   #define identifier( [ parameters, ] variadic_parameter... ) body

   Dim array_symbol ([lbound To] ...) [As datatype] => { expression_list }

Description
   Variadic Procedures

   The ellipsis (three dots, ...) is used in procedure declarations and 
   definitions to indicate a variable argument list.

   A first argument (at least) must always be specified and the procedure 
   must be called with the C calling convention cdecl.

   In the procedure body, Cva_List data type, and Cva_Arg marco can be used 
   to expand the ellipsis parameter (...) to obtain the values of the 
   arguments passed to the variadic procedure.  The argument list, once 
   initialized with Cva_Start or copied with Cva_Copy, can be passed to 
   another procedure taking a Cva_List parameter.

   On some targets, for backwards compatibility, va_first, va_arg and 
   va_next can still be used to handle the variable arguments.

   Only numeric types and pointers are supported as variable arguments (all 
   bytes and shorts passed on variable arguments are implicitly converted 
   to integers, all singles passed on variable arguments are implicitly 
   converted to doubles).  Strings can be passed, in which case a ZString 
   Ptr to the string data is taken.

   A variadic procedure name can never be overloaded.

   Variadic Macros

   Using an ellipsis behind the last parameter in a #define or #macro 
   declaration allows creation of a variadic macro. This means it is 
   possible to pass any number of arguments to the variadic_parameter, 
   which can be used in the body as if it was a normal macro parameter. The 
   variadic_parameter will expand to the full list of arguments passed to 
   it, including commas, and can also be completely empty.

   Note: To distinguish between the different arguments passed by 
   variadic_parameter, you can first convert variadic_parameter to a string 
   using the Operator # (Preprocessor Stringize), then differentiate in 
   this string (#variadic_parameter) each passed argument by locating the 
   separators (usually a comma).

   Array Upper Bound

   Using an ellipsis in place of the upper bound in an array declaration 
   causes the upper bound to be set according to the data that appears in 
   the expression_list.  When the ellipsis is used in this manner, an 
   initializer must appear, and cannot be Any.

Example
   Declare Function foo cdecl (x As Integer, ...) As Integer

   Dim As Integer myarray(0 To ...) = {0, 1, 2, 3}
   Print LBound(myarray), UBound(myarray)   '' 0, 3

   '' Using a variadic macro to wrap a variadic function
   #include "crt.bi"
   #define eprintf(Format, args...) fprintf(stderr, Format, args)
   eprintf(!"Hello from printf: %i %s %i\n", 5, "test", 123)

   '' LISP-like accessors allowing to modify comma-separated lists
   #define car(a, b...) a
   #define cdr(a, b...) b

Differences from QB
   * New to FreeBASIC

See also
   * cdecl
   * Cva_List
   * Cva_Arg
   * va_arg
   * va_first
   * va_next
   * Dim
   * Static
   * #define




============================================================================
    _

----------------------------------------------------------- KeyPgDddate ----
__DATE__

Intrinsic define (macro value) set by the compiler

Syntax
   __DATE__

Description
   Substitutes the compiler date in a literal string ("mm-dd-yyyy" format) 
   where used.

Example
   Print "Compile Date: " & __DATE__


   Compile Date: 09-29-2011

Differences from QB
   * New to FreeBASIC

See also
   * __DATE_ISO__
   * __TIME__
   * Date



-------------------------------------------------------- KeyPgDddateiso ----
__DATE_ISO__

Intrinsic define (macro value) set by the compiler

Syntax
   __DATE_ISO__

Description
   Substitutes the compiler date in a literal string ("yyyy-mm-dd" format) 
   where used.  This format is in line with ISO 8601 and can be used for 
   lexicographical date comparisons.

Example
   Print "Compile Date: " & __DATE_ISO__

   If __DATE_ISO__ < "2011-12-25" Then
      Print "Compiled before Christmas day 2011"
   Else
      Print "Compiled after Christmas day 2011"
   End If


   Compile Date: 2011-09-29
   Compiled before Christmas Day 2011

Differences from QB
   * New to FreeBASIC

See also
   * __DATE__
   * __TIME__
   * Date



-------------------------------------------------------- KeyPgDdfb64bit ----
__FB_64BIT__

Intrinsic define set by the compiler

Syntax
   __FB_64BIT__

Description
   Define created at compile time if the the compilation target is 64bit, 
   otherwise undefined.

Example
   #ifdef __FB_64BIT__
     '...instructions for 64bit OSes...
   #else
     '...instructions for other OSes
   #endif 

Differences from QB
   * New to FreeBASIC

See also
   * __FB_LINUX__
   * __FB_FREEBSD__
   * __FB_OPENBSD__
   * __FB_NETBSD__
   * __FB_CYGWIN__
   * __FB_DARWIN__
   * __FB_PCOS__
   * Compiler Option: -target



--------------------------------------------------------- KeyPgDdfbargc ----
__FB_ARGC__

Intrinsic define (macro value) set by the compiler

Syntax
   __FB_ARGC__

Description
   Substituted with the number of arguments passed in on the command line.

   __FB_ARGC__ is the name of a parameter passed to the program's implicit 
   main function, and therefore is only defined in the module level code of 
   the main module for an application.

Example
   Dim i As Integer
   For i = 0 To __FB_ARGC__ - 1
         Print "arg "; i; " = '"; Command(i); "'"
   Next i

Differences from QB
   * New to FreeBASIC

See also
   * __FB_ARGV__
   * Command



--------------------------------------------------------- KeyPgDdfbargv ----
__FB_ARGV__

Intrinsic define (macro value) set by the compiler

Syntax
   __FB_ARGV__

Description
   Substituted with a pointer to a list of pointers to the zero terminated 
   command line arguments passed in on the command line.

   __FB_ARGV__ is the name of a parameter passed to the program's implicit 
   main function, and therefore is only defined in the module level code of 
   the main module for an application.

Example
   Declare Function main _
     ( _
      ByVal argc As Integer, _
      ByVal argv As ZString Ptr Ptr _
     ) As Integer

     End main( __FB_ARGC__, __FB_ARGV__ )

   Private Function main _
     ( _
      ByVal argc As Integer, _
      ByVal argv As ZString Ptr Ptr _
     ) As Integer

     Dim i As Integer
     For i = 0 To argc - 1
         Print "arg "; i; " = '"; *argv[i]; "'"
     Next i

     Return 0

   End Function

Differences from QB
   * New to FreeBASIC

See also
   * __FB_ARGC__
   * Command



---------------------------------------------------------- KeyPgDdfbarm ----
__FB_ARM__

Intrinsic define set by the compiler

Syntax
   __FB_ARM__

Description
   Define created at compile time if the compilation target uses the ARM 
   CPU architecture, otherwise undefined.

Example
   #ifdef __FB_ARM__
     '...instructions for ARM OSes...
   #else
     '...instructions for other OSes
   #endif 

Differences from QB
   * New to FreeBASIC

See also
   * __FB_LINUX__
   * __FB_FREEBSD__
   * __FB_OPENBSD__
   * __FB_NETBSD__
   * __FB_CYGWIN__
   * __FB_DARWIN__
   * __FB_PCOS__
   * Compiler Option: -target



---------------------------------------------------------- KeyPgDdfbasm ----
__FB_ASM__

Intrinsic define set by the compiler

Syntax
   __FB_ASM__

Description
   __FB_ASM__ returns a string equal to "intel" or "att" depending on 
   whether inline assembly blocks should use the Intel format or the 
   GCC/AT&T format.

Example
   Dim a As Long
   #if __FB_ASM__ = "intel"
      Asm
          inc dword Ptr [a]
      End Asm
   #else
      Asm
         "incl %0\n" : "+m" (a) : :
      End Asm
   #endif

Differences from QB
   * New to FreeBASIC

See also
   * Compiler Option: -asm



------------------------------------------------------ KeyPgDdFBBackend ----
__FB_BACKEND__

Intrinsic define set by the compiler

Syntax
   __FB_BACKEND__

Description
   Defined to either "gas" or "gcc", depending on which backend was 
   specified via -gen.

Differences from QB
   * Did not exist in QB



---------------------------------------------------- KeyPgDdFBBigEndian ----
__FB_BIGENDIAN__

Intrinsic define set by the compiler

Syntax
   __FB_BIGENDIAN__

Description
   Define without a value created at compile time if compiling for a big 
   endian target.

   It can be used to compile parts of the program only if the target is big 
   endian.

Example
   #ifdef __FB_BIGENDIAN__
      '...instructions only for big endian machines
   #else
     '...instructions only for little endian machines
   #endif 

Differences from QB
   * Did not exist in QB



---------------------------------------------------- KeyPgDdFBBuildDate ----
__FB_BUILD_DATE__

Intrinsic define (macro string) set by the compiler

Syntax
   __FB_BUILD_DATE__

Description
   Substituted with the quoted string containing the date (MM-DD-YYYY) the 
   compiler was built on.

Example
      Print "This program compiled with a compiler built on this date:" & __FB_BUILD_DATE__

Differences from QB
   * New to FreeBASIC



------------------------------------------------------- KeyPgDdfbcygwin ----
__FB_CYGWIN__

Intrinsic define set by the compiler

Syntax
   __FB_CYGWIN__

Description
   Define without a value created at compile time in the Cygwin version of 
   the compiler, or when the -target cygwin command line option is used. It 
   can be used to compile parts of the program only if the target is 
   Cygwin.

Example
   #ifdef __FB_CYGWIN__
     '...instructions only for Cygwin...
   #else
     '...instructions not for Cygwin...
   #endif 

Differences from QB
   * New to FreeBASIC

See also
   * __FB_LINUX__
   * __Fb_Win32_
   * __FB_UNIX__
   * Compiler Option: -target



------------------------------------------------------- KeyPgDdfbdarwin ----
__FB_DARWIN__

Intrinsic define set by the compiler

Syntax
   __FB_DARWIN__

Description
   Define without a value created at compile time in the Darwin version of 
   the compiler, or when the -target darwin command line option is used. It 
   can be used to compile parts of the program only if the target is 
   Darwin.

Example
   #ifdef __FB_DARWIN__
     '...instructions only for Darwin...
   #else
     '...instructions not for Darwin...
   #endif 

Differences from QB
   * New to FreeBASIC

See also
   * __FB_LINUX__
   * __FB_WIN32__
   * __FB_UNIX__
   * Compiler Option: -target



-------------------------------------------------------- KeyPgDdfbdebug ----
__FB_DEBUG__

Intrinsic define (macro value) set by the compiler

Syntax
   __FB_DEBUG__

Description
   __FB_DEBUG__ indicates if the the generate debug information option -g 
   or the enable intrinsic define __FB_DEBUG__ option 
   Compiler Option: -edebug was specified on the command line at the time 
   of compilation.

   Returns non-zero (-1) if either option was specified.  Returns zero (0) 
   otherwise.

   __FB_ERR__ can be used to determine in user source code if the -g or 
   -edebug option was specified or implied on the command line.

Example
   #if __FB_DEBUG__ <> 0
         #print Debug mode 
   #else 
         #print Release mode 
   #endif

Differences from QB
   * New to FreeBASIC

See also
   * __FB_ERR__
   * __FB_MT__
   * Compiler Option: -edebug
   * Compiler Option: -g



---------------------------------------------------------- KeyPgDdfbdos ----
__FB_DOS__

Intrinsic define set by the compiler

Syntax
   __FB_DOS__

Description
   Define without a value created at compile time if compiling for the DOS 
   target. Default in the DOS hosted version, or active when the -target dos
   command line option is used. It can be used to compile parts of the 
   program only if the target is DOS. Note: the DOS hosted version cannot 
   compile to other targets than DOS by now.

Example
   #ifdef __FB_DOS__
     ' ... instructions only for DOS ...
     ' ... INT 0x31
   #else
     ' ... instructions not for DOS ...
   #endif 

Differences from QB
   * New to FreeBASIC

See also
   * __FB_LINUX__
   * __FB_WIN32__
   * __FB_PCOS__
   * DOS related FAQ
   * Compiler Option: -target



---------------------------------------------------------- KeyPgDdfberr ----
__FB_ERR__

Intrinsic define (macro value) set by the compiler

Syntax
   __FB_ERR__

Description
   __FB_ERR__ indicates if -e, -ex, or -exx was specified on the compiler 
   command line at the time of compilation of a module.

   __FB_ERR__ indicates if -earray, -enullptr, or -elocation was specified 
   on the compiler command line, or implied by use of -exx, at the time of 
   compilation of a module.

   __FB_ERR__ indicates if -edebug, -edebuginfo, or -eassert was specified 
   on the compiler command line, or implied by use of -g, at the time of 
   compilation of a module.

   Returns bit-wise OR of the following values:
         +-----+---------------------------------------------------------+
         |value|description                                              |
         |0    |'-e', '-ex', '-exx' and other error options not specified|
         |1    |'-e' was specified                                       |
         |3    |'-ex' was specified (implies '-e')                       |
         |7    |'-exx' was specified (implies '-e, -exx')                |
         |8    |'-earray' was specified (or implied by '-exx')           |
         |16   |'-enullptr' was specified (or implied by '-exx')         |
         |32   |'-eassert' was specified (or implied by '-g')            |
         |64   |'-edebuginfo' was specified (or implied by '-g')         |
         |128  |'-edebug' was specified (or implied by '-g')             |
         |256  |'-elocation' was specified (or implied by '-exx')        |
         +-----+---------------------------------------------------------+

   __FB_ERR__ is always defined.

Example
   'Example code to demonstrate a use of __FB_ERR__
   Dim err_command_line As UByte
   err_command_line = __FB_ERR__
   Select Case err_command_line
   Case 0
   Print "No Error Checking enabled on the Command Line!"
   Case 1
   Print "Some Error Checking enabled on the Command Line!"
   Case 3
   Print "QBasic style Error Checking enabled on the Command Line!"
   Case 7
   Print "Extreme Error Checking enabled on the Command Line!"
   Case Else
   Print "Some Unknown Error level has been set!"
   End Select

Differences from QB
   * New to FreeBASIC

See also 
   * __FB_MT__
   * __FB_DEBUG__
   * Compiler Option: -e
   * Compiler Option: -ex
   * Compiler Option: -exx
   * Error Handling



------------------------------------------------------- KeyPgDdfbfpmode ----
__FB_FPMODE__

Intrinsic define set by the compiler

Syntax
   __FB_FPMODE__

Description
   Defined as "fast" if SSE fast arithmetics is enabled, or "precise" 
   otherwise.

Example
   #if __FB_FPMODE__ = "fast"
     ' ... instructions for using fast-mode math ...
   #else
     ' ... instructions for using normal math ...
   #endif

Differences from QB
   * New to FreeBASIC

See also
   * Compiler Option: -fpmode



---------------------------------------------------------- KeyPgDdfbfpu ----
__FB_FPU__

Intrinsic define set by the compiler

Syntax
   __FB_FPU__

Description
   Defined as "sse" if SSE floating point arithmetics is enabled, or "x87" 
   otherwise.

Example
   #if __FB_FPU__ = "sse"
     ' ... instructions only for SSE ...
   #else
     ' ... instructions not for SSE ...
   #endif

Differences from QB
   * New to FreeBASIC

See also
   * __FB_SSE__
   * Compiler Option: -fpu



------------------------------------------------------ KeyPgDdfbfreebsd ----
__FB_FREEBSD__

Intrinsic define set by the compiler

Syntax
   __FB_FREEBSD__

Description
   Define without a value created at compile time in the FreeBSD version of 
   the compiler, or when the -target freebsd command line option is used. 
   It can be used to compile parts of the program only if the target is 
   FreeBSD.

Example
   #ifdef __FB_FREEBSD__
     '...instructions only for FreeBSD...
   #else
     '...instructions not for FreeBSD...
   #endif 

Differences from QB
   * New to FreeBASIC

See also
   * __FB_LINUX__
   * __FB_WIN32__
   * __FB_UNIX__
   * Compiler Option: -target



---------------------------------------------------------- KeyPgDdfbgcc ----
__FB_GCC__

Intrinsic define set by the compiler

Syntax
   __FB_GCC__

Description
   Defined to true (-1) if -gen gcc is used, or false (0) otherwise.

Differences from QB
   * Did not exist in QB



---------------------------------------------------------- KeyPgDdfbgui ----
__FB_GUI__

Intrinsic define (macro value) set by the compiler

Syntax
   __FB_GUI__

Description
   __FB_GUI__ indicates if the executable subsystem option '-s gui' was 
   specified on the command line at the time of compilation.

   Returns non-zero (-1) if the executable subsystem option '-s gui' was 
   specified. Returns zero (0) otherwise (no executable subsystem option 
   specified, or executable subsystem option '-s console' specified).

Example
   #if __FB_GUI__ <> 0
         #print Executable subsystem: gui
   #else 
         #print Executable subsystem: console
   #endif

Platform Differences
   * Supported on Windows and Cygwin only.

Differences from QB
   * New to FreeBASIC

See also
   * Compiler Option: -s



--------------------------------------------------------- KeyPgDdfblang ----
__FB_LANG__

Intrinsic define (macro value) set by the compiler

Syntax
   __FB_LANG__

Description
   __FB_LANG__ indicates which language compatibility option was set at the 
   time of compilation of a module.  By default __FB_LANG__ will be set to 
   "fb".  The language compatibility option can be changed using one (or 
   more) of the following methods:
      * -lang command line option
      * -forcelang command line option
      * #lang directive
      * $Lang metacommand

   Returns a lower case string with one of the following values:
         +--------------+----------------------------------------------------------------------------+
         |value         |description                                                                 |
         |''fb''        |FreeBASIC compatibility (default)                                           |
         |''qb''        |QBASIC compatibility                                                        |
         |''fblite''    |FreeBASIC language compatibility, with a more QBASIC-compatible coding style|
         |''deprecated''|FBC version 0.16 compatibility                                              |
         +--------------+----------------------------------------------------------------------------+

   __FB_LANG__ is always defined.

Example
   '' Set option explicit always on

   #ifdef __FB_LANG__
     #if __FB_LANG__ <> "fb"
      Option Explicit
     #endif
   #else
     '' Older version - before lang fb
     Option Explicit
   #endif

Differences from QB
   * New to FreeBASIC

See also 
   * __FB_VERSION__
   * #lang
   * Compiler Option: -lang
   * Compiler Option: -forcelang
   * Compiler Dialects



-------------------------------------------------------- KeyPgDdfblinux ----
__FB_LINUX__

Intrinsic define set by the compiler

Syntax
   __FB_LINUX__

Description
   Define without a value created at compile time when compiling to the 
   Linux target. Default in the Linux hosted version of the compiler, or 
   active when the -target linux command line option is used. It can be 
   used to compile parts of the program only if the target is Linux.

Example
   #ifdef __FB_LINUX__
     ' ... instructions only for Linux ...
     ' ... #libpath "/usr/X11/lib" 
   #else
     ' ... instructions not for Linux ...
   #endif 

Differences from QB
   * New to FreeBASIC

See also
   * __FB_DOS__
   * __FB_WIN32__
   * __FB_UNIX__
   * Compiler Option: -target



--------------------------------------------------------- KeyPgDdFBMain ----
__FB_MAIN__

Intrinsic define set by the compiler

Syntax
   __FB_MAIN__

Description
   __FB_MAIN__ is defined in the main module and not defined in other 
   modules.

   The main module is determined by the compiler as either the first source 
   file listed on the command line or explicitly named using the -m option 
   on the command line.

Example
   #ifdef __FB_MAIN__
     #print Compiling the main module
   #else
     #print Compiling an additional module
   #endif

Differences from QB
   * New to FreeBASIC

See also
   * Compiler Option: -m
   * #ifdef
   * #ifndef



--------------------------------------------------- KeyPgDdFBMinVersion ----
__FB_MIN_VERSION__

Macro function to test minimum compiler version

Syntax
   #define __FB_MIN_VERSION__( major, minor, patch) _
      ((__FB_VER_MAJOR__ > major) or _
      ((__FB_VER_MAJOR__ = major) and ((__FB_VER_MINOR__ > minor) or _
      (__FB_VER_MINOR__ = minor and __FB_VER_PATCH__ >= patch_level))))

Usage
   __FB_MIN_VERSION__( major, minor, patch)

Parameters
   major
      minimum major version to test
   minor
      minimum minor version to test
   patch
      minimum patch version to test

Return Value
   Returns zero (0) if the compiler version is less than the specified 
   version, or non-zero (-1) if the compiler version is greater than or 
   equal to specified version

Description
   __FB_MIN_VERSION__ tests for a minimum version of the compiler.

Example
   #if Not __FB_MIN_VERSION__(0, 18, 2)
       #error fbc must be at least version 0.18.2 To compile This module
   #endif

Differences from QB
   * New to FreeBASIC

See also
   * #if



----------------------------------------------------------- KeyPgDdfbmt ----
__FB_MT__

Intrinsic define (macro value) set by the compiler

Syntax
   __FB_MT__

Description
   __FB_MT__ indicates if the the multithreaded option -mt was specified on 
   the command line at the time of compilation.

   Returns non-zero (-1) if the option was specified.  Returns zero (0) 
   otherwise.

Example
   #if __FB_MT__ 
         #print Using multi-threaded library
   #else
         #print Using Single-threaded library
   #endif

Differences from QB
   * New to FreeBASIC

See also 
   * __FB_DEBUG__
   * Compiler Option: -mt



------------------------------------------------------- KeyPgDdfbnetbsd ----
__FB_NETBSD__

Intrinsic define set by the compiler

Syntax
   __FB_NETBSD__

Description
   Define without a value created at compile time in the NetBSD version of 
   the compiler, or when the -target netbsd command line option is used. It 
   can be used to compile parts of the program only if the target is NetBSD
   .

Example
   #ifdef __FB_NETBSD__
     '...instructions only for NetBSD...
   #else
     '...instructions not for NetBSD...
   #endif 

Differences from QB
   * New to FreeBASIC

See also
   * __FB_LINUX__
   * __FB_WIN32__
   * __FB_UNIX__
   * Compiler Option: -target



------------------------------------------------------ KeyPgDdfbopenbsd ----
__FB_OPENBSD__

Intrinsic define set by the compiler

Syntax
   __FB_OPENBSD__

Description
   Define without a value created at compile time in the OpenBSD version of 
   the compiler, or when the -target openbsd command line option is used. 
   It can be used to compile parts of the program only if the target is 
   OpenBSD.

Example
   #ifdef __FB_OPENBSD__
     '...instructions only for OpenBSD...
   #else
     '...instructions not for OpenBSD...
   #endif 

Differences from QB
   * New to FreeBASIC

See also
   * __FB_LINUX__
   * __FB_WIN32__
   * __FB_UNIX__
   * Compiler Option: -target



-------------------------------------------------- KeyPgDdfboptionbyval ----
__FB_OPTION_BYVAL__

Intrinsic define (macro value) set by the compiler

Syntax
   __FB_OPTION_BYVAL__

Description
   Indicates if parameters to a Function or Sub are passed by reference as 
   with ByRef, or by value as with ByVal by default when the by value / by 
   reference specifier is not explicitly stated.

   __FB_OPTION_BYVAL__ is set to non-zero (-1) if by default parameters are 
   passed value, and zero (0) if by default parameters are passed by 
   reference.

   The default for passing parameters by reference or by value is 
   determined by the -lang command line option used during compilation or 
   usage of Option ByVal in the source file.

Example
   #if( __FB_OPTION_BYVAL__ <> 0 )
     #error Option ByVal must Not be used With This source
   #endif

Differences from QB
   * New to FreeBASIC

See also 
   * ByVal
   * ByRef
   * Option ByVal



------------------------------------------------ KeyPgDdfboptiondynamic ----
__FB_OPTION_DYNAMIC__

Intrinsic define (macro value) set by the compiler

Syntax
   __FB_OPTION_DYNAMIC__

Description
   __FB_OPTION_DYNAMIC__ is defined as true (negative one (-1)) if a recent 
   Option Dynamic statement or '$Dynamic meta-command was issued. 
   Otherwise, it is defined as zero (0).

Example
   #if __FB_OPTION_DYNAMIC__ <> 0
   #error This module must Not use Option Dynamic
   #endif

Differences from QB
   * New to FreeBASIC

See also 
   * Option Dynamic
   * Option Static



------------------------------------------------- KeyPgDdfboptionescape ----
__FB_OPTION_ESCAPE__

Intrinsic define (macro value) set by the compiler

Syntax
   __FB_OPTION_ESCAPE__

Description
   Indicates if by default, string literals are processed for escape 
   characters when not explicitly prefixed with the $ Operator for 
   non-escaped strings, or the ! Operator for escaped strings.

   The default method for processing string literals is set by usage of the 
   -lang command line option during compilation or usage of Option Escape 
   in the source file.

   __FB_OPTION_ESCAPE__ returns zero (0) if the option has not been set.  
   Returns non-zero (-1) if the option has been set.

Example
   #if( __FB_OPTION_ESCAPE__ <> 0 )
     #error Option Escape must Not be used With This include file
   #endif

Differences from QB
   * New to FreeBASIC

See also 
   * Option Escape



----------------------------------------------- KeyPgDdfboptionexplicit ----
__FB_OPTION_EXPLICIT__

Intrinsic define (macro value) set by the compiler

Syntax
   __FB_OPTION_EXPLICIT__

Description
   __FB_OPTION_EXPLICIT__ indicates if Option Explicit has been used 
   previously in the source.  

   Returns zero (0) if the option has not been set.  Returns non-zero (-1) 
   if the option has been set.

Example
   #if( __FB_OPTION_EXPLICIT__ = 0 )
     #error Option Explicit must used With This module
   #endif

Differences from QB
   * New to FreeBASIC

See also 
   * Dim
   * Option Explicit



-------------------------------------------------- KeyPgDdfboptiongosub ----
__FB_OPTION_GOSUB__

Intrinsic define (macro value) set by the compiler

Syntax
   __FB_OPTION_GOSUB__

Description
   Indicates how GoSub and Return will be handled at compile time. If the 
   option is set (-1) then GoSub is allowed and Return is recognized as 
   return-from-gosub only.  If the option is not set (0) then GoSub is not 
   allowed and Return is recognized as return-from-procedure only.

   This macro value can be changed at compile time.  Option Gosub will set 
   the option (enable gosub support) and Option Nogosub will clear the 
   option (disable gosub support).

   __FB_OPTION_GOSUB__ returns zero (0) if the option has not been set.  
   Returns non-zero (-1) if the option has been set.

Example
   #if( __FB_OPTION_GOSUB__ <> 0 )
      '' turn off gosub support
      Option nogosub
   #endif

Dialect Differences
   * Defaults to -1 in the -lang qb dialect and 0 in all other dialects.

Differences from QB
   * New to FreeBASIC

See also 
   * Option Gosub
   * Option Nogosub



------------------------------------------------ KeyPgDdfboptionprivate ----
__FB_OPTION_PRIVATE__

Intrinsic define (macro value) set by the compiler

Syntax
   __FB_OPTION_PRIVATE__

Description
    Indicates if by default Function's and Sub's have module scope or 
   global scope when not explicitly specified with Private or Public.

   The default scope specifier for functions and subs is set by usage of 
   the -lang command line option during compilation or usage of 
   Option Private in the source file.

   __FB_OPTION_PRIVATE__ returns zero (0) if the option has not been set.  
   Returns non-zero (-1) if the option has been set.

Example
   #if( __FB_OPTION_PRIVATE__ <> 0 )
     #error Option Private must Not be used With This module
   #endif

Differences from QB
   * New to FreeBASIC

See also 
   * Option Private
   * Private
   * Public



------------------------------------------------------- KeyPgDdfboutdll ----
__FB_OUT_DLL__

Intrinsic define (macro value) set by the compiler

Syntax
   __FB_OUT_DLL__

Description
   __FB_OUT_DLL__ indicates that the specified output file type on the 
   compiler command line at the time of compilation is a shared library.

   Returns non-zero (-1) if the output is a shared library.  Returns zero 
   (0) otherwise.

   Only one of __FB_OUT_DLL__, __FB_OUT_EXE__, __FB_OUT_LIB__, or 
   __FB_OUT_OBJ__ will evaluate to non-zero (-1).  All others will evaluate 
   to zero (0).

Example
   #if __FB_OUT_DLL__ 
         '... specific instructions when making a shared library (DLL)
   #else
         '... specific instructions when not making a shared library (DLL)
   #endif   

Differences from QB
   * New to FreeBASIC

See also 
   * __FB_OUT_EXE__
   * __FB_OUT_LIB__
   * __FB_OUT_OBJ__
   * Compiler Option: -dll



------------------------------------------------------- KeyPgDdfboutexe ----
__FB_OUT_EXE__

Intrinsic define (macro value) set by the compiler

Syntax
   __FB_OUT_EXE__

Description
   __FB_OUT_EXE__ indicates that the specified output file type on the 
   compiler command line at the time of compilation is an executable.

   Returns non-zero (-1) if the output is an executable.  Returns zero (0) 
   otherwise.

   Only one of __FB_OUT_DLL__, __FB_OUT_EXE__, __FB_OUT_LIB__, or 
   __FB_OUT_OBJ__ will evaluate to non-zero (-1).  All others will evaluate 
   to zero (0).

Example
   #if __FB_OUT_EXE__ 
         '... specific instructions when making an executable
   #else
         '... specific instructions when not making an executable
   #endif

Differences from QB
   * New to FreeBASIC

See also 
   * __FB_OUT_DLL__
   * __FB_OUT_LIB__
   * __FB_OUT_OBJ__



------------------------------------------------------- KeyPgDdfboutlib ----
__FB_OUT_LIB__

Intrinsic define (macro value) set by the compiler

Syntax
   __FB_OUT_LIB__

Description
   __FB_OUT_LIB__ indicates that the specified output file type on the 
   compiler command line at the time of compilation is a static library.

   Returns non-zero (-1) if the output is a static library.  Returns zero 
   (0) otherwise.

   Only one of __FB_OUT_DLL__, __FB_OUT_EXE__, __FB_OUT_LIB__, or 
   __FB_OUT_OBJ__ will evaluate to non-zero (-1).  All others will evaluate 
   to zero (0).

Example
   #if __FB_OUT_LIB__ 
         '... specific instructions when making a static library
   #else
         '... specific instructions when not making a static library
   #endif

Differences from QB
   * New to FreeBASIC

See also 
   * __FB_OUT_EXE__
   * __FB_OUT_DLL__
   * __FB_OUT_OBJ__
   * Compiler Option: -lib



------------------------------------------------------- KeyPgDdfboutobj ----
__FB_OUT_OBJ__

Intrinsic define (macro value) set by the compiler

Syntax
   __FB_OUT_OBJ__

Description
   __FB_OUT_OBJ__ indicates that the specified output file type on the 
   compiler command line at the time of compilation is an object module.

   Returns non-zero (-1) if the output is an object module.  Returns zero 
   (0) otherwise.

   Only one of __FB_OUT_DLL__, __FB_OUT_EXE__, __FB_OUT_LIB__, or 
   __FB_OUT_OBJ__, will evaluate to non-zero (-1).  All others will 
   evaluate to zero (0).

Example
   #if __FB_OUT_OBJ__ 
         '... specific instructions when compiling to an object file only
   #else
         '... specific instructions when not compiling to an object file only
   #endif

Differences from QB
   * New to FreeBASIC

See also 
   * __FB_OUT_EXE__
   * __FB_OUT_DLL__
   * __FB_OUT_LIB__



--------------------------------------------------------- KeyPgDdfbpcos ----
__FB_PCOS__

Intrinsic define set by the compiler

Syntax
   __FB_PCOS__

Description
   Define created at compile time if the OS has filesystem behavior styled 
   like common PC OSes, e.g. DOS, Windows, OS/2, Symbian OS, possibly 
   others. Drive letters, backslashes, that stuff, otherwise undefined.

Example
   #ifdef __FB_PCOS__
     '...instructions for PC-ish OSes...
   #else
     '...instructions for other OSes
   #endif 

Differences from QB
   * New to FreeBASIC

See also
   * __FB_WIN32__
   * __FB_DOS__
   * __FB_XBOX__
   * __FB_UNIX__
   * Compiler Option: -target



---------------------------------------------------- KeyPgDdfbsignature ----
__FB_SIGNATURE__

Intrinsic define (macro string) set by the compiler

Syntax
   __FB_SIGNATURE__

Description
   Substituted by a signature of the compiler where used.

Example
   Print __FB_SIGNATURE__


   FreeBASIC 0.21.1

Differences from QB
   * New to FreeBASIC

See also
   * __FB_VERSION__
   * __FB_WIN32__
   * __FB_LINUX__
   * __FB_DOS__



---------------------------------------------------------- KeyPgDdfbsse ----
__FB_SSE__

Intrinsic define set by the compiler

Syntax
   __FB_SSE__

Description
   Define without a value created at compile time if SSE floating point 
   arithmetics is enabled.

Example
   #ifdef __FB_SSE__
     ' ... instructions only for SSE ...
   #else
     ' ... instructions not for SSE ...
   #endif

Differences from QB
   * New to FreeBASIC

See also
   * __FB_FPU__
   * Compiler Option: -fpu



--------------------------------------------------------- KeyPgDdfbunix ----
__FB_UNIX__

Intrinsic define set by the compiler

Syntax
   __FB_UNIX__

Description
   Define created at compile time if the OS is reasonably enough like UNIX 
   that you can call it UNIX, otherwise undefined.

Example
   #ifdef __FB_UNIX__
     '...instructions for UNIX-family OSes...
   #else
     '...instructions for other OSes
   #endif 

Differences from QB
   * New to FreeBASIC

See also
   * __FB_LINUX__
   * __FB_FREEBSD__
   * __FB_OPENBSD__
   * __FB_NETBSD__
   * __FB_CYGWIN__
   * __FB_DARWIN__
   * __FB_PCOS__
   * Compiler Option: -target



---------------------------------------------------- KeyPgDdfbvectorize ----
__FB_VECTORIZE__

Intrinsic define set by the compiler

Syntax
   __FB_VECTORIZE__

Description
   Defined as the vectorisation level number set by the -vec command-line 
   option.

Example
   #if __FB_VECTORIZE__ = 2
     ' ... instructions only for vectorization level 2...
   #else
     ' ...
   #endif

Differences from QB
   * New to FreeBASIC

See also
   * Compiler Option: -vec



----------------------------------------------------- KeyPgDdFBVerMajor ----
__FB_VER_MAJOR__

Intrinsic define (macro value) set by the compiler

Syntax
   __FB_VER_MAJOR__

Description
   __FB_VER_MAJOR__ will return the major version of FreeBASIC currently 
   being used.  For example, the major version is 0 for FreeBASIC 0.90, and 
   will remain 0 until FreeBASIC version 1.0 is released.

Example
   Dim fbMajorVersion As Integer
   Dim fbMinorVersion As Integer
   Dim fbPatchVersion As Integer

   fbMajorVersion = __FB_VER_MAJOR__
   fbMinorVersion = __FB_VER_MINOR__
   fbPatchVersion = __FB_VER_PATCH__

   Print "Welcome to FreeBASIC " & fbMajorVersion & "." & fbMinorVersion & "." & fbPatchVersion

Differences from QB
   * New to FreeBASIC

See also
   * __FB_VER_MINOR__
   * __FB_VER_PATCH__



----------------------------------------------------- KeyPgDdFBVerMinor ----
__FB_VER_MINOR__

Intrinsic define (macro value) set by the compiler

Syntax
   __FB_VER_MINOR__

Description
   __FB_VER_MINOR__ will return the minor version of FreeBASIC currently 
   being used. For FreeBASIC version 0.90.1, for example, the minor version 
   number is 90.

Example
   Dim fbMajorVersion As Integer
   Dim fbMinorVersion As Integer
   Dim fbPatchVersion As Integer

   fbMajorVersion = __FB_VER_MAJOR__
   fbMinorVersion = __FB_VER_MINOR__
   fbPatchVersion = __FB_VER_PATCH__

   Print "Welcome to FreeBASIC " & fbMajorVersion & "." & fbMinorVersion & "." & fbPatchVersion

Differences from QB
   * New to FreeBASIC

See also 
   * __FB_VER_MAJOR__
   * __FB_VER_PATCH__



----------------------------------------------------- KeyPgDdFBVerPatch ----
__FB_VER_PATCH__

Intrinsic define (macro value) set by the compiler

Syntax
   __FB_VER_PATCH__

Description
   __FB_VER_PATCH__ will return the patch/subversion/revision number the 
   version of FreeBASIC currently being used. For FreeBASIC 0.18, for 
   example, there were subversions 1, 2, 3, 4, 5 and 6, resulting in 
   versions 0.18.1 through 0.18.6.

Example
   Dim fbMajorVersion As Integer
   Dim fbMinorVersion As Integer
   Dim fbPatchVersion As Integer

   fbMajorVersion = __FB_VER_MAJOR__
   fbMinorVersion = __FB_VER_MINOR__
   fbPatchVersion = __FB_VER_PATCH__

   Print "Welcome to FreeBASIC " & fbMajorVersion & "." & fbMinorVersion & ", revision " & fbPatchVersion

Differences from QB
   * New to FreeBASIC

See also 
   * __FB_VER_MAJOR__
   * __FB_VER_MINOR__



------------------------------------------------------ KeyPgDdfbversion ----
__FB_VERSION__

Intrinsic define (macro string) set by the compiler

Syntax
    __FB_VERSION__

Description
    Substituted by the version number of the compiler where used.

Example
   #if __FB_VERSION__ < "0.18" 
   #error  Please compile With FB version 0.18 Or above 
   #endif

   This will stop the compilation if the compiler version is below 0.18

Differences from QB
   * Did not exist in QB

See also
   * __FB_SIGNATURE__
   * __FB_WIN32__
   * __FB_LINUX__
   * __FB_DOS__



-------------------------------------------------------- KeyPgDdfbwin32 ----
__FB_WIN32__

Intrinsic define set by the compiler

Syntax
   __FB_WIN32__

Description
   Define without a value created at compile time if compiling to the Win 
   (32-bit or 64-bit) target. Default in Win hosted version, or active if 
   the -target win32 or -target win64 command line option is used. It can 
   be used to compile parts of the program only if the target is Win.

Example
   #ifdef __FB_WIN32__
     ' ... instructions only for Win ...
     ' ... GetProcAddress ...
   #else
     ' ... instructions not for Win ...
   #endif 

Differences from QB
   * New to FreeBASIC

See also
   * __FB_DOS__
   * __FB_LINUX__
   * __FB_PCOS__
   * Compiler Option: -target



--------------------------------------------------------- KeyPgDdfbxbox ----
__FB_XBOX__

Intrinsic define set by the compiler

Syntax
   __FB_XBOX__

Description
   Define without a value created at compile time when the -target xbox 
   command line option is used. It can be used to compile parts of the 
   program only if the target is Xbox.

Example
   #ifdef __FB_XBOX__
     '...instructions only for Xbox...
   #else
     '...instructions not for Xbox...
   #endif 

Differences from QB
   * New to FreeBASIC

See also
   * __FB_LINUX__
   * __FB_WIN32__
   * Compiler Option: -target



----------------------------------------------------------- KeyPgDdfile ----
__FILE__

Intrinsic define (macro string) set by the compiler

Syntax
   __FILE__

Description
   Substituted with the quoted source file name where used.

   An example of normal use is to report wrong values in debugging.

Example
   Dim a As Integer
   If a<0 Then
      Print "Error: a = " & a & " in " & __FILE__ & " (" & __FUNCTION__ & ") line " & __LINE__
   End If


   Error: a = -32767 in test.bas (MAIN) Line 47

Differences from QB
   * Did not exist in QB

See also
   * __FILE_NQ__
   * __FUNCTION__
   * __LINE__



--------------------------------------------------------- KeyPgDdfilenq ----
__FILE_NQ__

Intrinsic define (macro string) set by the compiler

Syntax
   __FILE_NQ__

Description
   Substituted with the non-quoted source file name where used.

Example
   #print __FILE_NQ__

Differences from QB
   * New to FreeBASIC

See also
   * __FILE__
   * __FUNCTION_NQ__
   * __LINE__



------------------------------------------------------- KeyPgDdfunction ----
__FUNCTION__

Intrinsic define (macro string) set by the compiler

Syntax
   __FUNCTION__

Description
   Substituted with the quoted name of the current function block where 
   used.

   Its normal use is to report wrong values in debugging.

   If __FUNCTION__ is used at the module level, the function name given 
   will be "__FB_MAINPROC__" for the main module, or "__FB_MODLEVELPROC__" 
   for a different module.

Example
   Dim a As Integer

   '...

   If a < 0 Then '' this shouldn't happen
      Print "Error: a = " & a & " in " & __FILE__ & " (" & __FUNCTION__ & ") line " & __LINE__
   End If


   Error: a = -32767 in test.bas (__FB_MAINPROC__) Line 47

Differences from QB
   * Did not exist in QB

See also
   * __FILE__
   * __FUNCTION_NQ__
   * __LINE__



----------------------------------------------------- KeyPgDdfunctionnq ----
__FUNCTION_NQ__

Intrinsic define (macro string) set by the compiler

Syntax
   __FUNCTION_NQ__

Description
   Substituted with the non-quoted name of the current function block where 
   used.

   If __FUNCTION_NQ__ is used at the module level, the function name given 
   will be __FB_MAINPROC__ for the main module, or __FB_MODLEVELPROC__ for 
   a different module.  This is not the actual function name though, so 
   it's not as useful there.

Example
   Sub MySub
     Print "Address of " + __FUNCTION__ + " is ";
     Print Hex( @__FUNCTION_NQ__ )
   End Sub

   MySub


   Address of MYSUB Is 4012D0

Differences from QB
   * Did not exist in QB

See also
   * __FILE_NQ__
   * __FUNCTION__
   * __LINE__



----------------------------------------------------------- KeyPgDdline ----
__LINE__

Intrinsic define (macro value) set by the compiler

Syntax
   __LINE__

Description
   Substituted with the current line number of the source file where used.

   Its normal use is to report wrong values in debugging.

Example
   Dim a As Integer

   If a < 0 Then 
      Print "Error: a = " & a & " in " & __FILE__ & " (" & __FUNCTION__ & ") line " & __LINE__
   End If


   Error: a = -32767 in test.bas (MAIN) Line 47

Differences from QB
   * Did not exist in QB

See also
   * __FILE__
   * __FUNCTION__



----------------------------------------------------------- KeyPgDdpath ----
__PATH__

Intrinsic define (macro string) set by the compiler

Syntax
   __PATH__

Description
   Set to the quoted absolute path of the source file at the time of 
   compilation.

Example
   ' Tell the compiler to seach the source file's
   ' directory for libraries

   #libpath __PATH__

Differences from QB
   * New to FreeBASIC

See also
   * __FILE__



----------------------------------------------------------- KeyPgDdtime ----
__TIME__

Intrinsic define (macro value) set by the compiler

Syntax
   __TIME__

Description
   Substitutes the compiler time in a literal string (24 clock, "hh:mm:ss" 
   format) where used.

Example
   Print "Compile Time: " & __TIME__


   Compile Time: 13:42:57

Differences from QB
   * New to FreeBASIC

See also
   * __DATE__
   * __DATE_ISO__
   * Time




============================================================================
    #

--------------------------------------------------------- KeyPgPpassert ----
#assert

Preprocessor conditional directive

Syntax
   #assert  condition

Parameters
   condition
      A conditional expression that is assumed to be true

Description
   Asserts the truth of a conditional expression at compile time.  If 
   condition is false, compilation will stop with an error.

   This statement differs from the Assert macro in that #assert is 
   evaluated at compile-time and Assert is evaluated at run-time.

Example
   Const MIN = 5, MAX = 10
   #assert MAX > MIN '' cause a compile-time error if MAX <= MIN

Differences from QB
   * New to FreeBASIC

See also
   * Assert
   * #if
   * #error



--------------------------------------------------------- KeyPgPpdefine ----
#define

Preprocessor directive to define a macro

Syntax
   #define identifier body
   #define identifier( [ parameters ] ) body
   #define identifier( [ parameters, ] Variadic_Parameter... ) body

Description
   #define allows to declare text-based preprocessor macros. Once the 
   compiler has seen a #define, it will start replacing further occurrences 
   of identifier with body. body may be empty. The expansion is done 
   recursively, until there is nothing more to expand and the compiler can 
   continue analyzing the resulting code. #undef can be used to make the 
   compiler forget about a #define.

   Parameters turn a define into a function-like macro, allowing text 
   arguments to be passed to the macro. Any occurrences of the parameter 
   names in the body will be replaced by the given argument text during 
   expansion. The # Stringize operator can be used on macro parameters to 
   turn them into string literals, and the ## Concatenate operator can be 
   used to merge tokens together.

   Note: In the function-like macro declaration, the identifier should be 
   followed by the opening parentheses (() immediately without any 
   white-space in between, otherwise the compiler will treat it as part of 
   the body.

   Defines are scoped; they are only visible in the scope they were defined 
   in. If defined at module level, the define is visible throughout the 
   module. If the identifier is defined inside a compound statement having 
   scope (Sub, For..Next, While..Wend, Do..Loop, Scope..End Scope, etc), 
   the identifier define is only visible within that scope. Namespaces on 
   the other hand do not have any effect on the visibility of a define.

   Identifiers can be checked for with #ifdef and others, which can be used 
   to hide parts of code from the compiler (conditional compiling).

   The result of macro expansion can be checked by using the -pp compiler 
   option.

   #defines are often used to declare constants. The Const statement is a 
   type-safe alternative.

   WARNING: When the macro body contains an expression with one operator at 
   least, it may be mandatory to have to surround some terms (parameters, 
   whole body) by parentheses in order to not undergo an unwanted 
   precedence change of operators.

Example
   '' Definition and check
   #define DEBUGGING
   #ifdef DEBUGGING
     ' ... statements
   #endif

   '' Simple definition/text replacement
   #define False 0
   #define True (Not False)

   '' Function-like definition
   #define MyRGB(R,G,B) (((R)Shl 16)  Or ((G)Shl 8) Or (B)) 
   Print Hex( MyRGB(&hff, &h00, &hff) )

   '' Line continuation and statements in a definition
   #define printval(bar) _
      Print #bar; " ="; bar

   '' #defines are visible only in the scope where they are defined
   Scope
      #define LOCALDEF 1
   End Scope

   #ifndef LOCALDEF
   #   Print LOCALDEF Is Not defined
   #endif

   '' namespaces have no effect on the visibility of a define
   Namespace foo
   #   define NSDEF
   End Namespace

   #ifdef NSDEF
   #   Print NSDEF Is defined
   #endif

Differences from QB
   * New to FreeBASIC

See also
   * #macro
   * # Preprocessor Stringize
   * ## Preprocessor Concatenate
   * #ifdef
   * #undef
   * Const
   * ...



----------------------------------------------------------- KeyPgPpelse ----
#else

Preprocessor conditional directive

Syntax
   #if (expression)
      ' Conditionally included statements if expression is True
   #else
      ' Conditionally included statements if expression is False 
   #endif

Description
   #else can be added to an #if, #ifdef, or #ifndef block to provide an 
   alternate result to the conditional expression.

Example
   #define MODULE_VERSION 1
   Dim a As String
   #if (MODULE_VERSION > 0)
     a = "Release"
   #else
     a = "Beta"
   #endif
   Print "Program is "; a

Differences from QB
   * New to FreeBASIC

See also
   * #define
   * #macro
   * #if
   * #elseif 
   * #endif 
   * #ifdef
   * #ifndef
   * #undef
   * defined



--------------------------------------------------------- KeyPgPpelseif ----
#elseif

Preprocessor conditional directive

Syntax
   #if (expression1)
      ' Conditionally included statements if expression1 is True
   #elseif (expression2)
      ' Conditionally included statements if expression2 is True
   #else
      ' Conditionally included statements if both
      ' expression1 and expression2 are False
   #endif

Description
   #elseif can be added to an #if block to provide an additional 
   conditions.

Example
   #define WORDSIZE 16
   #if (WORDSIZE = 16)
     ' Do some some 16 bit stuff
   #elseif (WORDSIZE = 32)
     ' Do some some 32 bit stuff
   #else
     #error WORDSIZE must be set To 16 Or 32
   #endif

Differences from QB
   * New to Freebasic

See also
   * #define
   * #macro
   * #if
   * #else 
   * #endif 
   * #ifdef
   * #ifndef
   * #undef
   * defined



---------------------------------------------------------- KeyPgPpendif ----
#endif

Preprocessor conditional directive

Syntax
   #endif

Description
   Ends a group of conditional directives

   See #if, #ifdef, or #ifndef for examples of usage.

Example
   #define DEBUG_LEVEL 1
   #if (DEBUG_LEVEL = 1)
     'Conditional statements
   #endif

Differences from QB
   * New to FreeBASIC

See also
   * #define
   * #macro
   * #if
   * #else 
   * #elseif 
   * #ifdef
   * #ifndef
   * #undef
   * defined



---------------------------------------------------------- KeyPgPpmacro ----
#Macro...#Endmacro

Preprocessor directive to define a multiline macro

Syntax
   #macro identifier( [ parameters ] )
      body
   #endmacro

   #macro identifier( [ parameters, ] Variadic_Parameter... )
      body
   #endmacro

Description
   #macro is the multi-line version of #define.

Example
   '' macro as an expression value
   #macro Print1( a, b )
     a + b
   #endmacro

   Print Print1( "Hello", "World" )

   '' Output :
   '' Hello World!

   '' macro as multiple statements
   #macro Print2( a, b )
      Print a;
      Print " ";
      Print b;
      Print "!"
   #endmacro

   Print2( "Hello", "World" )

   '' Output :
   '' Hello World!

Differences from QB
   * New to FreeBASIC

See also
   * #define
   * #ifdef
   * #undef



---------------------------------------------------------- KeyPgPperror ----
#error

Preprocessor diagnostic directive

Syntax
   #error error_text

Parameters
   error_text
      The display message

Description
   #error interrupts compiling to display error_text when compiler finds 
   it, and then parsing continues. 

   This keyword must be surrounded by an #if <condition> ...#endif, so the 
   compiler can reach #error only if <condition> is met.

   In any case, the final status will be "Failed to compile".

Example
   #define c 1

   #if c = 1
     #error Bad value of c 
   #endif

Differences from QB
   * New to FreeBASIC

See also
   * #if
   * #print
   * #assert



------------------------------------------------------------- KeyPgPpif ----
#if

Preprocessor conditional directive

Syntax
   #if (expression)
      ' Conditionally included statements
   #endif

Description
   Conditionally includes statements at compile time.

   Statements contained within the #if / #endif block are included if 
   expression evaluates to True (non-zero) and excluded (ignored) if 
   expression evaluates to False (0).

   This conditional directive differs from the If conditional statement in 
   that #if is evaluated at compile-time and If is evaluated at run-time.

Example
   #define DEBUG_LEVEL 1
   #if (DEBUG_LEVEL >= 2)
     ' This line is not compiled since the expression is False
     Print "Starting application"
   #endif

Differences from QB
   * New to FreeBASIC

See also
   * #define
   * #macro
   * #else 
   * #elseif 
   * #endif 
   * #ifdef
   * #ifndef
   * #undef
   * defined
   * #assert 



---------------------------------------------------------- KeyPgPpifdef ----
#ifdef

Preprocessor conditional directive

Syntax
   #ifdef symbol
      ' Conditionally included statements
   #endif

Description
   Conditionally includes statements at compile time.

   Statements within the #ifdef...#endif block are included if symbol is 
   defined and excluded (ignored) if symbol is not defined.

   #ifdef symbol is equivalent to #if defined (symbol)

Example
   #define _DEBUG
   #ifdef _DEBUG
      ' Special statements for debugging
   #endif

Differences from QB
   * New to Freebasic

See also
   * #define
   * #macro
   * #if
   * #else 
   * #elseif 
   * #endif 
   * #ifndef
   * #undef
   * defined



--------------------------------------------------------- KeyPgPpifndef ----
#ifndef

Preprocessor conditional directive

Syntax
   #ifndef symbol
      ' Conditionally included statements
   #endif

Description
   Conditionally includes statements at compile time.

   Statements within the #ifndef...#endif block are included if symbol is 
   not defined and excluded (ignored) if symbol is defined.

   #ifndef symbol is equivalent to #if Not defined(symbol)

Example
   #ifndef __MYFILE_BI__
   #define __MYFILE_BI__
      ' Declarations 
   #endif

Differences from QB
   * New to FreeBASIC

See also
   * #define
   * #macro
   * #if
   * #else 
   * #elseif 
   * #endif 
   * #ifdef
   * #undef
   * defined



----------------------------------------------------------- KeyPgInclib ----
#inclib

Preprocessor directive

Syntax
   #inclib "libname"

Description
   Includes a library in the linking process as if the user specified 
   -l libname on the command line.

Example
   '' incomplete code snippet

   '' this will include libmystuff.a in the link process
   #inclib "mystuff" 

Differences from QB
   * New to FreeBASIC

See also
   * #include
   * Compiler Option: -l
   * Compiler Option: -p



---------------------------------------------------------- KeyPgInclude ----
#include

Preprocessor statement to include contents of another source file

Syntax
   #include [once] "file"

Description
   #include inserts source code from another file at the point where the 
   #include directive appears.  This has the effect of compiling the source 
   code from the include file as though it were part of the source file 
   that includes it.  Once the compiler has reached the end of the include 
   file, the original source file continues to be compiled.

   This is useful to remove code from a file and separate it into more 
   files. It is useful to have a single file with declarations in a program 
   formed by several modules. You may include files within an include file, 
   although avoid including the original file into itself, this will not 
   produce valid results. Typically, include files will have an extension 
   of .bi and are mainly used for declaring subs/functions/variables of a 
   library, but any valid source code may be present in an include file.

   The Once specifier tells the compiler to include the file only once even 
   if it is included several times by the source code.

   $Include is an alternative form of include, existing only for 
   compatibility with QuickBASIC. It is recommended to use #include 
   instead.

   The compiler will automatically convert path separator characters ( '/' 
   and '\' ) as needed to properly load the file.  The filename name may be 
   an absolute or relative path.  

   For relative paths, or where no path is given at all, the include file 
   is search for in the following order:
   * Relative from the directory of the source file
   * Relative from the current working directory
   * Relative from addition directories specified with the -i command line 
     option
   * The include folder of the FreeBASIC installation (FreeBASIC\inc, 
     where FreeBASIC is the folder where the fbc executable is located)

Example
   ' header.bi file
   Type FooType
      Bar As Byte
      Barbeque As Byte 
   End Type

   ' main.bas file
   #include "header.bi"

   Dim Foo As FooType

   Foo.Bar = 1
   Foo.Barbeque = 2

Differences from QB
   * New to FreeBASIC

See also
   * #define
   * #inclib
   * Compiler Option: -i
   * Compiler Option: -include



----------------------------------------------------------- KeyPgPplang ----
#lang

Preprocessor statement to set the compiler dialect.

Syntax
   #lang "lang"

Parameters
   "lang"
      The dialect to set, enclosed in double quotes, and must be one of 
      "fb", "fblite", "qb", or "deprecated".

Description
   If the -forcelang option was not given on the command line, #lang can be 
   used to set the dialect for the source module in which it appears.  At 
   most two passes will be made on the source module.  On the first pass, 
   if the specified dialect is anything other than the default dialect 
   (chosen with -lang, or "fb" by default), the compiler will reset the 
   parser for another pass and restart compilation at the beginning of the 
   source module.  If this directive is encountered again on the second 
   pass, and the specified dialect does not match the new current dialect, 
   a warning is issued and compilation continues.  If any errors were 
   encountered on the first pass, the compiler will not attempt a second 
   pass."

   #lang may not be used in any compound statement, scope, or subroutine.  
   However, it may be nested in module level preprocessor statements or 
   used in an include file.

   There is currently no restriction on where this directive may be placed 
   in a source module.  In future this may change, therefore best practice 
   would be to use this directive before the first declaration, definition, 
   or executable statement in the source.

   This directive overrides the -lang option if it was given on the command 
   line.  However, if the -forcelang option was given on the command line, 
   this directive will have no effect.  A warning is issued, the directive 
   is ignored, and compilation will continue.  This allows the user to 
   explicitly override #lang directives.

Example
   #lang "fblite"

Differences from QB
   * New to FreeBASIC

See also
   * $Lang
   * __FB_LANG__
   * Compiler Option: -lang
   * Compiler Option: -forcelang
   * FreeBASIC Dialects



-------------------------------------------------------- KeyPgPplibpath ----
#libpath

Preprocessor statement to add a search path for libraries

Syntax
   #libpath "path"

Description
   Adds a library search path to the linker's list of search paths as if it 
   had been specified on the command line with the '-p' option.

   Paths are relative to the working directory where fbc was invoked and 
   not relative to the directory of the source file.

   No error is generated if the path does not exist and compilation and 
   linking will continue.

Example
   ' search the lib directory for external libraries
   #libpath "lib"

Differences from QB
   * New to FreeBASIC

See also
   * #inclib
   * #include
   * Compiler Option: -p



----------------------------------------------------------- KeyPgPpline ----
#line

Preprocessor directive to set the current line number and file name

Syntax
   #line number [ "name" ]

Parameters
   number 
      new line number
   "name"
      new file name (optional)

Description
   Informs the compiler of a change in line number and file name and 
   updates the __FILE__ and __LINE__ macro values accordingly.

   Both compile time messages and run-time messages are affected by this 
   directive.

   This directive allows other programs to generate source code for the 
   FreeBASIC compiler and have it return warning and/or error messages that 
   refer to the original source used by the other program.

Example
   #line 155 "outside.src"

   Error 1000

   '' Output is:
   '' Aborting due to runtime error 1000 at line 157 of outside.src()

Differences from QB
   * New to FreeBASIC

See also
   * __FILE__
   * __LINE__



---------------------------------------------------------- KeyPgPpmacro ----
#Macro...#Endmacro

Preprocessor directive to define a multiline macro

Syntax
   #macro identifier( [ parameters ] )
      body
   #endmacro

   #macro identifier( [ parameters, ] Variadic_Parameter... )
      body
   #endmacro

Description
   #macro is the multi-line version of #define.

Example
   '' macro as an expression value
   #macro Print1( a, b )
     a + b
   #endmacro

   Print Print1( "Hello", "World" )

   '' Output :
   '' Hello World!

   '' macro as multiple statements
   #macro Print2( a, b )
      Print a;
      Print " ";
      Print b;
      Print "!"
   #endmacro

   Print2( "Hello", "World" )

   '' Output :
   '' Hello World!

Differences from QB
   * New to FreeBASIC

See also
   * #define
   * #ifdef
   * #undef



----------------------------------------------------------- KeyPgPragma ----
#pragma

Preprocessor directive

Syntax
   #pragma option [ = value ]
   Or
   #pragma push ( option [, value ] )
   Or
   #pragma pop ( option )

Parameters
   Possible values for option and related values:

      +------------+---------------------------------+-------------------------------------------------------------------------------------------------------------+
      |Option      | Value                           | Description                                                                                                 |
      | msbitfields| 0                               | Use bitfields compatible with gcc (default)                                                                 |
      |            | -1 (or any other non-zero value)| Use bitfields compatible with those used in Microsoft C compilers                                           |
      | once       | N/A                             | cause the source file in which the pragma appears to behave as though it was included with #include once ...|
      | constness  | 0                               | cause the source file in which the pragma appears to disable 'CONST qualifier discarded' warning            |
      |            | -1 (or any other non-zero value)| cause the source file in which the pragma appears to enable 'CONST qualifier discarded' warning             |
      +------------+---------------------------------+-------------------------------------------------------------------------------------------------------------+

   If value is not given, the compiler assumes -1 (TRUE).

Description
   Allows the setting of compiler options inside the source code.

   Push saves the current value of the option onto a stack, then assigns 
   the new value (or -1) to it. Pop restores the option to its previous 
   value, and removes it from the stack. This mechanism allows options to 
   be changed for a certain part of source code, regardless of the setting 
   used by the context, which is especially useful inside #include header 
   files.

   constness pragma is added for testing fbc compiler.  It will be removed 
   in future at should not be relied upon.

Example
   '' MSVC-compatible bitfields: save the current setting and then enable them
   #pragma push(msbitfields)

   '' do something that requires MS-compatible bitfields here

   '' restore original setting
   #pragma pop(msbitfields)

Differences from QB
   * New to FreeBASIC

See also
   * #include



---------------------------------------------------------- KeyPgPpprint ----
#print

Preprocessor diagnostic directive

Syntax
   #print text

Description
   Causes compiler to output text to screen during compilation.

Example
   #print Now compiling module foo

Differences from QB
   * New to FreeBASIC

See also
   * #error



---------------------------------------------------------- KeyPgPpundef ----
#undef

Preprocessor directive to undefine a macro

Syntax
   #undef symbol

Description
   Undefines a symbol previously defined with #define.

   Can be used to ensure that a macro or symbol has a limited lifespan and 
   does not conflict with a similar macro definition that may be defined 
   later in the source code.

   (Note: #undef should not be used to undefine variable or function names 
   used in the current function scope.  The names are needed internally by 
   the compiler and removing them can cause strange and unexpected 
   results.)

Example
   #define ADD2(a_, b_)  ((a_) + (b_))
   Print ADD2(1, 2)
   ' Macro no longer needed so get rid of it ...
   #undef ADD2

Differences from QB
   * New to Freebasic

See also
   * #define
   * #macro
   * #if
   * #else 
   * #elseif 
   * #endif 
   * #ifdef
   * #ifndef
   * defined




============================================================================
    $

------------------------------------------------------ KeyPgMetaDynamic ----
$Dynamic

Metacommand to change the way arrays are allocated

Syntax
   '$Dynamic
      or
   Rem $Dynamic

Description
   '$Dynamic is a metacommand that specifies that any following array 
   declarations are variable-length, whether they are declared with 
   constant subscript ranges or not. This remains in effect for the rest of 
   the module in which '$Dynamic is used, and can be overridden with 
   '$Static.  It is equivalent to the Option Dynamic statement.

Example
   ' compile with -lang fblite or qb

   #lang "fblite"

   '$DYNAMIC
   Dim a(100)
   '......
   ReDim a(200)

Dialect Differences
   * Only available in the -lang fblite and -lang qb dialects.

Differences from QB
   * When used inside comments it must be the first token

See also
   * $Static
   * Dim
   * ReDim
   * Erase
   * Option Dynamic



------------------------------------------------------ KeyPgMetaInclude ----
$Include

Metacommand statement to include contents of another source file

Syntax
   '$Include [once]: 'file'
      or
   Rem $Include [once]: 'file'

Description
   $Include inserts source code from another file at the point where the 
   $Include metacommand appears.  This has the effect of compiling the 
   source code from the include file as though it were part of the source 
   file that includes it.  Once the compiler has reached the end of the 
   include file, the original source file continues to be compiled.

   The Once specifier tells the compiler to include the file only once even 
   if it is included several times by the source code.

   '$Include: exists for compatibility with QuickBASIC. It is recommended 
   to use #include instead.

Example
   ' header.bi file
   Type FooType
      Bar As Byte
      Barbeque As Byte 
   End Type
   Dim Foo As FooType

   '' compile with -lang fblite or qb

   #lang "fblite"

   '' main.bas file

   '$INCLUDE: "header.bi"

   Foo.Bar = 1
   Foo.Barbeque = 2

Dialect Differences
   * Only available in the -lang fblite and -lang qb dialects.

Differences from QB
   * None

See also
   * #include



--------------------------------------------------------- KeyPgMetaLang ----
$Lang

Metacommand statement to set the compiler dialect.

Syntax
   '$lang: "lang"
      or
   Rem $lang: "lang"

Parameters
   "lang"
      The dialect to set, enclosed in double quotes, and must be one of 
      "fb", "fblite", "qb", or "deprecated".

Description
   If the -forcelang option was not given on the command line, $Lang can be 
   used to set the dialect for the source module in which it appears.  At 
   most two passes will be made on the source module.  On the first pass, 
   if the specified dialect is anything other than the default dialect 
   (chosen with -lang, or "fb" by default), the compiler will reset the 
   parser for another pass and restart compilation at the beginning of the 
   source module.  If this metacommand is encountered again on the second 
   pass, and the specified dialect does not match the new current dialect, 
   a warning is issued and compilation continues.  If any errors were 
   encountered on the first pass, the compiler will not attempt a second 
   pass.

   $Lang  may not be used in any compound statement, scope, or subroutine.  
   However, it may be nested in module level preprocessor statements or 
   used in an include file.

   There is currently no restriction on where this directive may be placed 
   in a source module.  In future this may change, therefore best practice 
   would be to use this directive before the first declaration, definition, 
   or executable statement in the source.

   This directive overrides the -lang option if it was given on the command 
   line.  However, if the -forcelang option was given on the command line, 
   this directive will have no effect.  A warning is issued, the directive 
   is ignored, and compilation will continue.  This allows the user to 
   explicitly override $Lang metacommands.

   This metacommand was introduced in FreeBASIC version 0.20.0.  Older 
   versions of FB, and QuickBASIC, will treat it as a comment and silently 
   ignore it.

Example
   '$lang: "qb"

Differences from QB
   * New to FreeBASIC
   * QB handles '$lang: as a normal comment

See also
   * #lang
   * __FB_LANG__
   * Compiler Option: -lang
   * Compiler Option: -forcelang
   * FreeBASIC Dialects



------------------------------------------------------- KeyPgMetaStatic ----
$Static

Metacommand to change the way arrays are allocated

Syntax
   '$Static
      or
   Rem $Static

Description
   '$Static is a metacommand that overrides the behavior of $Dynamic, that 
   is, arrays declared with constant subscript ranges are fixed-length. 
   This remains in effect for the rest of the module in which '$Static is 
   used, and can be overridden with $Dynamic.  It is equivalent to the 
   Option Static statement.

Example
   ' compile with -lang fblite or qb

   #lang "fblite"

   '$dynamic
   Dim a(100)   '<<this array will be variable-length
   '$static
   Dim b(100)   '<<this array will be fixed-length

Dialect Differences
   * Only available in the -lang fblite and -lang qb dialects.

Differences from QB
   * When used inside comments it must be the first token

See also
   * $Dynamic
   * Dim
   * Erase
   * ReDim
   * Option Dynamic
   * Option Static




============================================================================
    ?

------------------------------------------------------------ KeyPgPrint ----
(Print | ?)

Writes text to the screen

Syntax
   (Print | ?) [ expressionlist ] [ , | ; ]

Parameters
   expressionlist
      list of items to print

Description
   Print outputs a list of values to the screen. Numeric values are 
   converted to their string representation, with left padding for the 
   sign. Objects of user-defined types must overload Operator Cast () As 
   String.

   Consecutive values in the expression list are separated either by a 
   comma (,) or semicolon (;). A comma indicates printing should take place 
   at the next 14 column boundary, while a semicolon indicates values are 
   printed with no space between them.  This has a similar effect to 
   concatenating expressions using + or &.

   Print also supports the special expressions, Spc() and Tab().  These can 
   be used to space out expressions, or to align the printing to a specific 
   column.

   A new-line character is printed after the values in the expression list 
   unless the expression list is followed by a comma or semicolon.  A Print 
   without any expressions or separators following it will just print a 
   new-line.

   NOTE: Print resets the Err value after each expression is printed.

   NOTE: In graphics mode, Draw String provides a flexible alternative to 
   Print: it prints a string to the screen with pixel positioning, 
   transparent background, and can use a user-supplied font.

Example
   '' print "Hello World!", and a new-line
   Print "Hello World!"

   '' print several strings on one line, then print a new-line
   Print "Hello";
   Print "World"; "!";
   Print

   '' column separator
   Print "Hello!", "World!"

   '' printing variables/expressions
   Dim As Double pi = Atn(1) * 4
   Dim As String s = "FreeBASIC"

   Print "3 * 4 ="; 3 * 4

   Print "Pi is approximately"; pi
   Print s; " is great!"

Dialect Differences
   * In the -lang qb dialect, an extra space is printed after numbers.

Differences from QB
   * None, when using QBASIC's variable types in -lang qb.
   * Unsigned numbers are printed without a space before them.
   * QB did not support casting for UDTs, so didn't allow them to be Print
     ed.

See also
   * Spc
   * Tab
   * Print #
   * ? #
   * Print Using
   * ? Using
   * Write
   * Draw String
   * Input



---------------------------------------------------------- KeyPgPrintPp ----
(Print | ?) #

Writes a list of values to a file or device

Syntax
   (Print | ?) # filenum, [ expressionlist ] [ , | ; ]

Parameters
   filenum
      The file number of a file or device opened for Output or Append.
   expressionlist
      List of values to write.

Description
   Print # outputs a list of values to a text file or device. Numeric 
   values are converted to their string representation, with left padding 
   for the sign. Objects of user-defined types must overload Operator Cast 
   () As String.

   Consecutive values in the expression list are separated either by a 
   comma (,) or semicolon (;). A comma indicates printing should take place 
   at the next 14 column boundary, while a semicolon indicates values are 
   printed with no space between them.

   A new-line character is printed after the values in the expression list 
   unless the expression list is followed by a comma or semicolon.

   Note that the comma (,) immediately following the file number is still 
   necessary, even the expression list is empty.  In this case a new-line 
   is printed, just as with a normal expression list that doesn't have a 
   comma or semicolon at the end.

Example
   Open "bleh.dat"  For Output As #1
      
      Print #1, "abc def"
      Print #1, 1234, 5678.901, "xyz zzz"
      
      Close #1

Dialect Differences
   * In the -lang qb dialect, an extra space is printed after numbers.

Differences from QB
   * None, when using QBASIC's variable types in -lang qb.
   * Unsigned numbers are printed without a space before them.
   * QB did not support casting for UDTs, so didn't allow them to be Print
     ed.

See also
   * Print Using
   * ? Using
   * Print
   * ?
   * Write #
   * Open



------------------------------------------------------- KeyPgPrintusing ----
(Print | ?) Using

Outputs formatted text to the screen or output device

Syntax
   (Print | ?) [# filenum ,] [ printexpressionlist {,|;} ] Using 
   formatstring ; [ expressionlist [ ; ] ]

Parameters
   filenum
      The file number of a file or device opened for Output or Append.  
      (Alternatively LPrint may be used where appropriate, instead of 
      Print #)
   printexpressionlist
      Optional preceding list of items to print, separated by commas (,) or 
      semi-colons (;) (see Print for more details).
   formatstring
      Format string to use.
   expressionlist
      List of items to format, separated by semi-colons (;).

Description
   Print to screen various expressions using a format determined by the 
   formatstring parameter. Internally, Print Using uses a buffer size of 
   2048 bytes: while it is highly unlikely that this buffer would be 
   filled, it should be noted that output would be truncated should this 
   limit be reached.

   If no expression list is given, the format string will be printed up to 
   the first special marker.  Note that the semi-colon after formatstring 
   is still necessary, even if no expression list is given.

   The format string dictates how the expressions are to be formatted when 
   output to the screen, indicated by the use of special marker characters. 
   There are markers for formatting both string and numeric output:

   String formatting

         +------+----------------------------------------------------------------------+
         |Marker|Formatting                                                            |
         |!     |prints the first character of a string                                |
         |\   \ |prints as many characters of a string as occupied between the pair \ \|
         |&     |prints the entire string                                              |
         +------+----------------------------------------------------------------------+

   Numeric formatting

         +------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
         |Marker|Formatting                                                                                                                                                            |
         |#     |placeholder for either an integer digit, or a decimal digit if a decimal point precedes it                                                                            |
         |,     |placed after integer digit indicates groups of 3 digits should be separated by commas in fixed-point notation                                                         |
         |.     |placed near # indicates place for the decimal point                                                                                                                   |
         |^^^^  |uses exponential notation (E+/-###) when placed after the digit characters                                                                                            |
         |+     |placed before/after the format string, controls whether the sign of a number is prepended/appended, and causes an explicit '+' sign to be printed for positive numbers|
         |-     |placed after the format string, causes the sign of the number to be appended rather than prepended, appending a space/negative sign for positive/negative numbers     |
         |$$    |placed at the start of integer digits, causes a dollar sign to be prepended to the number (after the sign if one is prepended)                                        |
         |**    |placed at the start of integer digits, causes any padding on the left to be changed from spaces to asterisks                                                          |
         |**$   |placed at the start of integer digits, pads on the left with asterisks, and prepends a dollar sign after the asterisks                                                |
         |&     |prints a number intelligently, using the exact number of digits required (new to version 0.21.0b)                                                                     |
         +------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+

   All of the special marker characters can be escaped by preceding them 
   with the underscore character "_", allowing them to be printed directly. 
   For example, "_!" is printed as "!", and "__" is printed as "_".

   If a numerical value cannot fit in the number of digits indicated by the 
   format string, the formatting is adapted to fit the number, possibly 
   switching to scientific notation, and the number is printed preceded by 
   the percent "%" character. E.g., the number 1234 with a formatstring of 
   "##.##" would be printed as "%1234.00".

   All other characters within the format string are printed as they 
   appear.

   A new-line character is printed after the values in the expression list 
   unless the expression list is followed by a semicolon (;).

Example

   Print Using "The value is #.## seconds"; 1.019
   Print Using "The ASCII code for the pound sign (_#) is ###"; Asc("#")
   Print Using "The last day in the year is & \ \"; 31; "December"

   will produce the output:

   The value Is 1.02 seconds
   The ASCII code For the pound sign (#) Is  35
   The last Day in the Year Is 31 Dec

Differences from QB
   * QB didn't allow "&" to be used for printing numbers.

See also
   * Print
   * ?
   * Print #
   * ? #
   * Format
   * Using
   * Palette Using




============================================================================
    A

-------------------------------------------------------------- KeyPgAbs ----
Abs

Calculates the absolute value of a number

Syntax
   Declare Function Abs ( ByVal number As Integer ) As Integer
   Declare Function Abs ( ByVal number As UInteger ) As UInteger
   Declare Function Abs ( ByVal number As Double ) As Double

Usage
   result = Abs( number )

Parameters
   number
      Value to find the absolute value of.

Return Value
   The absolute value of number.

Description
   The absolute value of a number is its positive magnitude.  If a number 
   is negative, its value will be negated and the positive result returned. 
   For example, Abs(-1) and Abs(1) both return 1. The required number 
   argument can be any valid numeric expression.
   Unsigned numbers will be treated as if they were signed, i.e. if the 
   highest bit is set the number will be treated as negative, and its value 
   negated.
   The value returned will be greater than or equal to 0, with the 
   exception of signed integers containing the lowest possible negative 
   value that can be stored in its type, in which case negating it will 
   overflow the result.

   The Abs unary Operator can be overloaded with user defined types.

Example
   Dim n As Integer

   Print Abs( -1 )
   Print Abs( -3.1415 )
   Print Abs( 42 )
   Print Abs( n )

   n = -69

   Print Abs( n )

Output:

   1
   3.1415
   42
   0
   69

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * None

See also
   * Sgn
   * Operator



--------------------------------------------------------- KeyPgAbstract ----
Abstract

Declare abstract methods

Syntax
   Type typename Extends base_typename
      Declare Abstract Sub|Function|Property|Operator ...
   End Type

Description
   Abstract is a special form of Virtual. The difference is that abstract 
   methods do not have a body, but just the declaration. Essentially this 
   allows the declaration of an interface which can be implemented by 
   various derived types.

   In order to call an abstract method, it must have been overridden and 
   implemented by a derived data type, or else the program will abort.
   As a result, only types that implement all the abstract methods are 
   allowed to create objects. For the same reason, a constructor should not 
   call an unimplemented method.

   Constructors cannot be abstract, since they cannot be virtual. In 
   addition, abstract Destructors are not supported either, because a 
   destructor body (no matter whether implicit or explicit) is needed in 
   order to call base and field destructors.

   Abstracts are called "pure virtual" in C++ (unlike FreeBASIC, C++ allows 
   pure virtuals to have a body, but accessible only statically).

   Note: In a multi-level inheritance, a same named method (same identifier 
   and signature) can be declared Abstract, Virtual or normal (without 
   specifier) at each inheritance hierarchy level. When there is mixing of 
   specifiers, the usual order is abstract -> virtual -> normal, from top 
   to bottom of the inheritance hierarchy.
   The access control (Public/Protected/Private) of an overriding method is 
   not taken into account by the internal polymorphism process, but only 
   for the initial call at compile-time.
   A derived static method cannot override a base virtual/abstract method, 
   but can shadow any base method (including virtual/abstract).

Example
   Type Hello Extends Object
      Declare Abstract Sub hi( )
   End Type

   Type HelloEnglish Extends Hello
      Declare Sub hi( )
   End Type

   Type HelloFrench Extends Hello
      Declare Sub hi( )
   End Type

   Type HelloGerman Extends Hello
      Declare Sub hi( )
   End Type

   Sub HelloEnglish.hi( )
      Print "hello!"
   End Sub

   Sub HelloFrench.hi( )
      Print "Salut!"
   End Sub

   Sub HelloGerman.hi( )
      Print "Hallo!"
   End Sub

      Randomize( Timer( ) )

      Dim As Hello Ptr h

      For i As Integer = 0 To 9
         Select Case( Int( Rnd( ) * 3 ) + 1 )
         Case 1
            h = New HelloFrench
         Case 2
            h = New HelloGerman
         Case Else
            h = New HelloEnglish
         End Select

         h->hi( )
         Delete h
      Next

Dialect Differences
   * Only available in the -lang fb dialect.

Differences from QB
   * New to FreeBASIC

See also
   * Virtual
   * Type
   * Extends
   * Extends Zstring
   * Extends Wstring
   * Object
   * Override



----------------------------------------------------------- KeyPgAccess ----
Access

Clause of the Open statement to specify requested privileges

Syntax
   Open filename for Binary Access {Read | Write | Read Write} as [#]
   filenum

Usage
   open filename for binary Access Read as #filenum
   open filename for binary Access Write as #filenum
   open filename for binary Access Read Write as #filenum

Parameters
   Read
      Open the file with only read privileges.
   Write
      Open the file with only write privileges.
   Read Write
      Open the file with read and write privileges.

Description
   Access is used with the Open statement to request read, write, or read 
   and write privileges.  If the Access clause is not specified, Read Write 
   is assumed.

Example

This example shows how to open the file "data.raw" with Read and then 
"data.out" with Write access, in Binary mode, in an open file number 
returned by FreeFile.
   Dim As Integer o

     '' get an open file number.
     o = FreeFile
     
     '' open file for read-only access.    
     Open "data.raw" For Binary Access Read As #o
      
      '' make a buffer in memory thats the entire size of the file
      Dim As UByte file_char( LOF( o ) - 1 )

        '' get the file into the buffer.      
        Get #o, , file_char()
      
     Close
     
     '' get another open file number.
     o = FreeFile
     
     '' open file for write-only access.    
     Open "data.out" For Binary Access Write As #o

      '' put the buffer into the new file.      
      Put #o, , file_char()
      
     Close

     Print "Copied file ""data.raw"" to file ""data.out"""

     Sleep

Differences from QB
   * None known.

See also
   * Open
   * Read
   * Write



------------------------------------------------------------- KeyPgAcos ----
Acos

Finds the arccosine of an angle

Syntax
   Declare Function Acos ( ByVal number As Double ) As Double

Usage
   result = Acos( number )

Parameters
   number
      A cosine value in the range [-1..1].

Return Value
   The arccosine of number, in radians, in the range [0..Pi].

Description
   Acos returns the arccosine of the argument number as a Double within the 
   range of 0 to Pi.  The arccosine is the inverse of the Cos function. The 
   returned angle is measured in radians (not degrees).

   Acos can be overloaded as operator to accept user-defined types.

Example
   Dim h As Double
   Dim a As Double
   Input "Please enter the length of the hypotenuse of a triangle: ", h
   Input "Please enter the length of the adjacent side of the triangle: ", a
   Print ""
   Print "The angle between the sides is"; Acos ( a / h )
   Sleep

The output would look like:

   Please enter the length of the hypotenuse of a triangle: 5
   Please enter the length of the adjacent side of the triangle: 4

   The angle between the sides Is 0.6435011087932843

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Acos.

Differences from QB
   * New to FreeBASIC

See also
   * Cos
   * A Brief Introduction To Trigonometry



----------------------------------------------------------- KeyPgAddGfx ----
Add

Parameter to the Put graphics statement which selects addition as the 
blitting method

Syntax
   Put [ target, ] [ STEP ] ( x,y ), source [ ,( x1,y1 )-( x2,y2 ) ], Add[ 
   ,multiplier ]

Parameters
   Add
      Required.
   multiplier
      Optional value between 0 and 255.  The source pixels are 
      premultiplied by (multiplier / 256) before being added.  If omitted, 
      this value defaults to 255.

Description
   Add selects addition as the method for blitting an image buffer.  For 
   each source and target pixel, the values of each respective component 
   are added together to produce the result.
   The addition is saturated - i.e. if the sum of the two values is 256 or 
   more, then it will be cropped down to 255.

   This method will work in all color modes.  Mask colors (color 0 for 
   indexed images, magenta (RGB(255, 0, 255)) for full color images) will 
   be skipped, though full color values of 0 (RGBA(0, 0, 0, 0)) will have 
   also have no effect.

Example
   ''open a graphics window
   ScreenRes 320, 200, 16

   ''create a sprite containing a circle
   Const As Integer r = 32
   Dim c As Any Ptr = ImageCreate(r * 2 + 1, r * 2 + 1, 0)
   Circle c, (r, r), r, RGB(255, 255, 192), , , 1, f

   ''put the sprite at three different multipier
   ''levels, overlapping each other in the middle
   Put (146 - r, 108 - r), c, Add,  64
   Put (174 - r, 108 - r), c, Add, 128
   Put (160 - r,  84 - r), c, Add, 192

   ''free the memory used by the sprite
   ImageDestroy c

   ''pause the program before closing
   Sleep

Differences from QB
   * New to FreeBASIC

See also
   *Trans
   *Alpha
   *Custom
   * Put (Graphics)



------------------------------------------------------------ KeyPgAlias ----
Alias (Name)

Clause of the Sub and Function statements that provides an alternate 
internal name.

Syntax
   [Declare] { Sub | Function } usablename Alias "alternatename" (...)

Usage
   declare sub usablename Alias "alternatename" ( ... )
      or
   declare function usablename Alias "alternatename" ( ... )
      or
   sub usablename Alias "alternatename" ( ... )
      ...
   end sub
      or
   function usablename Alias "alternatename" ( ... )
      ...
   end function
      or
   type typename Alias "alternatename" ( ... )
      ...
   end type

Description
   Alias gives an alternate name to a procedure.  This alternate name 
   cannot be used within the program to call the procedure, but it is 
   visible (if the function is not private) to the linker when linking with 
   code written in other languages.

   Alias is commonly used for procedures in libraries written in other 
   languages when such procedure names are valid in the other language but 
   invalid in BASIC.  When using Alias with Declare, only the alternate 
   name is used by the linker.

   Differently from normal procedure names, Alias does not change the case 
   of the alternate name, so it is useful when external code requires an 
   exported function with a particular name or with a particular case.

   Alias can be used to specify an alternate name for Type definitions.

   Alias can be used as a modifier that specifies an alternate name 
   mangling for procedure parameters.  See Alias (Modifier)

Example

If there is a sub called xClearScreen in an external library and you want 
to reference it with the name ClearVideoScreen, here is sample code to do 
so:
   Declare Sub ClearVideoScreen Alias "xClearScreen" ()

A procedure meant to be used by external C code, exported as MyExportedProc
:
   Function MultiplyByFive cdecl Alias "MyExportedProc" (ByVal Parameter As Integer) As Integer Export
     Return Parameter * 5
   End Function

Differences from QB
   * In QB, Alias only worked with Declare.

See also
   * Declare
   * Export
   * Type (Alias)
   * Alias (Modifier)



---------------------------------------------------- KeyPgAliasModifier ----
Alias (Modifier)

Modifies the data type name mangling (decoration) of a public symbol

Syntax
   ... As [ Const ] datatype alias "modifier" [ Const [ Ptr ... ] ]

Usage
   Dim variable As datatype alias "modifier"
   Type name As datatype alias "modifier"
   Declare Sub name ( param As datatype alias "modifier", ... )
   Declare Function name ( param As datatype alias "modifier", ... ) As 
   datatype alias "modifier"

Parameters
   datatype
      Standard data type or user defined data type to modify
   modifier
      One of the supported modifiers as described in Description section 
      following

Description
   Alias "modifier", when specified following a data type, gives an 
   alternate meaning to the data type, which may be needed for linking with 
   languages other than FreeBASIC.

   Public symbol names are mangled (decorated) to encode information about 
   the data type that is used for the symbol.  When linking with the c 
   language, the special meaning of the alias modifier is meaningless, 
   since the extra information is not encoded in to the public name.  When 
   linking with the c++ language, typically more information is encoded in 
   to the public symbol, and the alias modifier may be required.  The 
   public name is written to the compiled object file, and used by the 
   linker to match symbol names from one object module to another.

   The same rules for mapping data types is used regardless of which 
   backend (gas or gcc) code emitter is used,  And the intent is that FB's 
   compiled code can link consistently with it's own object modules and 
   object modules (or libraries) compiled from other languages.

   Supported Modifiers

      Long alias "long"
      ULong alias "long"
         On Win 64-bit targets, used to map FB's 32-bit Long and ULong 
         types to c/c++'s 32-bit long [int] type, instead of the 32-bit int 
         type.

      Any alias "char" Ptr
         Maps any ptr to c/c++'s char *.  In c/c++, char, signed char, and 
         unsigned char, are three distinct types.
         * Byte Ptr maps to signed char *
         * UByte Ptr maps to unsigned char *
         * On some platforms the variable argument list va_list type is a 
           typed as a char *, but FB does not have an equivalent type, 
           therefore Any Ptr is used instead.  Linking with names encoded 
           with this type will fail since, normally, FB encodes void * data 
           type instead of char *.
         * alias "char" keeps the any ptr behaviour in FB but then encodes 
           the public name as char * for linking.

      any alias "__builtin_va_list" ptr
         Maps the data type to gcc's __builtin_va_list type
         * expected that gcc's built-in type is a pointer type
         * used on dos, win32, win64, linux-x86, targets
         * see Cvalist for default usage in the cva_list data type

      alias "__builtin_va_list"
         Maps the data type to gcc's __builtin_va_list type
         * expected that gcc's built-in type is a struct type
         * used on aarch64 target
         * see Cvalist for default usage in the cva_list data type

      alias "__builtin_va_list[]"
         Maps the data type to gcc's __builtin_va_list type
         * expected that gcc's built-in type is a struct array type
         * used on linux-x86_64 target
         * see Cvalist for default usage in the cva_list data type

   Data Type Mapping Details

   On all targets, FB to c/c++:
   Several of FB's data types are consistently mapped across all targets:
      * 8-bit Byte maps to signed char
      * 8-bit UByte maps to unsigned char
      * 16-bit Short maps to [signed] short [int]
      * 16-bit UShort maps to unsigned short [int]
      * 32-bit Long maps to int
      * 32-bit ULong maps to unsigned int
      * 64-bit LongInt maps to long long [int]
      * 64-bit ULongInt maps to unsigned long long [int]

   On Dos/Win/Linux 32-bit targets, FB to c/c++:
   Integer on 32-bit targets is 32-bits wide
      * 32-bit Integer maps to long [int]
      * 32-bit UInteger maps to unsigned long [int]

   On Linux 64-bit targets, FB to c/c++:
   Integer on 64-bit targets is 64-bits wide
      * 64-bit Integer maps to long [int]
      * 64-bit UInteger maps to unsigned long [int]

   On Win 64-bit targets, FB to c/c++:
   Integer on 64-bit targets is 64-bits wide.  However, on Win target, 
   c/c++'s long int type is 32-bit, not 64-bit, and we can't use the long 
   long int mangling because it's already used by FB's LongInt type.  
   Reusing the same mangling (decoration) for two different data types 
   would cause function overloading to fail or have duplicate definitions.  
   To preserve FB's behaviour that Integer on 64-bit targets is always 
   64-bits, we mangle (decorate) the symbol with a custom datatype and keep 
   the size at 64-bit.  
      * 64-bit Integer maps to custom INTEGER
      * 64-bit UInteger maps to custom UINTEGER
      To create a data type in FB that will map to c/c++'s long [int] 
      32-bit on win, we must use alias modifier.
      * 32-bit Long alias "long"  maps to long [int]
      * 32-bit ULong alias "long"  maps to unsigned long [int]

      For example extern c++ : declare sub proc( byval as long alias "long" 
      ) : end extern.  This allows FreeBASIC to call external c++ 
      procedures (on win-64) requiring a 32-bit long int type.  Usage of 
      Alias in this way affects win-64 targets only, and is ignored on all 
      other targets.

Differences from QB
   * In QB, Alias only worked with Declare.

See also
   * Alias (Name)
   * Declare
   * Export
   * Type (Alias)



--------------------------------------------------------- KeyPgAllocate ----
Allocate

Allocates a block of memory from the free store

Syntax
   Declare Function Allocate cdecl ( ByVal count As UInteger ) As Any Ptr

Usage
   result = Allocate( count )

Parameters
   count
      The size, in bytes, of the block of memory to allocate.

Return Value
   If successful, the address of the start of the allocated memory is 
   returned. Otherwise, if the requested block size could not be allocated, 
   or if count < 0, then the null pointer (0) is returned.

Description
   Attempts to allocate, or reserve, count number of bytes from the free 
   store (heap). The newly allocated memory is not initialized.

   As the initial value of newly allocated memory is unspecified, Allocate 
   must not be directly used with String or Udt containing string, because 
   the string descriptor being not cleared (containing random data), that 
   may induce corrupted string or more (trying to write to a random place 
   in memory or trying to deallocate a random pointer).  It is mandatory in 
   that case (with string or UDT containing string) to use CAllocate 
   (clearing memory), or New Expression (calling constructor) in case of 
   UDT, or at worst after Allocate to explicitly clear the descriptor 
   (setting to 0) before the first string use.
   For allocating memory for a ZString or a WString, see the corresponding 
   page.

   The pointer that is returned is an Any Ptr and points to the start of 
   the allocated memory. This pointer is guaranteed to be unique, even if 
   count is zero.

   Allocated memory must be deallocated, or returned back to the free 
   store, with Deallocate when no longer needed. 

Example
   '' This program uses the ALLOCATE(...) function to create a buffer of 15 integers that is
   '' then filled with the first 15 numbers of the Fibonacci Sequence, then output to the
   '' screen. Note the call to DEALLOCATE(...) at the end of the program.

      Const integerCount As Integer = 15

      '' Try allocating memory for a number of integers.
      ''
      Dim buffer As Integer Ptr
      buffer = Allocate(integerCount * SizeOf(Integer))

      If (0 = buffer) Then
         Print "Error: unable to allocate memory, quitting."
         End -1
      End If

      '' Prime and fill the memory with the fibonacci sequence.
      ''
      buffer[0] = 0
      buffer[1] = 1
      For i As Integer = 2 To integerCount - 1
         buffer[i] = buffer[i - 1] + buffer[i - 2]
      Next

      '' Display the sequence.
      ''
      For i As Integer = 0 To integerCount - 1
         Print buffer[i] ;
      Next

      Deallocate(buffer)
      End 0

   Output is:
    0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

   It is important to free allocated memory if it's not going to be used 
   anymore. Unused memory that isn't freed is simply wasting memory, and if 
   the address of that memory is somehow overwritten or forgotten, that 
   memory can never be freed. This condition is known as a memory leak, and 
   should be avoided at all costs. Note that leaked memory is always 
   completely freed when the application terminates, either by an 
   "ordinary" exit or crash, so the leak "persists" only as long as the 
   application runs, nevertheless it's a good habit to free any allocated 
   memory inside your application. The following example demonstrates a 
   function with a memory leak, where the address of allocated memory is 
   lost and isn't and can't be freed anymore. If such a function is called 
   frequently, the total amount of memory wasted can add up quickly.

   '' Bad example of Allocate usage, causing memory leaks

   Sub BadAllocateExample()

      Dim p As Byte Ptr

      p = Allocate(420)   '' assign pointer to new memory

      p = Allocate(420)   '' reassign same pointer to different memory,
                     '' old address is lost and that memory is leaked

      Deallocate(p)

   End Sub

      '' Main
      BadAllocateExample() '' Creates a memory leak 
      Print "Memory leak!"
      BadAllocateExample() '' ... and another
      Print "Memory leak!"
      End

Platform Differences
   * This procedure is not guaranteed to be thread-safe.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Allocate 

Differences from QB
   * New to FreeBASIC

See also
   * CAllocate
   * Reallocate
   * Deallocate



--------------------------------------------------------- KeyPgAlphaGfx ----
Alpha

Parameter to the Put graphics statement which selects alpha blending as the 
method

Syntax
   Put [ target, ] [ STEP ] ( x,y ), source [ ,( x1,y1 )-( x2,y2 ) ], Alpha
   Put [ target, ] [ STEP ] ( x,y ), source [ ,( x1,y1 )-( x2,y2 ) ], Alpha
   , alphaval

Parameters
   Alpha
      Required.
   alphaval
      Optional alpha parameter in the range [0..255].  Overrides alpha 
      values in individual pixels.

Description
   Alpha selects alpha blending as the method for Putting an image.  If the 
   alphaval parameter is specified, it overrides the alpha value of each 
   pixel, and the mask color (magenta) will be treated as transparent.  
   This works in 15, 16, 24, or 32-bit color depths.

   If alphaval is not specified, Alpha will only work in 32-bit color 
   depth, and Put will use the alpha value embedded within each pixel.  
   Pixels using the mask color will be treated as normal, and drawn with 
   their given alpha value.

   Alpha also has another mode which allows an 8-bit image to be Put on top 
   of a 32-bit image.  In this case, it will replace the alpha channel of 
   the 32-bit image with the contents of the 8-bit image.

      Alpha values range between 0 and 255.  An alpha value of 0 will not 
      draw the image at all.  All other alpha values are incremented by 1 
      to get a range between 2 and 256, and the result is then divided by 
      256 to get a value between 1/128 and 1, which is used to calculate 
      the exact value of each pixel from the source and destination pixels. 
      Thus, 255 is practically equivalent to drawing using Put with Trans 
      blitting mode, 0 is equivalent to doing nothing at all, and all the 
      other alpha values blend is expected.

Example
   This example compares the two different Alpha modes, including how they 
   react to the mask color
   '' Set up a 32-bit screen
   ScreenRes 320, 200, 32

   '' Draw checkered background
   For y As Integer = 0 To 199
      For x As Integer = 0 To 319
         PSet (x, y), IIf((x Shr 2 Xor y Shr 2) And 1, RGB(160, 160, 160), RGB(128, 128, 128))
      Next x
   Next y

   '' Make image sprite for Putting
   Dim img As Any Ptr = ImageCreate(32, 32, RGBA(0, 0, 0, 0))
   For y As Single = -15.5 To 15.5
      For x As Single = -15.5 To 15.5
         Dim As Integer r, g, b, a
         If y <= 0 Then
            If x <= 0 Then
               r = 255: g = 0: b = 0   '' red
            Else
               r = 0: g = 0: b = 255   '' blue
            End If
         Else
            If x <= 0 Then
               r = 0: g = 255: b = 0   '' green
            Else
               r = 255: g = 0: b = 255 '' magenta (transparent mask color)
            End If
         End If
         a = 255 - (x ^ 2 + y ^ 2)
         If a < 0 Then a = 0': r = 255: g = 0: b = 255
         PSet img, (15.5 + x, 15.5 - y), RGBA(r, g, b, a)
      Next x
   Next y

   '' Put with single Alpha value, Trans for comparison
   Draw String (32, 10), "Single alpha"
   Put (80 - 16,  50 - 16), img, Alpha, 64
   Put (80 - 16, 100 - 16), img, Alpha, 192
   Put (80 - 16, 150 - 16), img, Trans

   '' Put with full Alpha channel
   Draw String (200, 10), "Full alpha"
   Put (240 - 16, 100 - 16), img, Alpha

   '' Free the image memory
   ImageDestroy img

   '' Wait for a keypress
   Sleep

   This example shows the special method for setting a 32-bit alpha channel 
   using an 8-bit image
   Dim As Any Ptr img8, img32
   Dim As Integer x, y, i

   '' Set up an 8-bit graphics screen
   ScreenRes 320, 200, 8
   For i = 0 To 255
      Palette i,  i, i, i
   Next i
   Color 255, 0

   '' Create an 8-bit image
   img8 = ImageCreate(64, 64, 0,  8)
   For y = 0 To 63
      For x = 0 To 63
         Dim As Single x2 = x - 31.5, y2 = y - 31.5
         Dim As Single t = Sqr(x2 ^ 2 + y2 ^ 2) / 5
         PSet img8, (x, y), Sin(t) ^ 2 * 255
      Next x
   Next y

   Draw String (16, 4), "8-bit Alpha sprite"
   Put (16, 16), img8
   Sleep

   '' Set up a 32-bit graphics screen
   ScreenRes 320, 200, 32
   For y = 0 To 199
      For x = 0 To 319
         PSet (x, y), IIf(x - y And 3, RGB(160, 160, 160), RGB(128, 128, 128))
      Next x
   Next y

   '' Create a 32-bit, fully opaque sprite
   img32 = ImageCreate(64, 64, 0, 32)
   For y = 0 To 63
      For x = 0 To 63
         PSet img32, (x, y), RGB(x * 4, y * 4, 128)
      Next x
   Next y

   Draw String (16, 4), "Original Alpha channel"
   Put (16, 16), img32, Alpha

   '' Put a new alpha channel using the 8-bit image
   Put img32, (0, 0), img8, Alpha

   Draw String (16, 104), "New Alpha channel"
   Put (16, 116), img32, Alpha

   ''Free the memory for the two images
   ImageDestroy img8
   ImageDestroy img32

   Sleep

Differences from QB
   * New to FreeBASIC

See also
   * Put (Graphics)
   * Trans
   * Custom



------------------------------------------------------------ KeyPgOpAnd ----
Operator And (Conjunction)

Returns the bitwise-and (conjunction) of two numeric values

Syntax
   Declare Operator And ( ByRef lhs As T1, ByRef rhs As T2 ) As Ret

Usage
   result = lhs And rhs

Parameters
   lhs
      The left-hand side expression.
   T1
      Any numeric or boolean type.
   rhs
      The right-hand side expression.
   T2
      Any numeric or boolean type.
   Ret
      A numeric or boolean type (varies with T1 and T2).

Return Value
   Returns the bitwise-and (conjunction) of the two operands.

Description
   This operator returns the bitwise-and of its operands, a logical 
   operation that results in a value with bits set depending on the bits of 
   the operands (for conversion of a boolean to an integer, false or true 
   boolean value becomes 0 or -1 integer value).

   The truth table below demonstrates all combinations of a boolean-and 
   operation:

      +-------+-------+------+
      |Lhs Bit|Rhs Bit|Result|
      |0      |0      |0     |
      |1      |0      |0     |
      |0      |1      |0     |
      |1      |1      |1     |
      +-------+-------+------+

   No short-circuiting is performed - both expressions are always 
   evaluated.

   The return type depends on the types of values passed. Byte, UByte and 
   floating-point type values are first converted to Integer. If the left 
   and right-hand side types differ only in signedness, then the return 
   type is the same as the left-hand side type (T1), otherwise, the larger 
   of the two types is returned. Only if the left and right-hand side types 
   are both Boolean, the return type is also Boolean.

   This operator can be overloaded for user-defined types.

Example
   ' Using the AND operator on two numeric values
   Dim As UByte numeric_value1, numeric_value2
   numeric_value1 = 15 '00001111
   numeric_value2 = 30 '00011110

   'Result =  14  =     00001110
   Print numeric_value1 And numeric_value2
   Sleep

   ' Using the AND operator on two conditional expressions
   Dim As UByte numeric_value1, numeric_value2
   numeric_value1 = 15
   numeric_value2 = 25

   If numeric_value1 > 10 And numeric_value1 < 20 Then Print "Numeric_Value1 is between 10 and 20"
   If numeric_value2 > 10 And numeric_value2 < 20 Then Print "Numeric_Value2 is between 10 and 20"
   Sleep

   ' This will output "Numeric_Value1 is between 10 and 20" because
   ' both conditions of the IF statement is true
   ' It will not output the result of the second IF statement because the first
   ' condition is true and the second is false.

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * None

See also
   * AndAlso
   * Operator Truth Tables



-------------------------------------------------------- KeyPgOpAndAlso ----
Operator Andalso (Short Circuit Conjunction)

Returns the short circuit-and (conjunction) of two numeric values

Syntax
   Declare Operator AndAlso ( ByRef lhs As T1, ByRef rhs As T2 ) As Ret

Usage
   result = lhs AndAlso rhs

Parameters
   lhs
      The left-hand side expression.
   T1
      Any numeric or boolean type.
   rhs
      The right-hand side expression.
   T2
      Any numeric or boolean type.
   Ret
      A numeric or boolean type (varies with T1 and T2).

Return Value
   Returns the short circuit-and (conjunction) of the two operands.

Description
   This operator evaluates the left hand side expression.  If the result is 
   zero, then zero is immediately returned.  If the result is nonzero then 
   the right hand side is evaluated, and the logical result from that is 
   returned.
   (for conversion of a boolean to an integer, false or true boolean value 
   becomes 0 or -1 integer value) 

   The truth table below demonstrates all combinations of a short 
   circuit-and operation, the '-' denotes that the operand is not 
   evaluated.

      +---------+---------+------+
      |Lhs Value|Rhs Value|Result|
      |0        |-        |0     |
      |nonzero  |0        |0     |
      |nonzero  |nonzero  |-1    |
      +---------+---------+------+

   Short-circuiting is performed - only expressions needed to calculate the 
   result are evaluated.  The left hand side lhs is evaluated first, and 
   only if it evaluates to non-zero (true) is the right hand side rhs also 
   evaluated.  If the left hand side evaluation lhs returns zero (false), 
   it is known that at that point that the overall condition is false, so 
   the right hand side rhs is not evaluated (skipped).

   The return type is almost always an Integer, of the value 0 or -1, 
   denoting false and true respectively. Except if the left and right-hand 
   side types are both Boolean, then the return type is also Boolean.

   This operator cannot be overloaded for user-defined types.

Example
   '' Using the ANDALSO operator to guard against array access
   '' when the index is out of range

   Dim As Integer isprime(1 To 10) = { _
      _ ' 1  2  3  4  5  6  7  8  9  10
         0, 1, 1, 0, 1, 0, 1, 0, 0, 0 _
      }

   Dim As Integer n
   Input "Enter a number between 1 and 10: ", n

   '' isprime() array will only be accessed if n is in range
   If (n >= 1 And n <= 10) AndAlso isprime(n) Then
      Print "n is prime"
   Else
      Print "n is not prime, or out of range"
   End If

Differences from QB
   * This operator was not available in QB.

See also
   * OrElse
   * And
   * Operator Truth Tables



----------------------------------------------------------- KeyPgAndGfx ----
And

Parameter to the Put graphics statement which uses a bit-wise And as the 
blitting method

Syntax
   Put [ target, ] [ STEP ] ( x,y ), source [ ,( x1,y1 )-( x2,y2 ) ], And

Parameters
   And
      Required.

Description
   The And method combines each source pixel with the corresponding 
   destination pixel, using the bit-wise And function.  The result of this 
   is output as the destination pixel.
   This method works in all graphics modes.  There is no mask color, 
   although color values with all bits set (255 for 8-bit palette modes, or 
   RGBA(255, 255, 255, 255) in full-color modes) will have no effect, 
   because of the behavior of And.

   In full-color modes, each component (red, green, blue and alpha) is kept 
   in a discrete set of bits, so the operation can be made to only affect 
   some of the channels, by making sure the all the values of the other 
   channels are set to 255.

Example
   ''open a graphics window
   ScreenRes 320, 200, 16
   Line (0, 0)-(319, 199), RGB(255, 255, 255), bf

   ''create 3 sprites containing cyan, magenta and yellow circles
   Const As Integer r = 32
   Dim As Any Ptr cc, cm, cy
   cc = ImageCreate(r * 2 + 1, r * 2 + 1, RGBA(255, 255, 255, 255))
   cm = ImageCreate(r * 2 + 1, r * 2 + 1, RGBA(255, 255, 255, 255))
   cy = ImageCreate(r * 2 + 1, r * 2 + 1, RGBA(255, 255, 255, 255))
   Circle cc, (r, r), r, RGB(0, 255, 255), , , 1, f
   Circle cm, (r, r), r, RGB(255, 0, 255), , , 1, f
   Circle cy, (r, r), r, RGB(255, 255, 0), , , 1, f

   ''put the three sprites, overlapping each other in the middle
   Put (146 - r, 108 - r), cc, And
   Put (174 - r, 108 - r), cm, And
   Put (160 - r,  84 - r), cy, And

   ''free the memory used by the sprites
   ImageDestroy cc
   ImageDestroy cm
   ImageDestroy cy

   ''pause the program before closing
   Sleep

Differences from QB
   * None

See also
   * And
   * Put (Graphics)



-------------------------------------------------------------- KeyPgAny ----
Any

The Any keyword is used as a placeholder for a type or value in various 
ways.

Syntax
   Dim identifier As Any Pointer|Ptr
or
   Declare Sub|Function identifier ( ByRef identifier As Any [ , ... ] )
or
   Dim identifier(Any [, Any...]) As DataType
or
   [ Declare ] { Sub | Function } proc_name ( param(Any [, Any...]) As 
   DataType  )
or
   Dim identifier As DataType = Any
or
   New DataType ( Any )
or
   New(Address) DataType [count] { Any }
or
   InStr|InStrRev ( string, Any substring )

Description
   * Pointers:
      A special pointer type called the Any Ptr (or "Any Pointer") allows 
      pointing to any variable type.  If you cast it to a DataType Ptr, it 
      can be indexed or dereferenced to access the memory as an instance of 
      DataType. Pointer arithmetic is allowed on an Any Ptr, and treats it 
      like a Byte Ptr: The pointer is changed by increments of 1.

      A pure Any Ptr has no type checking by the compiler.  It can be 
      implicitly converted to and from other pointer types through 
      assignment or parameter passing.

      Any on its own is not a valid data type for a variable. Also, it is 
      illegal to dereference an Any Ptr (although an Any Ptr Ptr may be 
      dereferenced to produce a Any Ptr).

      This should not be confused with Variant, a Visual Basic data type 
      which can contain any type of variable. FreeBASIC does not provide 
      native support for a Variant type.

   * Byref parameters:
      Any can be used in procedure prototypes (in a Declare statement) with 
      ByRef parameters to disable the compiler checking for the correct 
      type of the variable passed. This use of Any is deprecated and it 
      only exists for compatibility with QB.

   * Array dimensions:
      In array declarations, Any can be specified in place of the array 
      bounds in order to create a dynamic array with a certain amount of 
      dimensions that is determined based on the number of Anys specified 
      (use the syntax with Any is mandatory when declaring a dynamic array 
      member inside a Type).

      In parameter declarations, Any can be also specified instead of empty 
      parenthesis in order to fix the amount of dimensions.

   * Initialization:
      Any can be used as a fake initializer to disable the default 
      initialization of variables to 0, leaving the variable uninitialized. 
      This may save time in critical sections of a program. It is the 
      program's responsibility to fill the variables with meaningful data 
      before reading it.

      Comparison to C/C++: This matches the behavior of a variable 
      declaration without initialization value in C/C++.

      Similar to Any initializers for variables, Any can also be used with 
      the New Expression or Placement New operators in order to leave the 
      newly created object uninitialized (only allowed with data types that 
      do not have constructors).

   * Instr/InstrRev:
      Any can be used with InStr or InStrRev as a qualifier for the 
      substring parameter, to indicate that any individual character in it 
      may be matched.

Example
   Declare Sub echo(ByVal x As Any Ptr) '' echo will accept any pointer type

   Dim As Integer a(0 To 9) = Any '' this variable is not initialized
   Dim As Double  d(0 To 4)

   Dim p As Any Ptr

   Dim pa As Integer Ptr = @a(0)
   Print "Not initialized ";
   echo pa       '' pass to echo a pointer to integer

   Dim pd As Double Ptr = @d(0)
   Print "Initialized ";
   echo pd       '' pass to echo a pointer to double

   p = pa     '' assign to p a pointer to integer
   p = pd     '' assign to p a pointer to double      

   Sleep

   Sub echo (ByVal x As Any Ptr)
      Dim As Integer i
      For i = 0 To 39
         'echo interprets the data in the pointer as bytes
         Print Cast(UByte Ptr, x)[i] & " ";
      Next
      Print
   End Sub

   'Example of ANY disabling the variable type checking
   Declare Sub echo (ByRef a As Any) '' ANY disables the checking for the type of data passed to the function

   Dim x As Single
   x = -15
   echo x                  '' Passing a single to a function that expects an integer. The compiler does not complain!!             
   Sleep

   Sub echo (ByRef a As Integer)
     Print Hex(a)         
   End Sub

   Dim a(Any) As Integer ' 1-dimensional dynamic array
   Dim b(Any, Any) As Integer ' 2-dimensional dynamic array
   Dim c(Any, Any, Any) As Integer ' 3-dimensional dynamic array
   ' etc.

   ' Further Redims or array accesses must have a matching amount of dimensions
   ReDim a(0 To 1)
   ReDim b(1 To 10, 2 To 5)
   ReDim c(0 To 9, 0 To 5, 0 To 1)

Dialect Differences
   * Not available in the -lang qb dialect.

Differences from QB
   * Pointers and initializers are new to FreeBASIC.

See also
   * Dim
   * Declare



----------------------------------------------------------- KeyPgAppend ----
Append

Specifies text file to be opened for append mode

Syntax
   Open filename for Append [Encoding encoding_type] [Lock lock_type] as 
   [#]filenum 

Parameters
   filename
      file name to open for append
   encoding_type
      indicates encoding type for the file
   lock_type
      locking to be used while the file is open
   filenum
      unused file number to associate with the open file

Description
   A file mode used with Open to open a text file for writing.

   This mode is used to add text to an existing file  with Print #, or 
   comma separated values with Write#.

   Text files can't be simultaneously read and written in FreeBASIC, so if 
   both functions are required on the same file, it must be opened twice.

   filename must be a string expression resulting in a legal file name in 
   the target OS, without wildcards. The file will be sought for in the 
   present directory, unless the filename contains a path . If the file 
   does not exist, it is created. The pointer is set after the last 
   character of the file.

   Encoding_type indicates the Unicode Encoding of the file, so characters 
   are correctly read. If omitted, "ascii" encoding is defaulted. Only 
   little endian character encodings are supported at the moment. 
      *"utf8"
      *"utf16"
      *"utf32"
      *"ascii" (the default)

   Lock_type indicates the way the file is locked  for other processes, it 
   is one of:
      * Read - the file can be opened simultaneously by other processes, 
        but not for reading
      * Write - the file can be opened simultaneously by other processes, 
        but not for writing
      * Read Write - the file cannot be opened simultaneously by other 
        processes (the default)

   filenum Is a valid FreeBASIC file number (in the range 1..255) not being 
   used for any other file presently open. The file number identifies the 
   file for the rest of file operations. A free file number can be found 
   using the FreeFile function.

Example
   Dim i As Integer
   For i = 1 To 10
      Open "test.txt" For Append As #1
      Print #1, "extending test.txt"
      Close #1
   Next

Differences from QB
   * None

See also
   * Input (File Mode)
   * Open
   * Output
   * Print #
   * ? #
   * Write #



--------------------------------------------------------------- KeyPgAs ----
As

Part of a declaration which specifies a data type, or part of the Open 
statement which specifies a file handle.

Syntax
   symbolname As datatype

   Open ... As #filenumber
   Type ... As datatype

Description
   As is used to declare the type of variables, fields or arguments and is 
   also used in the Open statement to determine the file handle. As is also 
   used with the Type (Alias) syntax, similar to C's typedef statement.

Example
   '' don't try to compile this code, the examples are unrelated
   Declare Sub mySub (X As Integer, Y As Single, Z As String)
   ' ...

   Dim X As Integer
   ' ...

   Type myType
     X As Integer
     Y As Single
     Z As String
   End Type
   ' ...

   Type TheNewType As myType
   ' ...

   Open "test" For Input As #1
   ' ...

Differences from QB
   * The Type (Alias) syntax was not supported in QB.

See also
   * Declare
   * Dim
   * Type
   * Open



-------------------------------------------------------------- KeyPgAsc ----
Asc

Returns the corresponding ASCII or Unicode integer representation of a 
character

Syntax
   Declare Function Asc ( ByRef str As Const String, ByVal position As 
   Integer = 1 ) As ULong
   Declare Function Asc ( ByVal str As Const ZString Ptr, ByVal position As 
   Integer = 1 ) As ULong
   Declare Function Asc ( ByVal str As Const WString Ptr, ByVal position As 
   Integer = 1 ) As ULong

Usage
   result = Asc( str [, position ] )

Parameters
   str
      The source string.
   position
      The position in the string of a character.

Return Value
   The raw character value stored at position in str.
   If both str and position can be evaluated at compile time (like Asc("a") 
   or Asc(chr(97)) or Asc("abc", 2) ...), the value is returned in a 
   UInteger result, otherwise in a ULong result.

Description
   If str is a String or a ZString, the UByte value at that position is 
   returned. This will be a 7-bit ASCII code, or even a 8-bit character 
   value from some code-page, depending on the string data stored in str.

   If str is a WString, the UShort (Windows) or ULong (Linux) value at that 
   position is returned. This will be a 16bit value on Windows (WStrings 
   use UTF16 there), or a 32bit value on Linux (WStrings use UTF32 there).

   The function returns zero (0) if the string is a zero length string, 
   position is less than one (1), or position is greater than the number of 
   characters in str.

   Chr performs the opposite function for ASCII strings, while WChr is the 
   opposite for Unicode strings, returning a string containing the 
   character represented by the code passed as an argument.

Example
   Print "the ascii code of 'a' is:"; Asc("a")
   Print "the ascii code of 'b' is:"; Asc("abc", 2)

   will produce the output:

   the ascii code of 'a' is: 97
   the ascii code of 'b' is: 98

Unicode example (Note to documentation editors: don't put inside %%(qbasic) 
markers or the Russian text will disappear!)

dim a as wstring * 12
a = "&#1055;&#1088;&#1080;&#1074;&#1077;&#1090;, &#1084;&#1080;&#1088;"
print "the Unicode of the second char of " & a & " is: " & asc(a, 2)
	will produce the output:
the Unicode of the second char of 
&#1055;&#1088;&#1080;&#1074;&#1077;&#1090;, &#1084;&#1080;&#1088; is: 1088

Platform Differences
   * DOS does not support the wide-character string version of Asc.

Differences from QB
   * The optional position argument is new to FreeBASIC.
   * QB does not support the wide-character string version of Asc

See also
   * ASCII Character Codes
   * Chr
   * Str
   * Val



------------------------------------------------------------- KeyPgAsin ----
Asin

Finds the arcsine of a number

Syntax
   Declare Function Asin ( ByVal number As Double ) As Double

Usage
   result = Asin( number )

Parameters
   number
      Sine value in the range [-1..1].

Return Value
   The arcsine of number, in radians, in the range [-Pi/2..Pi/2].

Description
   Asin returns the arcsine of the argument number as a Double within the 
   range of -Pi/2 to Pi/2.  The arcsine is the inverse of the Sin function. 
   The returned angle is measured in radians (not degrees).

   Asin can be overloaded as operator to accept user-defined types.

Example
   Dim h As Double
   Dim o As Double
   Input "Please enter the length of the hypotenuse of a triangle: ", h
   Input "Please enter the length of the opposite side of the triangle: ", o
   Print ""
   Print "The angle between the sides is"; Asin ( o / h )
   Sleep

The output would look like:

   Please enter the length of the hypotenuse of a triangle: 5
   Please enter the length of the opposite side of the triangle: 3
   The angle between the sides Is 0.6435011087932844

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Asin.

Differences from QB
   * New to FreeBASIC

See also
   * Sin
   * A Brief Introduction To Trigonometry



-------------------------------------------------------------- KeyPgAsm ----
Asm

Code block that allows the use of architecture-specific instructions.

Syntax
   Asm
      architecture-dependent instructions
   End Asm

      Or

   Asm architecture-dependent instructions

Description
   The Asm block is used to insert specific machine-code instructions in a 
   program in order to perform operations that cannot be carried out using 
   the features of the language or to hand-optimize performance-sensitive 
   sections of code.

   The current FreeBASIC compiler currently only produces code for Intel 
   80x86-based machines; however, in the future, the compiler might be 
   ported to a platform which does not support the same instruction set.  
   Therefore, Asm blocks should only be used when necessary, and a 
   FreeBASIC-only alternative should be provided if possible.

   The return value of a function may be set by using the Function keyword 
   within brackets as shown in the example below.

   Asm block comments have the same syntax as usual FreeBASIC Comments  - 
   use FreeBASIC-like " ' " comments, not " ; " as usual in assembly code. 

   x86 Specific:

      Syntax
         The syntax of the inline assembler is a simplified form of Intel 
         syntax.  Intel syntax is used by the majority of x86 assemblers, 
         such as MASM, TASM, NASM, YASM and FASM. In general, the 
         destination of an instruction is placed first, followed by the 
         source. Variables and functions defined by a program may be 
         referenced in an Asm block.  The assembler used by FreeBASIC is 
         GAS, using the .intel_syntax noprefix directive, and Asm blocks 
         are passed through unmodified, except for the substitution of 
         local variable names for stack frame references, and commenting 
         removal.

         Instruction syntax is mostly the same as FASM uses, one important 
         difference is that GAS requires size settings to be followed by 
         the word "ptr".

   ' Assuming "n" is a FB global or local ULONG variable
   mov  eax, [n]        ' OK: size is apparent from eax
   inc  [n]             ' Not OK: size is not given
   inc  dword [n]       ' Not OK: size given, but still not accepted by GAS
   inc  dword Ptr [n]   ' OK: "ptr" is needed by GAS here

      Register Preservation
         When an Asm block is opened, the registers ebx, esi, and edi are 
         pushed to the stack, when the block is closed, these registers are 
         popped back from the stack.  This is because these registers are 
         required to be preserved by most or all OS's using the x86 CPU.  
         You can therefore use these registers without explicitly 
         preserving them yourself. You should not change esp and ebp, since 
         they are usually used to address local variables. 

      Register Names
         The names of the registers for the x86 architecture are written as 
         follows in an Asm block:
         * 4-byte integer registers: eax, ebx, ecx, edx, ebp, esp, edi, 
           esi
         * 2-byte integer registers: ax, bx, cx, dx, bp, sp, di, si (low 
           words of 4-byte e- registers)
         * 1-byte integer registers: al, ah, bl, bh, cl, ch, dl, dh (low 
           and high bytes of 2-byte -x registers)
         * Floating-point registers: st(0), st(1), st(2), st(3), st(4), 
           st(5), st(6), st(7)
         * MMX registers (aliased onto floating-point registers): mm0, mm1
           , mm2, mm3, mm4, mm5, mm6, mm7
         * SSE registers: xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7

      Instruction Set

      See these external references:
         * Original Intel 80386 manual from 1986
         * Latest Intel Pentium 4 manuals
         * NASM x86 Instruction Reference (Please note that NASM is not 
           the assembler used by FreeBASIC, but this page provides a good 
           overview of x86 instructions)

      Unsafe instructions
         Note that the FreeBASIC compiler produces 32-bit protected-mode 
         code for the x86 which usually runs in an unprivileged user level; 
         therefore, privileged and sensitive instructions will assemble 
         fine, but possibly won't work correctly or cause a runtime 
         "General Protection Fault", "Illegal instruction", or SIGILL 
         error. The following are the privileged and sensitive instructions 
         as of the Intel Pentium 4 and Xeon:

         * cli *1
         * clts
         * hlt
         * in *1
         * ins *1
         * int *1               
         * into *1               
         * invd
         * invlpg
         * lgdt
         * lidt
         * lldt
         * lmsw
         * ltr
         * mov to/from CRn, DRn, TRn
         * out *1
         * outs *1
         * rdmsr
         * rdpmc *2
         * rdtsc *2
         * sti *1
         * str
         * wbinvd
         * wrmsr
         * all SSE2 and higher instructions *2

          *1: sensitive to IOPL, fine in DOS 
          *2: sensitive to permission bits in CR4, see below

   The privileged instructions will work "correctly" in DOS when running on 
   a Ring 0 DPMI kernel, like the (non-default) Ring 0 version of CWSDPMI, 
   WDOSX or D3X, nevertheless most of them are not really useful and 
   dangerous when executed from DPMI code. RDTSC (Read Time Stamp Counter) 
   has been shown to be allowed by most, or all OS'es.

   However the usefulness of RDTSC has been diminished with the advent of 
   multi-core and hibernating CPUs. SSE2 and higher instructions are 
   disabled "by default" after CPU initialization, Windows and Linux 
   usually do enable them, in DOS it is business of the DPMI host: HDPMI32 
   will enable them, CWSDPMI won't. The INT instruction is usable in the 
   DOS version/target only, note that it works slightly differently from 
   real mode DOS, see also FaqDOS.

   The segment registers (cs, ds, es, fs, gs) should not be changed from an 
   Asm block, except in certain cases with the DOS port (note that they do 
   NOT work the same way as in real-mode DOS, see also FaqDOS). The 
   operating system or DPMI host is responsible for memory management; the 
   meaning of segments (selectors) in protected mode is very different from 
   real-mode memory addressing.

   Note that those "unsafe" instructions are not guaranteed to raise a 
   "visible" crash even when ran with insufficient privilege - the OS or 
   DPMI host can decide to "emulate" them, either functionally (reading 
   from some CRx works under HDPMI32), or "dummy" (nothing happens, 
   instruction will pass silently, like a NOP).

Example
   '' This is an example for the x86 architecture.
   Function AddFive(ByVal num As Long) As Long
      Asm
         mov eax, [num]
         Add eax, 5
         mov [Function], eax
      End Asm
   End Function

   Dim i As Long = 4

   Print "4 + 5 ="; AddFive(i)

   4 + 5 = 9

   FreeBASIC's Assembler is AS / GAS, the assembler of GCC, so an external 
   program. Some quirks apply:
      * The error lines  returned by FBC for Asm blocks are not related 
        the FB source file. As FBC simply displays the errors returned by 
        AS , the lines are related to the assembly file. To make FreeBASIC 
        preserve them, the compiler must be invoked with the -R option 
        ("don't delete ASM files").
      * The label names are case sensitive inside Asm blocks.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Asm.

Differences from QB
   * New to FreeBASIC

See also
   * Function
   * Naked



----------------------------------------------------------- KeyPgAssert ----
Assert

Debugging macro that halts program execution if an expression is evaluated 
to 0 (false).

Syntax
   #define Assert(expression) If (expression) = 0 Then : fb_Assert( __FILE__
   , __LINE__, __FUNCTION__, #expression ) : End If

Usage
   Assert( expression )

Parameters
   expression
      Any valid conditional/numeric expression.  If expression evaluates to 
      0 (i.e. "false"), execution is halted.

Description
   The Assert macro is intended for use in debugging and works only if the 
   -g or -eassert option is specified on the fbc command line. In this case 
   it prints an error message and stops the program execution if expression 
   evaluates to 0.

   Its normal use is to check the correct value of the variables or 
   expressions during debugging.

   If -g and -eassert are not passed to fbc, the macro does not generate 
   any code, and has no effect.

   Note: If an Assert fails while the program is in a graphics Screen, the 
   error message will not be visible as it will be printed to the graphics 
   screen, which will be closed immediately after.

Example
   Sub foo
    Dim a As Integer
    a=0
    Assert(a=1)
   End Sub

   foo 

   '' If -g or -eassert is used, this code stops with: test.bas(3): assertion failed at FOO: a=1 

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __ASSERT.

Differences from QB
   * New to FreeBASIC

See also
   * #assert
   * AssertWarn
   * Compiler Option: -eassert
   * Compiler Option: -g



------------------------------------------------------- KeyPgAssertwarn ----
AssertWarn

Debugging macro that prints a warning if an expression evaluates to 0.

Syntax
   #define AssertWarn(expression) If (expression) = 0 Then : fb_AssertWarn( 
   __FILE__, __LINE__, __FUNCTION__, #expression ) : End If

Usage
   AssertWarn( expression )

Parameters
   expression
      Any valid expression.  If expression evaluates to 0, a warning 
      message is printed to stderr (console).

Description
   The AssertWarn macro is intended for use in debugging and works only if 
   the -g option is selected in the FBC command line. In this case it 
   prints a warning message if expression evaluates to 0. It doesn't stop 
   the program execution like Assert does.

   Its normal use is to check the correct value of the variables during 
   debugging.

   If -g is not passed to fbc, the macro does not generate any code.

Example
   Sub foo
     Dim a As Integer
     a=0
     AssertWarn(a=1)
   End Sub

   foo 

   '' If -g is used this code prints: test.bas(3): assertion failed at FOO: a=1 

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __ASSERTWARN.

Differences from QB
   * New to FreeBASIC

See also
   * Assert



------------------------------------------------------------ KeyPgAtan2 ----
Atan2

Returns the arctangent of a ratio

Syntax
   Declare Function ATan2 ( ByVal y As Double, ByVal x As Double ) As Double

Usage
   result = ATan2( y, x )

Parameters
   y
      Vertical component of the ratio.
   x
      Horizontal component of the ratio.

Return Value
   The angle whose tangent is y/x, in radians, in the range [-Pi..Pi].

Description
   ATan2 returns the arctangent of the ratio y/x as a Double within the 
   range of -Pi to Pi.  The arctangent is the inverse of the Tan function. 
   The returned angle is measured in radians (not degrees).

   ATan2 cannot be overloaded as operator to accept user-defined types.

Example
   Print Atan2 ( 4, 5 )     'this is the same as PRINT ATN ( 4 / 5 )

The output would be:

   0.6747409422235527

Differences from QB
   * New to FreeBASIC

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Atan2.

See also
   * Tan
   * Atn
   * A Brief Introduction To Trigonometry



-------------------------------------------------------------- KeyPgAtn ----
Atn

Returns the arctangent of a number

Syntax
   Declare Function Atn ( ByVal number As Double ) As Double

Usage
   result = Atn( number )

Parameters
   number
      A number.

Return Value
   The angle, in radians, whose tangent is number, in the range 
   [-Pi/2..Pi/2].

Description
   Atn returns the arctangent of the argument number as a Double within the 
   range of -Pi/2 to Pi/2.  The arctangent is the inverse of the Tan 
   function. The returned angle is measured in radians (not degrees).

   Atn can be overloaded as operator to accept user-defined types.

Example
   Print "Pi ="; Atn ( 1.0 ) * 4
   Print Atn ( 4 / 5 )

The output would be:

   Pi = 3.141592653589793
   0.6747409422235527

Differences from QB
   * None

See also
   * Tan
   * Atan2
   * A Brief Introduction To Trigonometry




============================================================================
    B

--------------------------------------------------------- KeyPgBaseInit ----
Base (Initializer)

Specifies an initializer for the base UDT in derived Udt constructors

Syntax
   Base ( constructor-parameters... )
or:
   Base ( UDT-initializers... )

Description
   The Base initializer can be used at the top of constructors of derived 
   UDTs. It allows to specify an explicit constructor call or UDT 
   initializers to be used to initialize the base object. It will replace 
   the implicit default initialization, and must appear above any other 
   statements in the constructor it is used in.

   Note: Unlike "Base( )", a "Base.Constructor( )" statement does not 
   replace the implicit default initialization done by the constructor of a 
   derived UDT, and can usually not be used legally, because it would 
   result in two constructor calls for the base object (for an inheritance 
   structure extending the built-in Object type, this second base 
   constructor call may also corrupt the vtable pointer to point to the 
   base-type vtable instead of to the type vtable).

Example
   Type SimpleParent
      As Integer a, b, c
   End Type

   Type Child Extends SimpleParent
      Declare Constructor( )
   End Type

   Constructor Child( )
      '' Simple UDT initializer
      Base( 1, 2, 3 )
   End Constructor

   Type ComplexParent
      As Integer i
      Declare Constructor( ByVal As Integer = 0 )
   End Type

   Constructor ComplexParent( ByVal i As Integer = 0 )
      this.i = i
   End Constructor

   Type Child Extends ComplexParent
      Declare Constructor( )
      Declare Constructor( ByRef As Child )
   End Type

   Constructor Child( )
      '' Base UDT constructor call
      Base( 1 )
   End Constructor

   Constructor Child( ByRef rhs As Child )
      '' Base UDT constructor call
      Base( rhs.i )
   End Constructor

Dialect Differences
   * Methods are only supported in the -lang fb dialect, hence Base has no 
     function in other dialects.

Differences from QB
   * New to FreeBASIC

See also
   * Base (Member Access)
   * This
   * Type
   * Extends
   * Extends Zstring
   * Extends Wstring
   * Option Base



------------------------------------------------------------- KeyPgBase ----
Base (Member Access)

Provides explicit access to base type members in non-static methods of a 
Type

Syntax
   Base.member
   Base [ .Base ... ] .member

Description
   Base provides a way to explicitly access members of a specific base 
   type, in the context of non-static methods of a user-defined type 
   derived from another type using Extends.

   By using Base repeatedly, as in base.base.base.member, it is possible to 
   access any desired base type, in case there are multiple levels of 
   inheritance.

   Base is especially useful when a base type's member is shadowed by a 
   local variable or member of a derived type using the same identifier. 
   Base then allows unambiguous access to the base type.

   For virtual methods, base.method() always calls the base method and 
   never the overriding method.

Example
   Type Parent
      As Integer a
      Declare Constructor(ByVal As Integer = 0)
      Declare Sub show()
   End Type

   Constructor Parent(ByVal a As Integer = 0)
      This.a = a
   End Constructor

   Sub Parent.show()
      Print "parent", a
   End Sub

   Type Child Extends Parent
      As Integer a
      Declare Constructor(ByVal As Integer = 0)
      Declare Sub show()
   End Type

   Constructor Child(ByVal a As Integer = 0)
      '' Call base type's constructor
      Base(a * 3)
      This.a = a
   End Constructor

   Sub Child.show()
      '' Call base type's show() method, not ours
      Base.show()
      
      '' Show both a fields, the base type's and ours'
      Print "child", Base.a, a
   End Sub

   Type GrandChild Extends Child
      As Integer a
      Declare Constructor(ByVal As Integer = 0)
      Declare Sub show()
   End Type

   Constructor GrandChild(ByVal a As Integer = 0)
      '' Call base type's constructor
      Base(a * 2)
      This.a = a
   End Constructor

   Sub GrandChild.show()
      '' Call base type's show() method, not ours
      Base.show()
      
      '' Show both a fields, the base.base type's, the base type's and ours'
      Print "grandchild", Base.Base.a, Base.a, a
   End Sub

   Dim As GrandChild x = GrandChild(3)
   x.show()

Dialect Differences
   * Methods are only supported in the -lang fb dialect, hence Base has no 
     function in other dialects.

Differences from QB
   * New to FreeBASIC

See also
   * Base (Initializer)
   * This
   * Type
   * Extends
   * Extends Zstring
   * Extends Wstring
   * Option Base



------------------------------------------------------------- KeyPgBeep ----
Beep

Produces a beep sound.

Syntax
   Declare Sub Beep ( )

Usage
   Beep

Description
   Beep tells the system to sound a beep noise. Note that this might not 
   work on some platforms. Since this command is not reliable and there is 
   no way to specify the frequency and duration, you might want to avoid it 
   in favor of other / better solutions, for example: 
   http://www.freebasic.net/forum/viewtopic.php?p=20441#20441 by yetifoot.

Example
   Beep

Differences from QB
   *  In QB, this was a single tone noise generated through the PC 
     speaker. Now this might not be the case.

See also
   * Out - producing sound using CPU ports



-------------------------------------------------------------- KeyPgBin ----
Bin

Returns a binary (base 2) string representation of an integer

Syntax
   Declare Function Bin ( ByVal number As UByte ) As String
   Declare Function Bin ( ByVal number As UShort ) As String
   Declare Function Bin ( ByVal number As ULong ) As String
   Declare Function Bin ( ByVal number As ULongInt ) As String
   Declare Function Bin ( ByVal number As Const Any Ptr ) As String

   Declare Function Bin ( ByVal number As UByte, ByVal digits As Long ) As 
   String
   Declare Function Bin ( ByVal number As UShort, ByVal digits As Long ) As 
   String
   Declare Function Bin ( ByVal number As ULong, ByVal digits As Long ) As 
   String
   Declare Function Bin ( ByVal number As ULongInt, ByVal digits As Long ) 
   As String
   Declare Function Bin ( ByVal number As Const Any Ptr, ByVal digits As 
   Long ) As String

Usage
   result = Bin[$]( number [, digits ] )

Parameters
   number
      A number or expression evaluating to a number.  A floating-point 
      number will be converted to a LongInt.
   digits
      Desired number of digits in the returned string.

Return Value
   A string containing the unsigned binary representation of number.

Description
   Returns a string representing the unsigned binary value of the integer 
   number. Binary digits range from 0 to 1.

   If you specify digits > 0, the result string will be exactly that 
   length.  It will be truncated or padded with zeros on the left, if 
   necessary.

   The length of the string will not go longer than the maximum number of 
   digits required for the type of number (32 for a Long, 64 for a LongInt)
   .

   If you want to do the opposite, i.e. convert an binary string back into 
   a number, the easiest way to do it is to prepend the string with "&B", 
   and convert it to an integer type, using a function like CInt, similarly 
   to a normal numeric string.  E.g. CInt("&B101")

Example
   Print Bin(54321)
   Print Bin(54321, 5)
   Print Bin(54321, 20)

   will produce the output:

   1101010000110001
   10001
   00001101010000110001

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Bin.

Differences from QB
   * New to FreeBASIC

See also
   * Oct
   * Hex
   * ValInt
   * ValLng



----------------------------------------------------------- KeyPgBinary ----
Binary

Specifies file or device to be opened for binary mode

Syntax
   Open filename for Binary [Access access_type] [Lock lock_type] as [#]
   filenum 

Parameters
   filename
      file name to open
   access_type
      indicates whether the file may be read from, written to or both
   lock_type
      locking to be used while the file is open
   filenum
      unused file number to associate with the open file

Description
   Opens a file or device for reading and/or writing binary data in the 
   file filenum, with free format.
   If the file does not exist, a new file will be created. The file pointer 
   is initialized by Open at byte no. 1. 
   Get # and Put # file operations move the file pointer according to the 
   size of the data, the pointer can be set to any byte in the file.
   The data existing in the file is preserved by Open. 
   This file mode can use any buffer variable to read/write data in the 
   file.   
   The data is saved in binary mode, in the same internal format FreeBASIC 
   uses, by means of Get # and Put #.

   filename must be a string expression resulting in a legal file name in 
   the target OS, without wildcards. The file will be sought for in the 
   present directory, unless a path is given.

   Access_type By default Binary mode allows to both read and write the 
   file, unless an Access type is specified, it must be one of: 
      * Read - the file is opened for input only
      * Write - the file is opened for output only
      * Read Write - the file is opened for input and output (the default)

   Lock_type indicates the way the file is locked  for other processes 
   (users or threads), it is one of:
      * Shared - The file can be freely accessed by other processes     
      * Lock Read - The file can't be opened simultaneously for reading
      * Lock Write - The file can't be opened simultaneously for writing
      * Lock Read Write - The file cannot be opened simultaneously by 
        other processes.
      If no lock type is stated, the file will be Shared for other threads 
      of the program and Lock Read Write for other programs.
      Lock and Unlock can be used to restrict temporally access to parts of 
      a file.

   filenum is a valid file number (in the range 1..255) not being used for 
   any other file presently open. The file number identifies the file for 
   the rest of file operations. A free file number can be found using the 
   FreeFile function.

Example
   '' Create a binary data file with one number in it
   Dim x As Single = 17.164

   Open "MyFile.Dat" For Binary As #1
     '' put without a position setting will put from the last known file position
     '' in this case, the very beginning of the file.
     Put #1, , x
   Close #1

   '' Now read the number from the file
   Dim x As Single = 0

   Open "MyFile.Dat" For Binary As #1
     Get #1, , x
   Close #1

   Print x

   '' Read entire contents of a file to a string
   Dim txt As String

   Open "myfile.txt" For Binary Access Read As #1
     If LOF(1) > 0 Then
      '' our string has as many characters as the file has in bytes
      txt = String(LOF(1), 0)
      '' size of txt is known.  entire string filled with file data
      Get #1, , txt
     End If
   Close #1

   Print txt

Differences from QB
   * None

See also
   * Open
   * Put #
   * Get #
   * Random
   * Append
   * Output
   * Input



-------------------------------------------------------------- KeyPgBit ----
Bit

Gets the state of an individual bit in an integer value.

Syntax
   #define Bit( value, bit_number ) (((value) And (Cast(TypeOf(value), 1) 
   Shl (bit_number))) <> 0)

Usage
   result = Bit( value, bit_number )

Parameters
   value
      The integer value.
   bit_number
      The index of the bit.

Return Value
   Returns an Integer value of -1 if the bit is set, or 0 if the bit is 
   cleared.

Description
   This macro expands to an integer value indicating whether or not the bit 
   specified by bit_number is set in the integer value. Behaves as `(value 
   And 1 Shl bit_number) <> 0`.

   The valid range of values for bit_number depends on the size, in bits, 
   of `TypeOf(value)`, which is `0` (from the lowest bit) through `SizeOf(
   value) * 8 - 1` (up to the highest bit). See Standard Datatype Limits 
   for a table of the standard datatypes and their sizes.

Example
   Print Bit(4,2)
   Print Bit(5,1)
   Print Bit(&H8000000000000000ULL,63)

   will produce the output:


   -1
   0
   -1

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Bit.

Differences from QB
   * New to FreeBASIC

See also
   * BitSet
   * BitReset



--------------------------------------------------------- KeyPgBitreset ----
BitReset

Gets the value of an integer with a specified bit cleared.

Syntax
   #define BitReset( value, bit_number ) ((value) And Not (Cast(TypeOf(
   Value), 1) Shl (bit_number)))

Usage
   result = BitReset( value, bit_number )

Parameters
   value
      The integer value.
   bit_number
      The index of the bit to clear.

Return Value
   Returns the integer value with the specified bit cleared.

Description
   This macro expands to a copy of the integer value with the specified 
   bit_number cleared (to off, or `0`). Behaves as `value And Not (1 Shl 
   bit_number)`.

   The valid range of values for bit_number depends on the size, in bits, 
   of `TypeOf(value)`, which is `0` (from the lowest bit) through `SizeOf(
   value) * 8 - 1` (up to the highest bit). See Standard Datatype Limits 
   for a table of the standard datatypes and their sizes.

Example
   Print BitReset(5,0)
   Print Hex(BitReset(&h8000000000000001,63))

   will produce the output:

    4
   1

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Bitreset.

Differences from QB
   * New to FreeBASIC.

See also
   * Bit
   * BitSet



----------------------------------------------------------- KeyPgBitset ----
BitSet

Gets the value of an integer with a specified bit set.

Syntax
   #define BitSet( value, bit_number ) ((value) Or (Cast(TypeOf(Value), 1) 
   Shl (bit_number)))

Usage
   result = BitSet( value, bit_number )

Parameters
   value
      The integer value.
   bit_number
      The index of the bit to set.

Return Value
   Returns the integer value with the specified bit set.

Description
   This macro expands to a copy of the integer value with the specified 
   bit_number set (to on, or `1`). Behaves as `value Or (1 Shl bit_number)
   `.

   The valid range of values for bit_number depends on the size, in bits, 
   of `TypeOf(value)`, which is `0` (from the lowest bit) through `SizeOf(
   value) * 8 - 1` (up to the highest bit). See Standard Datatype Limits 
   for a table of the standard datatypes and their sizes.

Example
   Print BitSet(4, 0)
   Print Hex(BitSet(1ull, 63))

   will produce the output:

    5
   8000000000000001

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Bitset.

Differences from QB
   * New to FreeBASIC.

See also
   * Bit
   * BitReset



------------------------------------------------------------ KeyPgBload ----
BLoad

Loads arbitrary data from a file created with BSave, or a compatible BMP 
image file.

Syntax
   Declare Function BLoad ( ByRef filename As Const String, ByVal dest As 
   Any Ptr = 0, ByVal pal As Any Ptr = 0 ) As Long

Usage
   result = BLoad( filename [, [ dest ] [, pal ] ] )

Parameters
   filename
      the name of the file to load the image from; can include a file path
   dest
      the memory location to load the image to, or null (0) to copy the 
      image to the current graphics screen work page
   pal
      the memory location to load the palette to, or null (0) to change the 
      current graphics screen palette, if it uses one

Return Value
   Returns zero (0) if successful, or a non-zero error code to indicate a 
   failure. (throws a runtime error)

Description
   BLoad can be used to load image data or any other data from a file 
   created with BSave, and store that data in an array or paste it to the 
   screen. If dest is absent or null (0), the image data is pasted to the 
   current graphics screen work page.  Otherwise it is loaded as image data 
   to the address given by dest.

   BLoad can load 3 different types of files:
      * Old QB-like data files, saved with BSAVE from QB code, containing 
        "raw" data preceded by a 7-byte header, beginning with &HFD, up to 
        64 KiB in size
      * New FB-like data files, saved with BSave from FB code, containing 
        "raw" data preceded by a 5-byte header, beginning with &HFE. There 
        is no 64 KiB limit with this format
      * BMP image files, supports a subset of valid ("Windows") .BMP 
        files, beginning with "BM", saved from FB code with BSave, or 
        created / saved in a compatible format using a graphics editor / 
        converter.
   QB-like data files and BMP files are converted to an FB-compatible image 
   format when opened.

   Image files with 8-bit per pixel resolution or lower contain a palette 
   that describes the color values used in the images. If pal is not null (
   0), the palette is copied to memory starting at the address specified. 
   Otherwise, if the current graphics screen uses a palette then its 
   palette is changed to match that of the image file.

   When using one of the 2 "non-BMP" file formats to save images, the image 
   files must have been created with BSave in the same graphics screen mode 
   as it is being loaded into. When using the BMP file format, this 
   restriction doesn't apply. 

   When loading a BMP file using BLoad,  the images must be true-color 
   (15-, 16-, 24- or 32-bits per pixel) or palettized/indexed (8-bit or 
   lower). The image data will be converted to the proper pixel format for 
   the current color depth, except that true-color can't be reduced to a 
   palettized image. BLoad doesn't support BMP files using RLE compression 
   or other image file types (PNG, JPG, GIF, ...).  BLoad will load alpha 
   channel information, if available, from 32-bit BMP files with 
   BITMAPV4HEADER or BITMAPV5HEADER file headers.

   The error code returned by BLoad can be checked using Err in the next 
   line. The function version of  BLoad returns directly the error code as 
   a 32 bit Long.

Runtime errors:
   BLoad throws one of the following runtime errors:

   (1) Illegal function call
      * dest was not specified or was null (0), and no graphics screen was 
        set.
      * The Bitmap uses an unsupported BMP file compression type (BI_RLE4, 
        BI_RLE8)
      * The Bitmap is true-color (16, 24, or 32 bits per pixel) and the 
        current graphics screen uses a palette (8 bits per pixel or lower).
   (2) File not found
      * The file filename could not be found.
   (3) File I/O error
      * The file doesn't have any of the supported types 
      * A general read error occurred.

   Note: When you use BLoad to load a BMP file into an image buffer, the 
   original dimensions of the image are not changed.  If you want the image 
   buffer to have the same dimensions as the BMP file, you have to find out 
   the dimensions beforehand, and create an image of the right size 
   yourself.  See the example below for an example of how to do this.

Example
   'Load a graphic to current work page
   Screen 18, 32
   Cls
   BLoad "picture.bmp"
   Sleep

   'Load a 48x48 bitmap into an image
   ScreenRes 320, 200, 32
   Dim myImage As Any Ptr = ImageCreate( 48, 48 )
   BLoad "picture.bmp", myImage
   Put (10,10), myImage
   ImageDestroy( myImage )
   Sleep

   ScreenRes 640, 480, 8 '' 8-bit palette graphics mode
   Dim pal(0 To 256-1) As Integer '' 32-bit integer array with room for 256 colors

   '' load bitmap to screen, put palette into pal() array
   BLoad "picture.bmp", , @pal(0)

   WindowTitle "Old palette"
   Sleep

   '' set new palette from pal() array
   Palette Using pal(0)

   WindowTitle "New palette"
   Sleep

   '' A function that creates an image buffer with the same 
   '' dimensions as a BMP image, and loads a file into it.

   Const NULL As Any Ptr = 0

   Function bmp_load( ByRef filename As Const String ) As Any Ptr

      Dim As Long filenum, bmpwidth, bmpheight
      Dim As Any Ptr img

      '' open BMP file
      filenum = FreeFile()
      If Open( filename For Binary Access Read As #filenum ) <> 0 Then Return NULL

         '' retrieve BMP dimensions
         Get #filenum, 19, bmpwidth
         Get #filenum, 23, bmpheight

      Close #filenum

      '' create image with BMP dimensions
      img = ImageCreate( bmpwidth, Abs(bmpheight) )

      If img = NULL Then Return NULL

      '' load BMP file into image buffer
      If BLoad( filename, img ) <> 0 Then ImageDestroy( img ): Return NULL

      Return img

   End Function

   Dim As Any Ptr img

   ScreenRes 640, 480, 32

   img = bmp_load( "picture.bmp" )

   If img = NULL Then
      Print "bmp_load failed"

   Else

      Put (10, 10), img

      ImageDestroy( img )

   End If

   Sleep

Differences from QB
   * Support for loading BMP files is new to FreeBASIC.
   * Support for retrieving the palette from BMP files is new to FreeBASIC
     .
   * FreeBASIC uses a different file format from QBASIC internally, which 
     doesn't have the 64 KiB limit, and is unsupported by QBASIC.

See also
   * BSave
   * Palette
   * ImageCreate
   * ImageDestroy
   * Internal Graphics Formats



---------------------------------------------------------- KeyPgBoolean ----
Boolean

Standard data type

Syntax
   Dim variable As Boolean

Description
   Boolean data type. Can hold the values True or False
   Default value on initialization is False

   Notes on definition of boolean data type: Ideally, the definition of the 
   boolean data type is that it holds the value of True or False, and 
   that's it. However, to make this concept a reality, we need a definition 
   that uses real world connections.
   A more realistic definition is that the boolean data type is a 1-bit 
   integer, having the value 0 to indicate False and 1 to indicate True.
   For a practical definition, we must consider, yet again, additional 
   factors. The most significant factor is that the hardware (processor) on 
   which code is executed does not directly support a 1-bit data type; the 
   smallest register or memory size we can work with is 8-bits or 1-byte.
   Therefore, a practical definition of boolean data type is an integer, 8 
   bits wide, having the value 0 or 1, where all other values are 
   undefined. However, because of longstanding differences between C/C++ 
   and FB with respect to logical operations, the interpretation of the 
   value must also be considered.
   Assume "false" is 0 in both C/C++ and FB.  C/C++ has logical 'not' 
   operator '!' such that '!0' produces '1'.
   FB has a bitwise Not operator such that 'not 0' produces '-1'. Therefore 
   the definition for a C/C++ boolean is an unsigned 1-bit integer, zero 
   extended to fill larger integer types, and the definition for a FB 
   boolean is a signed 1-bit integer, sign extended to fill larger integer 
   types.
   However, the purpose and intent of the boolean data type remains, that 
   it should only ever hold a True value or False value, regardless of the 
   underlying details.

Example
   Dim boolvar As Boolean
   boolvar = True
   Print "boolvar = ", boolvar

   Output:
   boolvar =     True

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Boolean.

Differences from QB
   * New to FreeBASIC

See also
   * CBool
   * True
   * False



------------------------------------------------------------ KeyPgBsave ----
BSave

Saves an array of arbitrary data and palette information to a file on disk

Syntax
   Declare Function BSave ( ByRef filename As Const String, ByVal source As 
   Any Ptr, ByVal size As ULong = 0, ByVal pal As Any Ptr = 0, ByVal 
   bitsperpixel As Long = 0 ) As Long

Usage
   result = BSave( filename, source [,[ size ][,[ pal ][, bitsperpixel ]]] 
   )

Parameters
   filename
      the name of the file to create for storing the pixel and palette 
      data.
   source
      the address of the data to store, or null (0) to store pixel data 
      from the current screen work page.
   size
      optional, the total number of bytes of data to store.  This value is 
      needed unless the output is a BMP file.
   pal
      optional, the address of a buffer holding 256 Palette colors, or null 
      (0) for the current screen palette.
   bitsperpixel
      optional, a requested bit depth for the output BMP image.

Return Value
   Returns zero (0) if successful, or a non-zero error code to indicate a 
   failure. (throws a runtime error)

Description
   BSave is used for saving arbitrary data from memory into a file, using a 
   file format specific to FB, or saving images into a standard BMP image 
   file, replacing an existing file if necessary.

   BSave outputs a total of size bytes of arbitrary data located at source 
   to a specified file. If source is null (0), then BSave outputs a maximum 
   of size bytes from the current work page's pixel buffer, which is 
   structured in the current screen mode's internal pixel format. (This 
   data is not compatible with the image buffer format as it has no 
   header.)  For 8-bit images, palette information is obtained from pal if 
   present and non-null, or if pal omitted or null (0), from the current 
   screen palette.

   A BMP image file can be created if filename has a file extension of "
   .bmp" (case insensitive). source is assumed to point to a valid image 
   buffer whose entire pixel data will be stored in the BMP file. If source 
   is null (0), the contents of the current work page will be stored 
   instead. For 8-bit images, palette information is obtained from pal if 
   non-null, or if null (0), from the current screen palette. The size 
   parameter is ignored when saving BMP files.

   The default bit depth for BMP files is 8-bit for 8-bit (palette) images, 
   24-bit for 16-bit images, and 32-bit for 32-bit images.  The 
   bitsperpixel parameter can be used to request 24-bit output for 8-bit 
   images, or 24-bit output for 32-bit images.

   The error code returned by BSave can be checked using Err in the next 
   line. The function version of  BSave returns directly the error code as 
   a 32 bit Long.

Runtime errors:
   BSave throws one of the following runtime errors:

   (1) Illegal function call
      * size is less than zero (0), or size is zero and source is 
        non-null, or a problem is detected with the image buffer.
   (2) File not found
      * The file could not be created.
   (3) File I/O error
      * The file could not be written to.

Example
   ' Set gfx mode
   ScreenRes 320, 200, 32

   ' Clear with black on white
   Color RGB(0, 0, 0), RGB(255, 255, 255)
   Cls

   Locate 13, 15: Print "Hello world!"

   ' Save screen as BMP
   BSave "hello.bmp", 0

Save image buffer to bitmap file:
   'set graphics screen 640 x 480 pixels, 32 bit colors
   Const W = 640, H = 480 'width & hight
   ScreenRes W, H, 32
   'draw a smiley at screen center
   Circle (W \ 2, H \ 2), 180, &h00ffff00, , , , f 'yellow circle
   Circle (W \ 2 - 55, H \ 2 - 70), 35, &h00000000, , , 1.5, f 'left eye
   Circle (W \ 2 + 55, H \ 2 - 60), 35, &h00000000, , , 1.5, f 'right eye
   Circle (W \ 2, H \ 2 + 80), 70, &h00000000, , , 0.4, f 'mouth
   'allocate memory for image buffer
   Dim As Any Ptr pImageBuffer = ImageCreate(250, 250)
   'copy screen section to buffer
   Get (W \ 2 - 125, H \ 2 - 125)-Step(250 - 1, 250 - 1), pImageBuffer
   'save image buffer to file
   Dim As String fileName = "Smiley.bmp"
   If BSave(fileName, pImageBuffer) = 0 Then
      Print "Saved succesful: " + fileName
   Else
      Print "Error saving: " + fileName
   End If
   'free memory for image buffer
   ImageDestroy(pImageBuffer)
   'keep graphics screen open until key press
   Sleep

Differences from QB
   * Support for saving more than 64KiB of arbitrary data is new to 
     FreeBASIC.
   * Support for saving BMP files is new to FreeBASIC.
   * QB cannot use BLoad to load files created with BSave in FreeBASIC, 
     but FreeBASIC can use BLoad to load files created with BSave in QB

See also
   * BLoad
   * Palette



------------------------------------------------------------ KeyPgByref ----
Byref (Parameters)

Declaration specifier to explicitly pass a parameter by reference

Syntax
   ByRef param As datatype

Usage
   [ Declare ] { Sub | Function } proc_name ( ByRef param As datatype  )

Description
   Passes a variable by reference, that is its address, to a subroutine or 
   function. When a variable is passed by reference, the contents of the 
   variable can be changed by the target subroutine or function.

   In -lang qb and -lang fblite dialects, ByRef is the default parameter 
   passing convention, unless Option ByVal is in effect.

   Opposite of ByVal.

   Note: A constant or a literal expression can also be passed to such a 
   procedure (which gets by reference), but they are obviously not 
   modifiable from the procedure body. In that case, the compiler passes by 
   reference a temporary variable initialized with the constant or the 
   literal expression.

   Warning: When passing by reference, it is recommended to pass an 
   argument of the same type (or fully compatible, like a derived type for 
   example) as that of the declared parameter. Although in some cases the 
   compiler accepts to pass a different type, often the result is not the 
   one expected.

Example
   Dim MyVar As Integer

   Sub ChangeVar(ByRef AVar As Integer)
      AVar = AVar + 1
   End Sub

   MyVar = 1
   Print "MyVar: "; MyVar 'output = 1
   ChangeVar MyVar
   Print "MyVar: "; MyVar 'output = 2
   Sleep
   End

Dialect Differences
   * In -lang fb dialect, ByVal is the default parameter passing 
     convention for all built-in types except String and user-defined Type 
     which are passed ByRef by default. The ZString and WString built-in 
     types are also passed ByRef by default, but passing ByVal is 
     forbidden. Arrays are always passed ByRef and the use of the specifier 
     ByRef or ByVal is forbidden.
   * In -lang qb and -lang fblite dialects, ByRef is the default parameter 
     passing convention.

Differences from QB
   * New to FreeBASIC

See also
   * Passing Arguments to Procedures
   * Declare
   * ByVal
   * Byref (Function Results)
   * Byref (Variables)



---------------------------------------------------- KeyPgByrefFunction ----
Byref (Function Results)

Specifies that a function result is returned by reference

Syntax
   Function name ( parameter-list ) ByRef As datatype

Description
   Causes the function result to be returned by reference, rather than by 
   value. A function returning ByRef will return the address of a variable, 
   instead of making a copy like when returning by value. This allows the 
   caller of the function to modify the variable which the function result 
   points to.

   If ByRef is not specified, the default is to return the function result 
   by value.

   Functions with ByRef result should not return local variables from the 
   function, because they will be destroyed upon returning from the 
   function, invalidating any pointer or reference to them. To help with 
   writing safe code, the compiler will show an error message when a local 
   variable is used with Function = x (or name = x) assignments and Return 
   x statements.

   Note: On the left-hand side of an assignment expression using the '=' 
   symbol, the result of the function (returned by reference) must be 
   enclosed in parentheses when the function calls one single argument, in 
   order to solve the parsing ambiguity. '=>' can be used for assignments, 
   in place of '=', same as for initializers, allowing to avoid parsing 
   ambiguity (without parentheses). As for the arguments list, it should 
   always be surrounded with parentheses even if empty.

   Operators (member or global), when used as functions, have also the 
   capability to return results by reference, by using the same syntax.

Example
   Function min( ByRef I As Integer , ByRef J As Integer ) ByRef As Integer
      '' The smallest integer will be returned by reference, no copy will be created.
      If I < J Then
         Return I
      Else
         Return J
      End If
   End Function

   Dim As Integer A = 13, B = 7
   Print A, B
   Print min( A , B )
   min( A , B ) = 0
   Print A, B

   Function f( ) ByRef As Const ZString
      '' This string literal (because statically allocated in memory) will be returned by reference, no copy will be created.
      Function = "abcd"
   End Function

   Print f( )

   Dim Shared As String s

   Function f1( ) ByRef As String
      '' This variable-length string will be returned by reference, no copy will be created.
      Function = s
   End Function

   Function f2( ByRef _s As String ) ByRef As String
      '' This variable-length string will transit by reference (input and output), no copy will be created.
      Function = _s
   End Function

   s = "abcd"
   Print s

   f1( ) = f1( ) & "efgh"
   Print s

   '' The enclosing parentheses are required here on the left-hand side.
   ( f2( s ) ) = f2( s ) & "ijkl"
   Print s

   '' The enclosing parentheses are not required here on the left-hand side.
   f2( s ) => f2( s ) & "mnop"
   Print s

   Function power2( ByRef _I As Integer ) ByRef As Integer
      _I *= _I
      '' This integer will be returned by reference, no copy will be created.
      Function = _I
   End Function

   Dim As Integer I = 2
   power2( power2( power2( I ) ) )  '' Function return-byref cascading is equivalent to ((I*I)*(I*I))*((I*I)*(I*I)) = I^8
   Print I

Differences from QB
   * New to FreeBASIC

See also
   * Returning values
   * Byref (Parameters)
   * Byref (Variables)



--------------------------------------------------- KeyPgByrefVariables ----
Byref (Variables)

Declares a reference

Syntax
      (Dim | Static) [Shared] ByRef name1 As DataType = variable1 [, ByRef 
      name2 As DataType = variable2, ...]
   or
      (Dim | Static) [Shared] ByRef As DataType name1 = variable1 [, name2 
      = variable2, ...]
   or
      Var [Shared] ByRef name1 = variable1 [, ByRef name2 = variable2, ...]

Parameters
   name
      reference name
   variable
      variable name to refer

Description
   Declares a reference (by name) to a variable.

   A reference is an entity that is a way to access data located in memory. 
   A reference is not the data itself but only information about its 
   location. A reference can be thought of as a pointer that is implicitly 
   dereferenced. In many cases, it can be used as an alternative to 
   pointer.

   A reference must always be initialized with a variable when it is 
   created.
   DataType must be the same type as that of the variable, or a compatible 
   type (for example one from the types of its Bases in case of 
   inheritance):
      * Only when the two types are identical (or using the third syntax 
        with Var), a reference can be considered as an alias of the 
        variable. One can do the same operations through such a reference 
        as one can do with the original variable.
      * Otherwise (types compatible but not identical), one cannot do all 
        same operations than with the original variable:
            For example, a base type reference referring to a derived type 
            object allows to activate polymorphism when a virtual method is 
            called on it, similarly to a base type pointer referring to a 
            derived type object. One can do the same operations through 
            such a reference as one can do with a dereferenced pointer of 
            same type (but for both not the same operations as using 
            directly the derived type instance).

   A reference can be reassigned to refer to another variable (of 
   compatible type) by doing:
      @refname = @othervariable

   NOTE: The arrays of references and the non-static reference fields for 
   UDT are not supported yet.

Example
   '' Comparison between:
   ''   - a copy ('ci') of a variable ('i')
   ''   - a reference ('ri') to a variable ('i')

   Dim As Integer i = 12
   Print @i, i

   Dim As Integer ci = i  '' or Var ci = i
   Print @ci, ci

   Dim ByRef As Integer ri = i  '' or Var Byref ri = i
   Print @ri, ri

   Print

   Print i, ci, ri
   i = 34
   Print i, ci, ri
   ci = 56
   Print i, ci, ri
   ri = 78
   Print i, ci, ri

   Sleep

   '' Use reference allows to simplify expressions compared to pointer
   '' (avoid to use operator '@' and especially '*')

   Dim As ZString Ptr pz = @"FreeBASIC Zstring Ptr"
   Print *pz
   *pz &= " 1.3.0"
   Print *pz

   Print

   Dim ByRef As ZString rz = "FreeBASIC Zstring Ref"  '' or Var Byref rz = "FreeBASIC Zstring Ref"
   Print rz
   rz &= " 1.4.0"
   Print rz

   Sleep

   '' It is possible to reassign a reference.
   '' An example with an UDT to control the successive constructions & destructions of objects handled with one only reference.

   Type UDT
     Declare Constructor ()
     Declare Destructor ()
     Dim As Integer I
   End Type

   Constructor UDT ()
     Static As Integer nb
     nb += 1
     This.I = nb
     Print "UDT.Constructor()"
   End Constructor

   Destructor UDT ()
     Print "UDT.Destructor()"
   End Destructor

   Var ByRef ru = *New UDT  '' or Dim Byref As UDT ru = *New UDT
   Print ru.I
   Delete @ru

   Print

   @ru = New UDT
   Print ru.I
   Delete @ru

   Sleep

   '' Polymorphism (by using inheritance and virtuality) can be activated through any of the 3 following kinds of entities:
   ''   - base-type pointers referring to derived-type objects,
   ''   - dereferenced base-type pointers referring to derived-type objects,
   ''   - base-type references referring to derived-type objects.
   '
   '' If in the first line of the below code, FALSE is put instead TRUE, the polymorphism by virtuality is no more activated.

   #define virtuality True

   Type myBase Extends Object
     #if virtuality = True
      Declare Virtual Sub hello()
     #else
      Declare Sub Hello()
     #endif
   End Type

   Sub myBase.hello()
     Print "myBase.hello()"
   End Sub

   Type myDerived Extends myBase
     Declare Sub hello()
   End Type

   Sub myDerived.hello()
     Print "myDerived.hello()"
   End Sub

   Dim As myBase mb
   Dim As myBase Ptr pmb = @mb
   Dim ByRef As myBase rmb = mb  '' or Var Byref rmb = mb
   pmb->hello()    '' pmb is a base-type pointer referring to a base-type object
   (*pmb).hello()  '' *pmb is a dereferenced base-type pointer referring to a base-type object
   rmb.hello()     '' rmb is a base-type reference referring to a base-type object

   Print

   Dim As myDerived md
   Dim As myBase Ptr pmd = @md
   Dim ByRef As myBase rmd = md  '' only syntax because the reference data-type must be different from the one of object
   pmd->hello()    '' pmd is a base-type pointer referring to a derived-type object
   (*pmd).hello()  '' *pmd is a dereferenced base-type pointer referring to a derived-type object
   rmd.hello()     '' rmd is a base-type reference referring to a derived-type object

   Sleep

Dialect Differences
   * Only supported in -lang fb, -lang fblite and -lang deprecated 
     dialects.

Differences from QB
   * New to FreeBASIC.

See also
   * Dim
   * Static
   * Var
   * Shared
   * Byref (Parameters)
   * Byref (Function Results)



------------------------------------------------------------- KeyPgByte ----
Byte

Standard data type: 8 bit signed

Syntax
   Dim variable As Byte

Description
   8-bit signed whole-number data type. Can hold a value in the range of 
   -128 to 127.

Example
     Dim bytevar As Byte
     bytevar = 100
     Print "bytevar= ", bytevar

   Dim x As Byte = CByte(&H80)
   Dim y As Byte = CByte(&H7F)
   Print "Byte Range = "; x; " to "; y

   Output:
   Byte Range = -128 To  127

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Byte.

Differences from QB
   * New to FreeBASIC

See also
   * UByte
   * CByte



------------------------------------------------------------ KeyPgByval ----
ByVal

Declaration specifier to explicitly pass a parameter by value

Syntax
   ByVal param As datatype

Usage
   [ Declare ] { Sub | Function } proc_name ( ByVal param As datatype  )

Description
   ByVal in a parameter list of a declare statement causes a copy of the 
   variable to be passed to the procedure (for example, a sub or function) 
   by its value.

   This means that if the value of the variable x is passed, then the 
   original variable x will not be modified in any way; however, if the 
   variable were passed ByRef, the value of the original variable x could 
   be modified by the called function.

   Opposite of ByRef.

   The ByVal keyword is also used in the context of Byref Parameters and 
   Function Results, where it can be used to explicitly override the 
   by-reference semantics in order to pass or assign a pointer as-is to a 
   Byref parameter or function result. For reference:
      * Manually passing pointers to by-reference parameters
      * Manually returning pointers as-is from Byref functions

   Note: ByVal (passing by copy) is good for small objects (4 or 8 bytes, a 
   bit more will still be ok) that are easy to copy, like numeric types. 
   Passing ByVal avoids the overhead of the pointer used by ByRef.
   ByRef is better for passing huge objects like strings or big UDTs that 
   should not be copied. Even though ByRef has some overhead because it has 
   to pass a pointer (and dereference at each access to the object), this 
   is still better than copying a multitude of bytes on to the stack 
   every-time the procedure is called.

Example
   Sub MySub(ByVal value As Integer)
      value += 1
   End Sub

   Dim MyVar As Integer

   MyVar = 1
   Print "MyVar: "; MyVar 'output = 1
   MySub MyVar
   Print "MyVar: "; MyVar 'output = 1, because byval won't change the values passed into it globally.
   Sleep
   End

Dialect Differences
   * In the -lang fb dialect, ByVal is the default parameter passing 
     convention for all built-in types except String and user-defined Type 
     which are passed ByRef by default. The ZString and WString built-in 
     types are also passed ByRef by default, but passing ByVal is 
     forbidden. Arrays are always passed ByRef and the use of the specifier 
     ByRef or ByVal is forbidden.
   * In -lang qb and -lang fblite dialects, ByRef is the default parameter 
     passing convention.

Differences from QB
   * QB only used ByVal in declarations to non-Basic subroutines

See also
   * Passing Arguments to Procedures
   * Declare
   * ByRef




============================================================================
    C

------------------------------------------------------------- KeyPgCall ----
Call

Statement to invoke a subroutine

Syntax
   Call procname ([parameter list])

Description
   Calls a Sub or Function.

   This keyword is a holdover from earlier dialects of BASIC, and is mainly 
   deprecated.

   In -lang qb, it can be used to call Subs in code before they are 
   declared.  The function will be implicitly Declare'd, with any 
   parameters passed ByRef As Any.
   Note: until the function is declared, no type-checking is done on the 
   parameters, so it is up to the programmer to ensure they are of the 
   correct type.

Example
   '' Compile with -lang qb or -lang fblite

   #lang "fblite"

   Declare Sub foobar(ByVal x As Integer, ByVal y As Integer)
   Call foobar(35, 42)

   Sub foobar(ByVal x As Integer, ByVal y As Integer)
   Print x; y
   End Sub

   '' Compile with -lang qb or -lang fblite

   #lang "fblite"

   Function f ( ) As Integer
   f = 42
   End Function

   Call f ' execute function f, but ignore the answer

   '' Compile with -lang qb

   '$lang: "qb"

   Call mysub(15, 16) '' call "mysub" before it has been declared, or even mentioned.

   Sub mysub(ByRef a As Integer, ByRef b As Integer)
      
      Print a, b
      
   End Sub

Dialect Differences
   * The use of Call is not allowed in the -lang fb dialect.
   * The -lang fblite dialect does not allow you to call functions that 
     have not been previously declared.

Differences from QB
   * The procedure must have already been declared.
   * Call in QB will make a copy of all parameters, so changes made to the 
     arguments inside the called Sub will not be reflected in the variables 
     in the caller.

See also
   * Declare
   * Sub



-------------------------------------------------------- KeyPgCallocate ----
CAllocate

Allocates memory for a certain number of elements from the free store and 
clears the contents

Syntax
   Declare Function CAllocate cdecl ( ByVal num_elements As UInteger, ByVal 
   size As UInteger = 1 ) As Any Ptr

Usage
   result = CAllocate( num_elements [, size ] )

Parameters
   num_elements
      The number of elements to allocate memory for.
   size
      The size, in bytes, of each element.

Return Value
   If successful, the address of the start of the allocated memory is 
   returned. Otherwise, the null pointer (0) is returned.

Description
   CAllocate initializes the allocated memory with zeros.
   Consequently, CAllocate can be also directly used with String or Udt 
   containing string, because the string descriptor is cleared (set to 0) 
   first.
   Similarly, CAllocate can also be used directly with ZString or WString 
   because string data is created with null characters.

Example
   ' Allocate and initialize space for 10 integer elements.
   Dim p As Integer Ptr = CAllocate(10, SizeOf(Integer))

   ' Fill the memory with integer values.
   For index As Integer = 0 To 9
      p[index] = (index + 1) * 10
   Next

   ' Display the integer values.
   For index As Integer = 0 To 9
      Print p[index] ;
   Next

   ' Free the memory.
   Deallocate(p)

Outputs:
    10 20 30 40 50 60 70 80 90 100

Platform Differences
   * This procedure is not guaranteed to be thread-safe.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Callocate.

Differences from QB
   * New to FreeBASIC

See also
   * Allocate
   * Deallocate
   * Reallocate



------------------------------------------------------------- KeyPgCase ----
Case

Control flow statement

Syntax
   Case expression

Differences from QB
   * None

See also
   * Select Case



------------------------------------------------------------- KeyPgCast ----
Cast

Converts an expression to a specified data type

Syntax
   Cast( datatype, expression )

Parameters
   datatype 
      a built-in data type (standard type)
   expression 
      a variable of another built-in data type

Description
   Converts expression into a different datatype. Useful to be used in 
   macros when datatype is unknown and also when converting to Type Alias.

   This is a general form of conversion operators such as CInt or CDbl.
   Cast is more versatile because it can be used on built-in types that 
   have a built-in Cast Operator, but don't have a built-in keyword for it: 
   e.g. Cast( Byte, boolean ).
   It is also suitable for use in cases where the type of a variable is not 
   fixed in the code - for example, it might be Defined earlier, or may be 
   the Type Of a different variable or expression.

   Note: If you want to use an operator specifically for converting to 
   different types of Pointers, consider using CPtr instead.

   Upcasting: In an inheritance structure, the upcasting is converting a 
   derived type reference or pointer into a base type.
   In this special use, Cast applied on a derived-type instance (expression
   ) can be used to return a base-type (datatype) reference.

   By using a member Operator Cast, Cast can be overloaded for a user 
   defined type expression.
  
Example
   '' will print -128 because the integer literal will be converted to a signed Byte
   '' (this Casting operation is equivalent to using CByte)
   Print Cast( Byte, &h0080 )

   '' will print 3 because the floating-point value will be converted to an Integer
   '' (this Casting operator is equivalent to using CInt)
   Print Cast( Integer, 3.1 )

   Sleep

   '' macro sizeofDerefPtr(): returns the size of the dereferenced pointer
   #define sizeofDerefPtr(ptrToDeref) SizeOf(*Cast(TypeOf(ptrToDeref), 0))

   '' macro typeofDerefPtr(): returns the type of the dereferenced pointer
   #define typeofDerefPtr(ptrToDeref) TypeOf(*Cast(TypeOf(ptrToDeref), 0))

   ' Allocate dynamically memory for a Double by New
   Dim As Double Ptr pd
   pd = New typeofDerefPtr(pd)
   *pd = 3.14159
   Print *pd

   ' Allocate dynamically memory for a Zstring*10 by Callocate
   Dim As ZString Ptr pz
   pz = CAllocate(10, sizeofDerefPtr(pz))
   *pz = "FreeBASIC"
   Print *pz

   Sleep
   Delete pd
   Deallocate(pz)

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Cast.

Differences from QB
   * New to FreeBASIC

See also
   * Cast (Operator)
   * CPtr
   * CInt
   * TypeOf
   * Coercion and Conversion
    


------------------------------------------------------------ KeyPgCbool ----
CBool

Converts numeric or string expression to a boolean (Boolean)

Syntax
   Declare Function CBool ( ByVal expression As datatype ) As Boolean

   Type typename
      Declare Operator Cast ( ) As Boolean
   End Type

Usage
   result = CBool( numeric expression )
   result = CBool( string expression )
   result = CBool( user defined type )

Parameters
   expression
      a numeric, string, or user defined type to cast to a Boolean value
   datatype
      any numeric, string, or user defined type
   typename
      a user defined type

Return Value
   A Boolean value.

Description
   The CBool function converts a zero value to False and a non-zero value 
   to True.

   The name can be explained as 'Convert to Boolean'.

   If the argument is a string expression, it is converted to boolean using 
   a case insensitive to the string "false" to return a False value or 
   "true" to return a True value.

Example
   ' Using the CBOOL function to convert a numeric value

   'Create an BOOLEAN variable
   Dim b As Boolean

   'Convert a numeric value
   b = CBool(1)

   'Print the result, should return True
   Print b
   Sleep

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Cbool.

Differences from QB
   * New to FreeBASIC

See also
   * CByte
   * CUByte
   * CShort
   * CUShort
   * CInt
   * CUInt
   * CLng
   * CULng
   * CLngInt
   * CULngInt
   * CSng
   * CDbl
   * Str



------------------------------------------------------------ KeyPgCbyte ----
CByte

Converts numeric or string expression to Byte.

Syntax
   Declare Function CByte ( ByVal expression As datatype ) As Byte

   Type typename
      Declare Operator Cast ( ) As Byte
   End Type

Usage
   result = CByte( numeric expression )
   result = CByte( string expression )
   result = CByte( user defined type )

Parameters
   expression
      A numeric, string, or pointer expression to cast to a Byte value.
   datatype
      Any numeric, string, or pointer data type.
   typename
      A user defined type.

Return Value
   A Byte value.

Description
   The CByte function rounds off the decimal part and returns a 8-bit Byte 
   value. The function does not check for an overflow, and results are 
   undefined for values which are less than -128 or larger than 127.

   The name can be explained as 'Convert to Byte'.

   If the argument is a string expression, it is converted to numeric by 
   using ValInt.

Example
   ' Using the CBYTE function to convert a numeric value

   'Create an BYTE variable
   Dim numeric_value As Byte

   'Convert a numeric value
   numeric_value = CByte(-66.30)

   'Print the result, should return -66
   Print numeric_value
   Sleep

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Cbyte.

Differences from QB
   * New to FreeBASIC

See also
   * CUByte
   * CShort
   * CUShort
   * CInt
   * CUInt
   * CLng
   * CULng
   * CLngInt
   * CULngInt
   * CSng
   * CDbl



------------------------------------------------------------- KeyPgCdbl ----
CDbl

Converts numeric or string expression to Double precision floating point

Syntax
   Declare Function CDbl ( ByVal expression As datatype ) As Double

   Type typename
      Declare Operator Cast ( ) As Double
   End Type

Usage
   result = CDbl( numeric expression )
   result = CDbl( string expression )
   result = CDbl( user defined type )

Parameters
   expression
      a numeric, string, or pointer expression to cast to a Double value
   datatype
      any numeric, string, or pointer data type
   typename
      a user defined type

Return Value
   A Double precision value.

Description
   The CDbl function returns a 64-bit Double value. The function does not 
   check for an overflow, so be sure not to pass a value outside the 
   representable range of the Double data type. The name can be explained 
   as 'Convert to DouBLe'.

   If the argument to CDbl is a string expression, it is first converted to 
   numeric by using Val.

Example
   ' Using the CDBL function to convert a numeric value

   'Create an DOUBLE variable
   Dim numeric_value As Double

   'Convert a numeric value
   numeric_value = CDbl(-12345678.123)

   'Print the result, should return -12345678.123
   Print numeric_value
   Sleep

Differences from QB
   * The string argument was not allowed in QB

See also
   * CByte
   * CUByte
   * CShort
   * CUShort
   * CInt
   * CUInt
   * CLng
   * CULng
   * CLngInt
   * CULngInt
   * CSng



------------------------------------------------------------ KeyPgCdecl ----
cdecl

Specifies a cdecl-style calling convention in a procedure declaration

Syntax
   Sub name cdecl [Overload] [Alias "alias"] ( parameters )
   Function name cdecl [Overload] [Alias "alias"] ( parameters ) [ ByRef ] 
   As return_type

Description
   In procedure declarations, cdecl specifies that a procedure will use the 
   cdecl calling convention. In the cdecl calling convention, any 
   parameters are to be passed (pushed onto the stack) in the reverse order 
   in which they are listed, that is, from right to left. The procedures 
   need not preserve the EAX, ECX or EDX registers, and must not clean up 
   the stack (pop any parameters) before it returns - that is left to the 
   calling code.

   cdecl is allowed to be used with variadic procedure declarations (those 
   with the last parameter listed as "...").

   cdecl is the default calling convention on Linux, the *BSDs, and DOS, 
   unless another calling convention is explicitly specified or implied by 
   one of the Extern Blocks. cdecl is typically the default calling 
   convention for C compilers, and it's used almost exclusively on 
   Unix-like systems.

Example
   ' declaring 'strcpy' from the standard C library
   Declare Function strcpy cdecl Alias "strcpy" (ByVal dest As ZString Ptr, ByVal src As ZString Ptr) As ZString Ptr

Differences from QB
   * New to FreeBASIC

See also
   * pascal, stdcall
   * Declare
   * Sub, Function



------------------------------------------------------------ KeyPgChain ----
Chain

Temporarily transfers control to an external program

Syntax
   Declare Function Chain ( ByRef program As Const String ) As Long

Usage
   result = Chain( program )

Parameters
   program
      The file name (including file path) of the program (executable) to 
      transfer control to.

Return Value
      Returns the external program's exit code if executed successfully, or 
      negative one (-1) otherwise.

Description
   Transfers control over to an external program. When the program exits, 
   execution resumes immediately after the call to Chain.

Example
   #ifdef __FB_LINUX__
      Dim As String program = "./program"
   #else
      Dim As String program = "program.exe"
   #endif

   Print "Running " & program & "..."
   If (Chain(program) <> 0) Then
      Print program & " not found!"
   End If

Platform Differences
   * Linux requires the program name case matches the real name of the 
     file. Windows and DOS  are case insensitive. The program  chained may 
     be case sensitive for its command line parameters.
   * Path separators in Linux are forward slashes / . Windows uses 
     backward slashes \ but it allows for forward slashes .  DOS uses 
     backward  \ slashes.
   * Exit code is limited to 8 bits in DOS.

Differences from QB
   * None

See also
   * Exec transfer temporarily, with arguments  
   * Run one-way transfer
   * Command pick arguments



------------------------------------------------------------ KeyPgChdir ----
ChDir

Changes the current drive and directory

Syntax
   Declare Function ChDir ( ByRef path As Const String ) As Long

Usage
   result = ChDir( path )

Parameters
   path
      A String argument specifying the path to change to.

Return Value
   Returns zero (0) on success and negative one (-1) on failure.

Description
   Changes the current drive and directory to that specified.

Example
   Dim pathname As String = "x:\folder"
   Dim result As Integer = ChDir(pathname)

   If 0 <> result Then Print "error changing current directory to " & pathname & "."

Platform Differences
   * Linux requires the filename case matches the real name of the file. 
     Windows and DOS are case insensitive. 
   * Path separators in Linux are forward slashes / . Windows uses 
     backward slashes \ but it allows for forward slashes .  DOS uses 
     backward  \ slashes. 

Differences from QB
   * In QB, the drive could not be specified.

See also
   * CurDir
   * MkDir
   * RmDir



-------------------------------------------------------------- KeyPgChr ----
Chr

Returns a string of characters from one or more ASCII integer values

Syntax
   Declare Function Chr ( ByVal ch As Integer [, ... ] ) As String

Usage
   result = Chr[$]( ch0 [, ch1 ... chN ] )

Parameters
   ch
      The ASCII integer value of a character.

Return Value
   Returns a string containing the character(s).

Description
   Chr returns a string containing the character(s) represented by the ASCII
   values passed to it.

   When Chr is used with numerical constants or literals, the result is 
   evaluated at compile-time, so it can be used in variable initializers.

   Asc performs the opposite function, returning the ASCII code of a 
   character represented by a string.

Example
   Print "the character represented by";
   Print " the ASCII code of 97 is: "; Chr(97)

   Print Chr(97, 98, 99) ' prints abc

   ' s initially has the value "abc"
   Dim s As String = Chr(97, 98, 99)

   Print s

Dialect Differences
   * The string type suffix "$" is obligatory in the -lang qb dialect.
   * The string type suffix "$" is optional in the -lang fblite dialect.
   * The string type suffix "$" is forbidden in the -lang fb dialect.

Differences from QB
   * FreeBASIC accepts multiple integer values as arguments, QB accepted 
     only one.
   * FreeBASIC evaluates the CHR function at compile time when used with 
     constants or literals.

See also
   * ASCII Character Codes
   * Asc
   * Str
   * Val



------------------------------------------------------------- KeyPgCint ----
CInt

Converts a numeric or string expression to an Integer or an Integer<bits>

Syntax
   Declare Function CInt ( ByVal expression As datatype ) As Integer
   Declare Function CInt<bits> ( ByVal expression As datatype ) As Integer<
   bits>

   Type typename
      Declare Operator Cast ( ) As Integer
      Declare Operator Cast ( ) As Integer<bits>
   End Type

Usage
   result = CInt( expression )
   result = CInt( string expression )
   result = CInt( user defined type )

Parameters
   bits
      A numeric constant expression indicating the size in bits of integer 
      desired.  The values allowed are 8, 16, 32 or 64.
   expression
      a numeric, string, or pointer expression to cast to a Integer value
   datatype
      any numeric, string, or pointer data type
   typename
      a user defined type

Return Value
   An Integer or Integer<bits> containing the converted value.

Description
   If CInt is passed a numeric expression, it rounds it using using the 
   round-to-even method - i.e. it rounds to the closest integer value, 
   choosing the closest even integer if the number is equidistant from two 
   integers - and returns an Integer, or if a bits value is supplied, an 
   integer type of the given size.

   The function does not check for an overflow; for example, for a 32-bit 
   Integer the results are undefined for values which are less than -2 147 
   483 648 or larger than 2 147 483 647.

   If the argument is a string expression, it is converted to numeric by 
   using ValInt or ValLng, depending on the size of the result type.

   The name "CINT" is derived from 'Convert to INTeger'.

Example
   ' Using the CINT function to convert a numeric value

   'Create an INTEGER variable
   Dim numeric_value As Integer

   'Convert a numeric value
   numeric_value = CInt(300.5)

   'Print the result, should return 300, because 300 is even

   numeric_value = CInt(301.5)

   'Print the result, should return 302, because 301 is odd
   Print numeric_value

Dialect Differences
   * In the -lang qb dialect, CInt will return a 16-bit integer, like in 
     QB.

Differences from QB
   * The string argument was not allowed in QB
   * The <bits> parameter was not allowed in QB

See also
   * Cast
   * CByte
   * CUByte
   * CShort
   * CUShort
   * CUInt
   * CLng
   * CULng
   * CLngInt
   * CULngInt
   * CSng
   * CDbl
   * Integer



----------------------------------------------------------- KeyPgCircle ----
Circle

Graphics statement to draw an ellipse or a circle

Syntax
   Circle [target,] [STEP] (x,y), radius[, [color][, [start][, [end][, 
   [aspect][, F]]]]]

Parameters
   target
      optional; specifies the image buffer to draw on
   STEP
      indicates that coordinates are relative
   (x, y)
      coordinates of the center of the ellipse
   radius
      the radius of the circle - or for an ellipse, the semi-major axis 
      (i.e. the longest radius)
   color
      the color attribute
   start
      starting angle
   end
      ending angle
   aspect
      aspect ratio of the ellipse, the ratio of the height to the width
   F
      fill mode indicator

Description
   Circle will draw a circle, ellipse, or arc based on the parameters given 
   to it. 

   target specifies a buffer to draw on.  target may be an image created 
   with ImageCreate or Get (Graphics).  If omitted, target defaults to the 
   screen's current work page.  (See ScreenSet)

   The center of the shape will be placed on the destination surface at (x, 
   y). 

   Radius denotes the radius of the shape. If aspect ratio is not 1.0, the 
   biggest radius must be given here.

   Color denotes the color attribute, which is mode specific (see Color and 
   Screen (Graphics) for details). If omitted, the current foreground color 
   as set by the Color statement is used.

   The Step option specifies that x and y are offsets relative to the 
   current graphics cursor position.

   start and end are angles are in radians. These can range -2*PI to 2*PI, 
   where PI is the constant &pi;, approximately 3.141593; if you specify a 
   negative angle, its value is changed sign and a line is drawn from the 
   center up to that point in the arc. end angle can be less than start. If 
   you do not specify start and end, a full circle/ellipse is drawn; if you 
   you specify start but not end, end is assumed to be 2*PI; if you specify 
   end but not start, start is assumed to be 0.0.

   aspect is the aspect ratio, or the ratio of the y radius over the x 
   radius. If omitted, the default for ScreenRes modes is 1.0, while for 
   Screen modes the default value is the value required to draw a perfect 
   circle on the screen, keeping the pixel aspect ratio in mind. This value 
   can be calculated as follows:

   ratio = (y_radius / x_radius) * pixel_aspect_ratio

   Where pixel_aspect_ratio is the ratio of the current mode width over the 
   current mode height, assuming a 4:3 standard monitor. If aspect ratio is 
   less than 1.0, radius is the x radius; if aspect is more or equal to 1.0
   , radius is the y radius.

   F is the fill flag. If you specify this flag, the circle/ellipse will be 
   filled with the selected color. This only takes effect if you are 
   drawing a full circle/ellipse.

   Custom coordinates system set up by Window and/or View (Graphics) affect 
   the drawing operation; clipping set by View also applies. When Circle 
   finishes drawing, the current graphics cursor position is set to the 
   supplied center.

   Note: Curves drawn with Circle can induce pixels overdrawn at some 
   locations. Thus, the resultant (blended) color of these overdrawn pixels 
   is affected if a transparent color (in conjunction with the 
   GFX_ALPHA_PRIMITIVES option flag) is used.

Example
   ' Set 640x480 mode, 256 colors
   Screen 18

   ' Draws a circle in the center
   Circle (320, 240), 200, 15

   ' Draws a filled ellipse
   Circle (320, 240), 200, 2, , , 0.2, F

   ' Draws a small arc
   Circle (320, 240), 200, 4, 0.83, 1.67, 3

   Sleep

Differences from QB
   * target is new to FreeBASIC
   * The FreeBASIC implementation uses a different algorithm for 
     ellipse/arc drawing than QB, so the result may not be equal to QB for 
     every pixel.
   * The F flag to draw filled circles/ellipses is new to FreeBASIC.

See also
   * Screen (Graphics)
   * Color



------------------------------------------------------------ KeyPgClass ----
Class

Declares a class object

Syntax
   Class typename ...

Parameters
   typename
      name of the Class

Description
   We would have put something useful here (honest) except this feature 
   isn't implemented in the compiler yet.  But since it will get added in 
   future, and there are several other document pages that need to link 
   here, we thought it safe to include in anyway.

Example
   '' sample code

Output:

   sample Output

Dialect Differences
   * Object-related features are supported only in the -lang fb option

Differences from QB
   * New to FreeBASIC

See also
   * Enum
   * Type



------------------------------------------------------------ KeyPgClear ----
Clear

Clears or initializes some memory

Syntax
   Declare Sub Clear cdecl ( ByRef dst As Any, ByVal value As Long = 0, 
   ByVal bytes As UInteger )

Usage
   Clear( dst, [value], bytes )

Parameters
   dst
      starting address of some memory
   value
      the value to set all bytes equal to
   bytes
      number of bytes to clear

Description
   Clear sets one or more bytes in memory to a certain value (the default 
   value is zero (0) if not specified). The starting address is taken from 
   a reference to a variable or array element.

   NOTE: In order to clear memory referenced by a Pointer, it must be 
   dereferenced first.  Otherwise, Clear will try to clear the bytes at the 
   pointer variable's memory location.

Example
   'create an array with 100 elements
   Dim array(0 To 99) As Integer

   'clear the contents of the array to 0, starting with the first element
   Clear array(0), , 100 * SizeOf(Integer)

   'allocate 20 bytes of memory
   Dim As Byte Ptr p = Allocate(20)

   'set each of the first ten bytes to 0
   Clear *p, 0, 10

   'set each of the next ten bytes to 42
   Clear p[10], 42, 10

   'check the values of the allocated bytes
   For i As Integer = 0 To 19
      Print i, p[i]
   Next

   'deallocate memory
   Deallocate p

Differences from QB
   * The behavior and usage is new to FreeBASIC
   * The keyword CLEAR was used in QB to erase all variables, close all 
     files, and optionally change the stack size. This use is not supported 
     in FreeBASIC.

See also
   * Erase
   * Reset



------------------------------------------------------------- KeyPgClng ----
CLng

Converts numeric or string expression to Long

Syntax
   Declare Function CLng ( ByVal expression As datatype ) As Long

   Type typename
      Declare Operator Cast ( ) As Long
   End Type

Usage
   result = CLng( numeric expression )
   result = CLng( string expression )
   result = CLng( user defined type )

Parameters
   expression
      a numeric, string, or pointer expression to cast to a Long value
   datatype
      any numeric, string, or pointer data type
   typename
      a user defined type

Return Value
   A Long value.

Description
   The CLng function rounds off the decimal part and returns a 32-bit Long 
   value.  The function does not check for an overflow, and results are 
   undefined for values which are less than -2 147 483 648 or larger than 2 
   147 483 647.

   The name can be explained as 'Convert to LoNG'.

   If the argument is a string expression, it is converted to numeric by 
   using ValInt.

Example

   ' Using the CLNG function to convert a numeric value

   'Create an LONG variable
   Dim numeric_value As Long

   'Convert a numeric value
   numeric_value = CLng(-300.23)

   'Print the result, should return -300
   Print numeric_value
   Sleep

Differences from QB
   * The string argument was not allowed in QB

See also
   * CByte
   * CUByte
   * CShort
   * CUShort
   * CInt
   * CUInt
   * CULng
   * CLngInt
   * CULngInt
   * CSng
   * CDbl



---------------------------------------------------------- KeyPgClngint ----
CLngInt

Converts numeric or string expression to 64-bit integer (LongInt)

Syntax
   Declare Function CLngInt ( ByVal expression As datatype ) As LongInt

   Type typename
      Declare Operator Cast ( ) As LongInt
   End Type

Usage
   result = CLngInt( numeric expression )
   result = CLngInt( string expression )
   result = CLngInt( user defined type )

Parameters
   expression
      a numeric, string, or pointer expression to cast to a LongInt value
   datatype
      any numeric, string, or pointer data type
   typename
      a user defined type

Return Value
   A LongInt value.

Description
   The CLngInt function rounds off the decimal part and returns a 64-bit 
   LongInt value.  The function does not check for an overflow, and results 
   are undefined for values which are less than -9 223 372 036 854 775 808 
   or larger than 223 372 036 854 775 807.

   The name can be explained as 'Convert to LoNG INTeger'.

   If the argument is a string expression, it is converted to numeric by 
   using ValLng.

Example
   ' Using the CLNGINT function to convert a numeric value

   'Create an LONG INTEGER variable
   Dim numeric_value As LongInt

   'Convert a numeric value
   numeric_value = CLngInt(-12345678.123)

   'Print the result, should return -12345678
   Print numeric_value
   Sleep

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Clngint.

Differences from QB
   * New to FreeBASIC

See also
   * CByte
   * CUByte
   * CShort
   * CUShort
   * CInt
   * CUInt
   * CLng
   * CULng
   * CULngInt
   * CSng
   * CDbl



------------------------------------------------------------ KeyPgClose ----
Close

Stream I/O function to terminate access to a device

Syntax
   Close [[#]filenum ] [, [#]filenum ...]
             or 
   result = Close( [#filenum] )

Parameters
   filenum
      List of file numbers to close.

Return Value
   Close returns a 32 bit Long: a zero (0) on success and a non-zero error 
   code otherwise.

Description
   Closes the files whose file numbers are passed as arguments. If an 
   unused file number is passed, Close returns an error.

   Close without arguments closes all the files presently opened.

   Terminating the program using an End statement will automatically close 
   all files.

   The error code returned by Close can be checked using Err in the next 
   line. The function version of  Close returns directly the error code as 
   a 32 bit Long.

Example
   ' Create a string and fill it.
   Dim buffer As String, f As Integer

   buffer = "Hello World within a file."

   ' Find the first free file number.
   f = FreeFile

   ' Open the file "file.ext" for binary usage, using the number "f".
   Open "file.ext" For Binary As #f

     ' Place our string inside the file, using number "f".
     Put #f, , buffer

   ' Close the file.  We could also do 'Close #f', but it's only necessary if more than one number is open.
   Close

   ' End of program. (Check the file "file.ext" upon running to see the output.)

Differences from QB
   * Close can be called as a function that returns an error code.
   * FB throws an error on trying to close an unused file number, if 
     compiled with error checking and if not used with the function-style 
     syntax

See also
   * Open
   * Put (File I/O) 
   * Get (File I/O)
   * FreeFile



-------------------------------------------------------------- KeyPgCls ----
Cls

Clears the screen in both text modes and graphics modes

Syntax
   Declare Sub Cls ( ByVal mode As Long = 1 )

Usage
   Cls mode

Parameters
   mode
      A optional numeric variable with a value from 0 to 2.  If omitted, it 
      defaults to 1.

Description
   An optional mode parameter may be given,

      If omitted, Cls clears either the text or graphics viewport.  If a 
      graphics viewport has been defined using the View (Graphics) 
      statement, the graphics viewport is cleared.  Otherwise, the text 
      viewport, defined by View Print, is cleared.  (If there is no 
      explicit text viewport defined, the entire screen is cleared.)

      If 0, clears the entire screen

      If 1, clears the graphics viewport if defined.  Otherwise, clears the 
      text viewport

      If 2, clears the text viewport

Example
   '' set the color to light grey text on a blue background
   Color 7, 1

   '' clear the screen to the background color
   Cls

   '' print text in the center of the screen
   Locate 12, 33
   Print "Hello Universe!"

In graphics modes, if you want to clear the entire screen to color 0, it 
can be faster using  Clear to write zeroes to the screen memory than 
calling Cls.

   Dim scrbuf As Byte Ptr, scrsize As Integer
   Dim As Integer scrhei, scrpitch
   Dim As Integer r = 0, dr = 1

   ScreenRes 640, 480, 8

   scrbuf = ScreenPtr: Assert( scrbuf <> 0 )
   ScreenInfo( , scrhei, , , scrpitch )
   scrsize = scrpitch * scrhei

   Do
      
      '' lock the screen (must do this while working directly on screenbuffer)
      ScreenLock
         
         '' clear the screen (could use Cls here):
         Clear *scrbuf, 0, scrsize
         
         '' draw circle
         Circle (320, 240), r
         
      ScreenUnlock
      
      '' grow/shrink circle radius
      r += dr
      If r <= 0 Then dr = 1 Else If r >= 100 Then dr = -1
      
      '' short pause in each frame (prevents hogging the CPU)
      Sleep 1, 1
      
      '' run loop until user presses a key
   Loop Until Len(Inkey) > 0

Differences from QB
   * None

See also
   * Color
   * Locate
   * Print
   * ?
   * View (Graphics)



------------------------------------------------------------ KeyPgColor ----
Color

Sets the display foreground / background color that is used with console 
output and graphics output of text

Syntax
   Declare Function Color ( ByVal foreground As ULong , ByVal background As 
   ULong ) As ULong

Usage
   Color [foreground] [, background]
   result = Color [( [foreground] [, background] )]

Parameters
   foreground
      the foreground color to set
   background
      the background color to set

Return Value
   Returns a 32-bit value containing the current foreground color in the 
   Low Word and the current background color in the High Word.
   In hi/truecolor modes, only the foreground color is returned, taking up 
   the whole 32 bits. Instead, see ScreenControl to return the current 
   graphics mode color (foreground and background).

   The old color values can be retrieved at the same time as setting new 
   ones.

Description
   The Color statement sets the current foreground and/or background 
   colors. Circle, Draw, Line (Graphics), Cls, Paint, Print, PReset and PSet
   all use the last colors set by this function when you don't specify a 
   color to them, where applicable. The color values that Color accepts 
   depend on the current graphics mode.

      +---------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
      |Mode     |Meaning                                                                                                                                                                                                                             |
      |1        |foreground is screen color (ranging 0-15). background is the emulated CGA palette to be used: 0 (green, red, and brown), 1 (cyan, magenta and white), 2 (same as 0, but with bright colors) or 3 (same as 1, but with bright colors)|
      |2, 11    |foreground is a color index in current palette (ranging 0-1). background is a color index in current palette (ranging 0-1).                                                                                                         |
      |7, 8     |foreground is a color index in current palette (ranging 0-15). background is screen color index in current palette (ranging 0-15).                                                                                                  |
      |9        |foreground is a color index in current palette (ranging 0-63). background is screen color index in current palette (ranging 0-63).                                                                                                  |
      |12       |foreground is a color index in current palette (ranging 0-15). background is a color index in current palette (ranging 0-15).                                                                                                       |
      |13 and up|foreground is a color index in current palette (ranging 0-255). background is a color index in current palette (ranging 0-255).                                                                                                     |
      +---------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

   If you are using a color depth higher than 8bpp, foreground and 
   background are direct RGB color values in the form &hAARRGGBB, where AA, 
   RR, GG and BB are the alpha, red, green and blue components ranging &h00
   -&hFF (0-255 in decimal notation). While in hi/truecolor modes, you can 
   use the RGB or RGBA macro to obtain a valid color value.
   A Default Palette is automatically set when entering a Screen mode. 

Example
   ' Sets 320x240 in 32bpp color depth
   Screen 14, 32

   ' Sets orange foreground and dark blue background color
   Color RGB(255, 128, 0), RGB(0, 0, 64)

   ' Clears the screen to the background color
   Cls                     

   ' Prints "Hello World!" in the middle of the screen
   Locate 15, 14
   Print "Hello World!"

   Sleep

   Dim c As ULong

   'retrieve current color values
   c = Color()

   'extract color values from c using LOWORD and HIWORD
   Print "Console colors:"
   Print "Foreground: " & LoWord(c)
   Print "Background: " & HiWord(c)

   ' In 32-bit color depth, Function Color() returns only the foreground color

   #include "fbgfx.bi"

   '' screencontrol expects integer/uinteger
   Dim As UInteger fgcolor, bkcolor

   ScreenRes 500, 500, 32
   Width 500\8, 500\16
   Color &HFFFF00, &H0000FF
   Cls

   Print "From Function Color():"
   Print "  Foreground Color: "; Hex(Color(), 8)
   Print

   ScreenControl FB.GET_COLOR, fgcolor, bkcolor
   Print "From Sub ScreenControl():"
   Print "  Foreground Color: "; Hex(fgcolor, 8)
   Print "  Background Color: "; Hex(bkcolor, 8)

   Sleep

Differences from QB
   * Direct color modes were not supported in QB.
   * There is no border argument.

See also
   * RGB
   * RGBA
   * LoWord
   * HiWord
   * Locate
   * Palette
   * Screen



---------------------------------------------------------- KeyPgCommand ----
Command

Returns command line parameters used to call the program

Syntax
   Declare Function Command ( ByVal index As Long = -1 ) As String

Usage
   result = Command[$]( [ index ] )

Parameters
   index
      Zero-based index for a particular command-line argument.

Return Value
     Returns the command-line arguments(s).

Description
   Command returns command-line arguments passed to the program upon 
   execution.

   If index is less than zero (< 0), a space-separated list of all 
   command-line arguments is returned, otherwise, a single argument is 
   returned. A value of zero (0) returns the name of the executable; and 
   values of one (1) and greater return each command-line argument.

   If index is greater than the number of arguments passed to the program, 
   the null string ("") is returned.

   When the command line is parsed for arguments, everything between double 
   quotes in the parameter list will be considered as a single block, and 
   is returned without the double quotes.

   By default, filename globbing for arguments (expansion of wildcards to 
   filenames) is used on all ports of FreeBASIC for compatibility.  
   Arguments on the command line containing wildcards are typically not 
   expanded if when no file is matched or if properly quoted.  Other 
   special characters for redirection are typically not returned unless 
   properly quoted.  Consult the documentation on the shell being used for 
   more information on the proper quoting of command line arguments.

   WARNING: By nature of constructor precedence in FreeBASIC and main() 
   initialization, calling Command within a global constructor (module 
   constructor or UDT constructor called for static/shared object) is not 
   safe (may even induce a runtime error).

   Disabling filename globbing under Win32
      Define the following global variable(s) somewhere in the source:
   '' For MinGW.org and Cygwin runtimes:
   Extern _CRT_glob Alias "_CRT_glob" As Long
   Dim Shared _CRT_glob As Long = 0

   '' For MinGW-w64 runtime:
   Extern _dowildcard Alias "_dowildcard" As Long
   Dim Shared _dowildcard As Long = 0

   Disabling filename globbing under Dos
      Define the following function somewhere in the source:
   Function __crt0_glob_function Alias "__crt0_glob_function" ( ByVal arg As UByte Ptr ) As UByte Ptr Ptr
     Return 0
   End Function

   Disabling filename globbing under Linux
      Filename globbing is handled by the command shell.  Quote the 
      argument containing wildcards or disable filename globbing in the 
      shell prior to executing the command.  For example in bash use 'set 
      -f' to disable wildcard expansion

Example
   Print "program launched via: " & Command(0)

   Dim As Integer i = 1
   Do
      Dim As String arg = Command(i)
      If Len(arg) = 0 Then
         Exit Do
      End If

      Print "command line argument " & i & " = """ & arg & """"
      i += 1
   Loop

   If i = 1 Then
      Print "(no command line arguments)"
   End If

   Sleep

Dialect Differences
   * The string type suffix "$" is obligatory in the -lang qb dialect.
   * The string type suffix "$" is optional in the -lang fblite dialect.
   * The string type suffix "$" is forbidden in the -lang fb dialect.

Differences from QB
   * The numeric argument was not supported in QB.
   * QB converted the parameter list to uppercase before returning it, 
     FreeBASIC doesn't.
   * By default arguments containing wildcard characters are expanded 
     (filename globbing)

See also
   * __FB_ARGC__
   * __FB_ARGV__
   * Exec
   * Run



----------------------------------------------------------- KeyPgCommon ----
Common

Variable declaration and scope modifier

Syntax
   Common [Shared] symbolname[()] [AS DataType] [, ...]

Description
   Declares a variable which is shared between code modules. A matching 
   Common statement must appear in all other code modules using the 
   variable. 

   Common variables cannot be initialized.
   Common arrays are always variable-length, and must be defined with an 
   empty parameter list (), and its dimensions set in a later Dim or ReDim 
   statement.
   Common variables cannot be instances of a user-defined type having a 
   constructor or a destructor even implicit.

   The Shared optional parameter makes the variable global so that it can 
   be used inside Subs and Functions, as well as at module level.

Example
   '' common1.bas

   Declare Sub initme()

   Common Shared foo() As Double

   ReDim foo(0 To 2)

   initme()

   Print foo(0), foo(1), foo(2)

   '' common2.bas

   Common Shared foo() As Double

   Sub initme()
     foo(0) = 4*Atn(1)
     foo(1) = foo(0)/3
     foo(2) = foo(1)*2
   End Sub

After compiling the two files like:
fbc common1.bas common2.bas
running common1 produces the output:

    3.141592653589793           1.047197551196598           2.094395102393195

Differences from QB
   * The arrays will be always variable-length.
   * blockname is not needed and must be removed because the order of 
     declaration no longer matters, only the symbol names.

See also
   * Dim
   * Erase
   * Extern
   * LBound
   * ReDim
   * Preserve
   * Shared
   * Static
   * UBound
   * Var



---------------------------------------------------- KeyPgCondBroadcast ----
CondBroadcast

Restarts all threads CondWaiting for the handle

Syntax
   Declare Sub CondBroadcast ( ByVal handle As Any Ptr )

Usage
   CondBroadcast ( handle )

Parameters
   handle
      The handle of a conditional variable, or the null pointer (0) on 
      failure.

Description
   Once the conditional is CondCreate and the threads are started, one of 
   more of them (including the main thread executing main program) can be 
   set to CondWait for the conditional, they will be stopped until some 
   other thread CondSignals that the waiting thread can restart. 
   CondBroadcast can be used to restart all threads waiting for the 
   conditional. At the end of the program CondDestroy must be used to avoid 
   leaking resources in the OS.

   Condbroadcast must be used instead of CondSignal to restart all threads 
   waiting on the conditional.

Example
   See CondCreate

Platform Differences
   * Condbroadcast is not available with the DOS version / target of 
     FreeBASIC, because multithreading is not supported by DOS kernel nor 
     the used extender.
   * In Linux the threads are always started in the order they are 
     created, this can't be assumed in Win32. It's an OS, not a FreeBASIC 
     issue. 

Dialect Differences
   * Threading is not allowed in -lang qb

Differences from QB
   * New to FreeBASIC

See also
   * CondCreate
   * CondDestroy
   * CondSignal
   * CondWait
   * ThreadCreate



------------------------------------------------------- KeyPgCondCreate ----
CondCreate

Creates a conditional variable to be used in synchronizing threads

Syntax
   Declare Function CondCreate ( ) As Any Ptr

Usage
   result = CondCreate

Return Value
   A handle to a newly created conditional variable, or the null pointer 
   (0) on failure.

Description
   Once the conditional is Condcreated and the threads are started, one or 
   more of them (including the main thread executing main program) can be 
   set to CondWait for the conditional, they will be stopped until some 
   other thread CondSignals that the waiting thread can restart. 
   CondBroadcast can be used to restart all threads waiting for the 
   conditional. At the end of the program CondDestroy must be used to avoid 
   leaking resources in the OS.

Example
   See also CondWait and CondSignal

   ''
   '' make newly-created threads wait until all threads are ready, then start them all at once
   ''

   Dim Shared hcondstart As Any Ptr
   Dim Shared hmutexstart As Any Ptr
   Dim Shared start As Integer = 0

   Dim Shared threadcount As Integer
   Dim Shared hmutexready As Any Ptr
   Dim Shared hcondready As Any Ptr

   Sub mythread(ByVal id_ptr As Any Ptr)
      Dim id As Integer = Cast(Integer, id_ptr)
     
      '' signal that this thread is ready
      MutexLock hmutexready
      threadcount += 1
      Print "Thread #" & id & " is waiting..."
      CondSignal hcondready
      MutexUnlock hmutexready
      
      '' wait for the start signal
      MutexLock hmutexstart
      Do While start = 0   
         CondWait hcondstart, hmutexstart
      Loop

      '' now this thread holds the lock on hmutexstart
      
      MutexUnlock hmutexstart

      '' print out the number of this thread
      For i As Integer = 1 To 40
         Print id;
      Next i
   End Sub

   Dim threads(1 To 9) As Any Ptr

   hcondstart = CondCreate()
   hmutexstart = MutexCreate()

   hcondready = CondCreate()
   hmutexready = MutexCreate()

   threadcount = 0

   MutexLock(hmutexready)
   For i As Integer = 1 To 9
      threads(i) = ThreadCreate(@mythread, Cast(Any Ptr, i))
      If threads(i) = 0 Then
         Print "unable to create thread"
      End If
   Next i

   Print "Waiting until all threads are ready..."

   Do Until threadcount = 9
      CondWait(hcondready, hmutexready)
   Loop
   MutexUnlock(hmutexready)

   Print
   Print "Go!"

   MutexLock hmutexstart
   start = 1
   CondBroadcast hcondstart
   MutexUnlock hmutexstart

   '' wait for all threads to complete
   For i As Integer = 1 To 9
      If threads(i) <> 0 Then
         ThreadWait threads(i)
      End If
   Next i

   MutexDestroy hmutexready
   CondDestroy hcondready

   MutexDestroy hmutexstart
   CondDestroy hcondstart

   'Visual example of mutual exclusion + mutual synchronization between 2 threads
   'by using Mutex and CondVar:
   'the "user-defined thread" computes the points coordinates on a circle,
   'and the "main thread" plots the points.
   '
   'Principle of mutual exclusion + mutual synchronisation
   '          Thread#A               XOR + <==>             Thread#B
   '.....                                          .....
   'MutexLock(mut)                                 MutexLock(mut)
   '  Do_something_with_exclusion                    Do_something_with_exclusion
   '  While bool#1 <> true <------------------------ bool#1 = true
   '    CondWait(cond#1, mut) <--------------------- CondSignal(cond#1)
   '  Wend <-----------------------------------.     Do_something_with_exclusion
   '  bool#1 = false               .---------- | --> While bool#2 <> true
   '  Do_something_with_exclusion  |   .------ | ----> CondWait(cond#2, mut)
   '  bool#2 = true ---------------'   |   .-- | --> Wend
   '  CondSignal(cond#2) --------------'   |   |     bool#2 = false
   '  Do_something_with_exclusion          |   |     Do_something_with_exclusion
   'MutexUnlock(mut) ----------------------'   '-- MutexUnlock(mut)
   '.....                                          .....
   '
   'Behavior:
   '- Unnecessary to pre-calculate the first point.
   '- Each calculated point is plotted one time only.
   '
   'If you comment out the lines containing "MutexLock" and "MutexUnlock",
   '"CondWait" and "CondSignal", ".ready"
   '(inside "user-defined thread" or/and "main thread"),
   'there will be no longer mutual exclusion nor mutual synchronization
   'between computation of coordinates and plotting of points,
   'and many points will not be plotted on circle (due to non coherent coordinates).

   '-----------------------------------------------------------------------------------------------------

   Type ThreadUDT                                   'Generic user thread UDT
      Dim handle As Any Ptr                        'Any Ptr handle to user thread
      Dim sync As Any Ptr                          'Any Ptr handle to mutex
      Dim cond1 As Any Ptr                         'Any Ptr handle to conditional1
      Dim cond2 As Any Ptr                         'Any Ptr handle to conditional2
      Dim ready1 As Byte                           'Boolean to coordinates ready1
      Dim ready2 As Byte                           'Boolean to coordinates ready2
      Dim quit As Byte                             'Boolean to end user thread
      Declare Static Sub Thread (ByVal As Any Ptr) 'Generic user thread procedure
      Dim procedure As Sub (ByVal As Any Ptr)      'Procedure(Any Ptr) to be executed by user thread
      Dim p As Any Ptr                             'Any Ptr to pass to procedure executed by user thread
      Const False As Byte = 0                      'Constante "false"
      Const True As Byte = Not False               'Constante "true"
   End Type

   Static Sub ThreadUDT.Thread (ByVal param As Any Ptr) 'Generic user thread procedure
      Dim tp As ThreadUDT Ptr = param                  'Casting to generic user thread UDT
      Do
         Static As Integer I
         MutexLock(tp->sync)                          'Mutex (Lock) for user thread
         tp->procedure(tp->p)                         'Procedure(Any Ptr) to be executed by user thread
         I += 1
         Locate 30, 38
         Print I;
         tp->ready1 = True                            'Set ready1
         CondSignal(tp->cond1)                        'CondSignal to send signal1 to main thread
         While tp->ready2 <> True                     'Process loop against spurious wakeups
            CondWait(tp->cond2, tp->sync)            'CondWait to receive signal2 from main-thread
         Wend
         tp->ready2 = False
         If tp->quit = tp->True Then                  'Test for ending user thread
            MutexUnlock(tp->sync)                    'Mutex (Unlock) for user thread
            Exit Do
         End If
         MutexUnlock(tp->sync)                        'Mutex (Unlock) for user thread
         Sleep 5
      Loop
   End Sub

   '-----------------------------------------------------------------------------------------------------

   Type Point2D
      Dim x As Integer
      Dim y As Integer
   End Type

   Const x0 As Integer = 640 / 2
   Const y0 As Integer = 480 / 2
   Const r0 As Integer = 200

   Const pi As Single = 4 * Atn(1)

   Sub PointOnCircle (ByVal p As Any Ptr)
      Dim pp As Point2D Ptr = p
      Dim teta As Single = 2 * pi * Rnd
      pp->x = x0 + r0 * Cos(teta)
      Sleep 5                            'To increase possibility of uncorrelated data occurrence
      pp->y = y0 + r0 * Sin(teta)
   End Sub

   Screen 12
   Locate 30, 2
   Print "<any_key> : exit";
   Locate 30, 27
   Print "calculated:";
   Locate 30, 54
   Print "plotted:";

   Dim Pptr As Point2D Ptr = New Point2D

   Dim Tptr As ThreadUDT Ptr = New ThreadUDT
   Tptr->sync = MutexCreate
   Tptr->cond1 = CondCreate
   Tptr->cond2 = CondCreate
   Tptr->procedure = @PointOnCircle
   Tptr->p = Pptr
   Tptr->handle = ThreadCreate(@ThreadUDT.Thread, Tptr)

   Do
      Static As Integer I
      MutexLock(Tptr->sync)                 'Mutex (Lock) for main thread
      While Tptr->ready1 <> Tptr->True      'Process loop against spurious wakeups
         CondWait(Tptr->cond1, Tptr->sync) 'CondWait to receive signal1 from user-thread
      Wend
      Tptr->ready1 = Tptr->False
      PSet (Pptr->x, Pptr->y)               'Plotting one point
      I += 1
      Locate 30, 62
      Print I;
      Tptr->ready2 = Tptr->True             'Set ready2
      CondSignal(Tptr->cond2)               'CondSignal to send signal2 to user thread
      If Inkey <> "" Then
         Tptr->quit = Tptr->True           'Set quit
         MutexUnlock(Tptr->sync)           'Mutex (Unlock) for main thread
         Exit Do
      End If
      MutexUnlock(Tptr->sync)               'Mutex (Unlock) for main thread
      Sleep 5
   Loop
    

   ThreadWait(Tptr->handle)
   MutexDestroy(Tptr->sync)
   CondDestroy(Tptr->cond1)
   CondDestroy(Tptr->cond2)
   Delete Tptr
   Delete Pptr

   Sleep

   See also the similar MutexCreate example

Platform Differences
   * Condcreate is not available with the DOS version / target of 
     FreeBASIC, because multithreading is not supported by DOS kernel nor 
     the used extender.

Dialect Differences
   * Threading is not allowed in -lang qb

Differences from QB
   * New to FreeBASIC

See also
   * CondBroadcast
   * CondDestroy
   * CondSignal
   * CondWait
   * MutexCreate
   * MutexLock
   * MutexUnlock
   * ThreadCreate



------------------------------------------------------ KeyPgCondDestroy ----
CondDestroy

Destroys a multi-threading conditional variable when it is no more needed

Syntax
   Declare Sub CondDestroy ( ByVal handle As Any Ptr )

Usage
   CondDestroy ( handle )

Parameters
   handle
      The handle of a conditional variable to destroy.

Description
   Once the conditional is CondCreated and the threads are started, one of 
   more of them (including the main thread executing main program) can be 
   set to CondWait for the conditional, they will be stopped until some 
   other thread CondSignals that the waiting thread can restart. 
   CondBroadcast can be used to restart all threads waiting for the 
   conditional. At the end of the program CondDestroy must be used to avoid 
   leaking resources in the OS.

   Conddestroy destroys a condition variable, freeing the resources it 
   might hold. No threads must be waiting on the condition variable on 
   entrance to Conddestroy.

Example
   See CondCreate, CondWait and CondSignal

Platform Differences
   * Conddestroy is not available with the DOS version / target of 
     FreeBASIC, because multithreading is not supported by DOS kernel nor 
     the used extender.

Dialect Differences
   * Threading is not allowed in -lang qb

Differences from QB
   * New to FreeBASIC

See also
   * CondCreate
   * CondBroadcast
   * CondSignal
   * CondWait
   * ThreadCreate



------------------------------------------------------- KeyPgCondSignal ----
CondSignal

Restarts a thread suspended by a call to CondWait

Syntax
   Declare Sub CondSignal ( ByVal handle As Any Ptr )

Usage
   CondSignal ( handle )

Parameters
   handle
      The handle of a conditional variable, or the null pointer (0) on 
      failure.

Description
   Once the conditional is created with CondCreate and the threads are 
   started, one of more of them (including the main thread executing main 
   program) can be set to CondWait for the conditional, they will be 
   stopped until some other thread CondSignals that the waiting thread can 
   restart. CondBroadcast can be used to restart all threads waiting for 
   the conditional. At the end of the program CondDestroy must be used to 
   avoid leaking resources in the OS.

   Condsignal restarts one thread waiting. It should be called after mutex 
   is locked (using the same mutex as one used with CondWait). If no 
   threads are waiting on the conditional, nothing happens (the signal is 
   lost forever); if several are waiting, only one is restarted. The caller 
   must then unlock mutex in order for CondWait routine to complete.

Example
   See also CondCreate and CondWait

   ' This very simple example code demonstrates the use of several condition variable routines.
   ' The main routine initializes a string and creates one thread.
   ' The main routine waits until receive the condition signal from the thread, then print the complemented string.
   ' The thread complements the string, then sends a condition signal.
   '
   'Principle of mutual exclusion + simple synchronization
   '          Thread#A             XOR + ==>            Thread#B
   '.....                                     .....
   'MutexLock(mut)                            MutexLock(mut)
   '  Do_something_with_exclusion               Do_something_with_exclusion
   '  Thread_signal = true -------------------> While Thread_signal <> true
   '  CondSignal(cond) -------------------------> CondWait(cond, mut)
   '  Do_something_with_exclusion      .------> Wend
   'MutexUnlock(mut) ------------------'        Thread_signal = false
   '.....                                       Do_something_with_exclusion
   '.....                                     MutexUnlock(mut)
   '.....                                     .....

   Dim Shared As Any Ptr mutex
   Dim Shared As Any Ptr cond
   Dim Shared As String txt
   Dim As Any Ptr pt
   Dim Shared As Integer ok = 0

   Sub thread (ByVal p As Any Ptr)
      Print "thread is complementing the string"
      MutexLock(mutex)
      Sleep 400
      txt &= " complemented by thread"
      ok = 1
      CondSignal(cond)
      MutexUnlock(mutex)
      Print "thread signals the processing completed"
   End Sub

   mutex = MutexCreate
   cond = CondCreate

   txt = "example of text"
   Print "main() initializes a string = " & txt
   Print "main creates one thread"
   Print
   pt = ThreadCreate(@thread)
   MutexLock(mutex)
   While ok <> 1
      CondWait(cond, mutex)
   Wend
   Print
   Print "back in main(), the string = " & txt
   ok = 0
   MutexUnlock(mutex)

   ThreadWait(pt)
   MutexDestroy(mutex)
   CondDestroy(cond)

Dialect Differences
   * Threading is not allowed in -lang qb

Platform Differences
   * Condsignal is not available with the DOS version / target of 
     FreeBASIC, because multithreading is not supported by DOS kernel nor 
     the used extender.
   * In Linux the threads are always started in the order they are 
     created, this can't be assumed in Win32. It's an OS, not a FreeBASIC 
     issue. 

Differences from QB
   * New to FreeBASIC

See also
   * CondCreate
   * CondDestroy
   * CondBroadcast
   * CondWait
   * ThreadCreate



--------------------------------------------------------- KeyPgCondWait ----
CondWait

Stops execution of current thread until some condition becomes true

Syntax
   Declare Sub CondWait ( ByVal handle As Any Ptr, ByVal mutex As Any Ptr )

Usage
   CondWait ( handle, mutex )

Parameters
   handle
      The handle of a conditional variable, or the null pointer (0) on 
      failure.
   mutex
      The mutex associated with this conditional variable, which must be 
      locked when testing the condition and calling CondWait.

Description
   Function that stops the thread where it is called until some other 
   thread  CondSignals or CondBroadcasts  the handle.

   Once the conditional variable is created with CondCreate and the threads 
   are started, one of more of them (including the main thread executing 
   main program) can be set to CondWait for the conditional; they will be 
   stopped until some other thread CondSignals that the waiting thread can 
   restart. CondBroadcast can be used to restart all threads waiting for 
   the conditional. At the end of the program CondDestroy must be used to 
   avoid leaking resources in the OS.

   When calling CondWait, mutex should already be locked (using the same 
   mutex as one used with CondSignal or CondBroadcast). An atomic unlock of 
   the mutex and wait on the conditional variable will occur. The calling 
   thread execution is suspended and does not consume any CPU time until 
   the condition variable is signaled. When the condition variable becomes 
   signaled, mutex will be locked again and then execution will return to 
   the thread after the CondWait call, but with the mutex owned by the 
   caller. The caller is then responsible for unlocking mutex in order to 
   complete CondWait routine so that execution after the CondWait call can 
   then resume.

   Note: It is a good habit to use CondWait in a protected way against 
   eventual spurious wakeups.
   For that, CondWait is put within a loop for checking that a Boolean 
   predicate is indeed true (predicate set true by another thread just 
   before executing CondSignal or CondBroadcast) when the thread has 
   finished waiting: [While predicate <> true : Condwait(handle, mutex) : 
   Wend]. The loop can terminate only when the predicate is true.
   On the other hand, if the predicate is already true before the thread 
   reaches the loop, CondWait is downright skipped (allowing to take into 
   account a case of CondSignal or CondBroadcast that would have been lost 
   otherwise, because prematurely executed in a second thread before the 
   first thread is really waiting for this).
   See example below for detailed coding.

Example
   See also CondCreate and CondSignal

   ' This simple example code demonstrates the use of several condition variable routines.
   ' The main routine creates three threads.
   ' Two of the threads update a "count" variable.
   ' The third thread waits until the count variable reaches a specified value.

   #define numThread  3
   #define countThreshold 6

   Dim Shared As Integer count = 0
   Dim Shared As Any Ptr countMutex
   Dim Shared As Any Ptr countThresholdCV
   Dim As Any Ptr threadID(0 To numThread-1)
   Dim Shared As Integer ok = 0

   Sub threadCount (ByVal p As Any Ptr)
      Print "Starting threadCount(): thread#" & p
      Do
         Print "threadCount(): thread#" & p & ", locking mutex"
         MutexLock(countMutex)
         count += 1
         ' Check the value of count and signal waiting thread when condition is reached.
         ' Note that this occurs while mutex is locked.
         If count >= countThreshold Then
            If count = countThreshold Then
               Print "threadCount(): thread#" & p & ", count = " & count & ", threshold reached, unlocking mutex"
               ok = 1
               CondSignal(countThresholdCV)
            Else
               Print "threadCount(): thread#" & p & ", count = " & count & ", threshold exceeded, unlocking mutex"
            End If
            MutexUnlock(countMutex)
            Exit Do
         End If
         Print "threadCount(): thread#" & p & ", count = " & count & ", unlocking mutex"
         MutexUnlock(countMutex)
         Sleep 100
      Loop
   End Sub

   Sub threadWatch (ByVal p As Any Ptr)
      Print "Starting threadWatch(): thread#" & p & ", locking mutex, waiting for conditional"
      MutexLock(countMutex)
      ' Note that the Condwait routine will automatically and atomically unlock mutex while it waits.
      While ok = 0
         CondWait(countThresholdCV, countMutex)
      Wend
      Print "threadWatch(): thread#" & p & ", condition signal received"
      Print "threadWatch(): thread#" & p & ", count now = " & count & ", unlocking mutex"
      MutexUnlock(countMutex)
   End Sub

   ' Create mutex and condition variable
   countMutex = MutexCreate
   countThresholdCV = CondCreate
   ' Create threads
   threadID(0) = ThreadCreate(@threadWatch, Cast(Any Ptr, 1))
   threadID(1) = ThreadCreate(@threadCount, Cast(Any Ptr, 2))
   threadID(2) = ThreadCreate(@threadCount, Cast(Any Ptr, 3))
   ' Wait for all threads to complete
   For I As Integer = 0 To numThread-1
      ThreadWait(threadID(I))
      Print "Main(): Waited on thread#" & I+1 & " Done"
   Next I
   MutexDestroy(countMutex)
   CondDestroy(countThresholdCV)

Platform Differences
   * Condwait is not available with the DOS version / target of FreeBASIC, 
     because multithreading is not supported by DOS kernel nor the used 
     extender.
   * In Linux the threads are always started in the order they are 
     created, this can't be assumed in Win32. It's an OS, not a FreeBASIC 
     issue. 

Dialect Differences
   * Threading is not allowed in -lang qb

Differences from QB
   * New to FreeBASIC

See also
   * CondCreate
   * CondDestroy
   * CondBroadcast
   * CondSignal
   * MutexCreate
   * MutexLock
   * MutexUnlock
   * ThreadCreate



------------------------------------------------------------ KeyPgConst ----
Const

Non-modifiable variable declaration.

Syntax
   Const symbolname1 [AS DataType] = value1 [, symbolname2 [AS DataType] = 
   value2, ...]
      or
   Const [AS DataType] symbolname1 = value1 [, symbolname2 = value2, ...]

Description
   Declares non-modifiable constant data that can be integer or decimal 
   (floating-point) numbers or strings. The constant type will be inferred 
   if DataType isn't explicitly given.

   Specifying String * Size, Zstring * Size or Wstring * Size as DataType 
   is not allowed.
   Specifying String as DataType is tolerated but without effect because 
   the resulting type is always a Zstring * Size.

   Constants follow visibility rules similar to those of variables for 
   Namespace blocks, Type blocks, and compound block statements.

Example
   Const Red = RGB(252, 2, 4)
   Const Black As UInteger = RGB(0, 0, 0)
   Const Text = "This is red text on a black bkgnd."

   Locate 1, 1
   Color Red, Black
   Print Text
   Sleep
   End

Differences from QB
   * QB does not support the As datatype syntax.

See also
   * #define
   * Const (Qualifier)
   * Const (Member)
   * Enum
   * Var



------------------------------------------------------ KeyPgConstMember ----
Const (Member)

Specifies that a member procedure is read only.

Syntax
   Type typename
      Declare Const Sub|Function|Property|Operator ...
   End Type

   Const Sub|Function|... typename ...
      ...
   End Sub|Function|...

Description
   Specifies that a method does not change the object it is called on. The 
   hidden This parameter will be considered read-only. The declaration can 
   be read as 'invoking a const method promises not to change the object', 
   and the compiler will error if the member procedure tries to change any 
   of the data fields, or calls a non-const member procedure. 

   Read-only (Const) declarations are a measure of type safety that can be 
   read as 'promises not to change.'  The compiler uses the const 
   declarations to check operations on variables and parameters and 
   generate an error at compile time if their data could potentially 
   change.  There is no runtime overhead for using Const qualifiers since 
   all of the checks are made at compile time.

   Constructors and destructors cannot be Const (not useful).
   Member procedures can not be both Const and Static since static member 
   procedures do not have a hidden This parameter.

   For methods with Const in their declaration, Const can also be specified 
   on the corresponding method bodies, for improved code readability.

Example
   '' Const Member Procedures

   Type foo
     x As Integer
     c As Const Integer = 0
     Declare Const Sub Inspect1()
     Declare Const Sub Inspect2()
     Declare Sub Mutate1()
     Declare Sub Mutate2()
   End Type

   ''
   Sub foo.Mutate1()
     '' we can change non-const data fields
     x = 1

     '' but we still can't change const data
     '' fields, they are promised not to change
     '' c = 1 '' Compile error

   End Sub

   ''
   Sub foo.Mutate2()
     '' we can call const members
     Inspect1()

     '' and non-const members
     Mutate1()

   End Sub

   ''
   Sub foo.Inspect1()
     '' can use data members
     Dim y As Integer
     y = c + x

     '' but not change them because Inspect1()
     '' is const and promises not to change foo
     '' x = 10 '' Compile error

   End Sub

   ''
   Sub foo.Inspect2()
     '' we can call const members
     Inspect1()

     '' but not non-const members
     '' Mutate1() '' Compile error

   End Sub

Differences from QB
   * New to FreeBASIC

See also
   * Const
   * Const (Qualifier)
   * Dim
   * Type



--------------------------------------------------- KeyPgConstQualifier ----
Const (Qualifier)

Specifies that a data type or pointer data type is read only.

Syntax
   ... As [Const] datatype [ [Const] Ptr ... ]

Parameters
   datatype
      Name of a standard or user defined data type.

Description
   Specifies that the datatype or Ptr immediately to the right of the Const 
   qualifier is to be considered as read only.  Read-only (Const) 
   declarations are a measure of type safety that can be read as 'promises 
   not to change.'  The compiler uses the const declarations to check 
   operations on variables and parameters and generate an error at compile 
   time if their data could potentially change.  There is no runtime 
   overhead for using Const qualifiers since all of the checks are made at 
   compile time.

   Const can be used anywhere data type declarations are made.  This 
   includes variables, parameters, function return results, user defined 
   type fields, type aliases, and casting.  The datatype can be any 
   built-in standard data type or user defined type.

   Read-only variables must have an initializer since modifying a read-only 
   variable through an assignment will generate a compiler error.  The 
   initializer may appear after the declaration of the variable.

   Both non-const and const variables may be passed to a procedure 
   expecting a const parameter.  However, a const variable may not be 
   passed to a procedure taking a non-const parameter, and will generate a 
   compile error.

   Procedures can be overloaded based on the const-ness of parameters.  For 
   example a procedure can be overloaded where one version of the procedure 
   takes a 'byref foo as bar' parameter and another version of the 
   procedure takes a 'byref foo as const bar' parameter.

   With pointer declarations, Const can be used to indicate which part of 
   the pointer declaration is read-only (all other parts are by default 
   read-write).  The read-only portion of the pointer data type could be 
   the pointer itself (the address), what the pointer points to (the data), 
   or both.  In a declaration with more than one level of Ptr indirection, 
   the right most Ptr indicates the highest order level of indirection and 
   is therefore dereferenced first.

   The compiler has an internal hard-limit of eight (8) levels of pointer 
   indirection with respect to const qualifiers and the behavior of using 
   Const with Ptr data types having greater than eight (8) levels of 
   indirection is undefined.

Example
   '' Const Variables

   '' procedure taking a const parameter
   Sub proc1( ByRef x As Const Integer )

     '' can't change x because it is const
     '' x = 10 '' compile error

     '' but we can use it in expressions and
     '' assign it to other variables
     Dim y As Integer
     y = x
     y = y * x + x

   End Sub

   '' procedure taking a non-const parameter
   Sub proc2( ByRef x As Integer )
     '' we can change the value
     x = 10
   End Sub

   '' declare a non-const and const variable
   Dim a As Integer
   Dim b As Const Integer = 5

   '' proc1() will accept a non-const or const
   '' argument because proc1() promises not to
   '' change the variable passed to it.
   proc1( a )
   proc1( b )

   '' proc2() will accept a non-const argument
   proc2( a )

   '' but not a const argument because proc2()
   '' might change the variable's data and we
   '' promised that 'b' would not change.
   '' proc2( b ) '' compile error

   '' Const Pointers

   '' an integer
   Dim x As Integer = 1
   Dim y As Integer = 2
   Dim z As Integer = 3

   '' To check that the compiler generates errors
   '' when attempting to reassign const variables,
   '' uncomment the assignments below.

   ''
   Scope
     '' a pointer to an integer
     Dim p As Integer Ptr = @x

     p = @y       /' OK - pointer can be changed '/
     *p = z       /' OK - data can be changed '/

   End Scope

   ''
   Scope
     '' a pointer to a constant integer
     Dim p As Const Integer Ptr = @x

     p = @y       /' OK - pointer can be changed '/
     '' *p = z    /' Error - data is const '/

   End Scope

   ''
   Scope
     '' a constant pointer to an integer
     Dim p As Integer Const Ptr = @x

     '' p = @y    /' Error - pointer is const '/
     *p = z       /' OK - data can be changed '/

   End Scope

   ''
   Scope
     '' a constant pointer to a constant integer
     Dim p As Const Integer Const Ptr = @x

     '' p = @y    /' Error - pointer is const '/
     '' *p = z    /' Error - data is const '/

   End Scope

   '' Const Parameters in an Overloaded Procedure

   '' procedure with non-const parameter
   Sub foo Overload( ByRef n As Integer )
     Print "called 'foo( byref n as integer )'"
   End Sub

   '' procedure with const parameter
   Sub foo Overload( ByRef n As Const Integer )
     Print "called 'foo( byref n as const integer )'"
   End Sub

   Dim x As Integer = 1
   Dim y As Const Integer = 2

   foo( x )
   foo( y )

   '' OUTPUT:
   '' called 'foo( byref n as integer )'
   '' called 'foo( byref n as const integer )'

Differences from QB
   * New to FreeBASIC

See also
   * Const
   * Const (Member)
   * Dim
   * Type



------------------------------------------------------ KeyPgConstructor ----
Constructor

Called automatically when a class or user defined type is created

Syntax
   Type typename
      Declare Constructor ( )
      Declare Constructor ( [ ByRef | ByVal ] parameter As datatype [ = 
      default ] [, ... ] )
   End Type

   Constructor typename ( [ parameters ] ) [ Export ]
      statements
   End Constructor

Parameters
   typename 
      name of the Type or Class

Description
   Constructor methods are called when a user defined Type or Class 
   variable is created.

   typename is the name of the type for which the Constructor method is 
   declared and defined.  Name resolution for typename follows the same 
   rules as procedures when used in a Namespace.

   More than one constructor may exist for a type or class.  The exact 
   constructor method called depends on the parameter signature matched 
   when the variable is initialized.  More than one parameter may exist in 
   a constructor method declaration.

   A constructor method is passed a hidden This parameter having the same 
   type as typename.  This is optionally used to access the fields of the 
   Type or Class which is to be initialized in the Constructor method.

   Constructors are called when declaring global or local static instances 
   of typename and when allocating typename dynamically using the 
   New Expression operator. See examples below for different constructor 
   syntaxes.

   A copy Constructor is a special constructor that initializes a new 
   object from an existing object. There are three general cases where the 
   copy Constructor is called: when instantiating one object and 
   initializing it with another object (in one instruction), when passing 
   an object by value, when an object is returned from a function by value 
   (by using Return x statement).
      Note: When an object is returned from a function by value, but by 
      using Function = x (or function_identifier = x) assignment, the 
      Constructor is called once at first, and then the Let (Assign) 
      operator at each assignment.
   A copy Constructor must be defined if the shallow implicit copy 
   constructor is not sufficient. This happens in cases when the object 
   manages dynamically allocated memory or other resources which need to be 
   specially constructed or copied (for example if a member pointer points 
   to dynamically allocated memory, the implicit copy constructor will 
   simply do an implicit pointer construction and a copy of value instead 
   of allocate memory and then perform the copy of data).
      Note: Even if is defined an explicit default Constructor, it is never 
      called by the implicit copy constructor.

   Chaining of constructors in nested types is supported.  Any fields that 
   have their own default constructor are called first.
   Chaining together constructors of a same type is allowed by using the 
   keyword Constructor(parameters) at the top of constructor. It prevents 
   the compiler from emitting field initialization code (instead, it relies 
   on the chained constructor to initialize everything).

   Constructor can be also called directly from the typename instance like 
   the other member methods (Sub) and with the same syntax, i.e. using a 
   member access operator, e.g. obj.Constructor(parameters). In particular, 
   doing this.Constructor(parameters) is not treated as chaining together 
   constructors of a same type, and it is allowed anywhere (not only at the 
   top of constructors). In general it's not safe to manually call the 
   constructor on an object, because no Destructor is called, and the old 
   object state - if any - is overwritten without any of its old members 
   being destroyed, which could cause memory/resource leaks.

Example
Simple constructor example for beginners.
   Type MyObj
     Foo As Integer Ptr
     
      '' Constructor to create our integer, and set its value.
     Declare Constructor( ByVal DefVal As Integer = 0 )
      '' Destroy our integer on object deletion.
     Declare Destructor()
   End Type

   Constructor MyObj( ByVal DefVal As Integer = 0 )
     Print "Creating a new integer in MyObj!"
     Print "The Integer will have the value of: " & DefVal
     Print ""
     
      '' Create a pointer, and set its value to the one passed to the
      '' Constructor.
     This.Foo = New Integer
     *This.Foo = DefVal
   End Constructor

   Destructor MyObj()
     Print "Deleting our Integer in MyObj!"
     Print ""
     
      '' Delete the pointer we created in MyObj.
     Delete This.Foo
     This.Foo = 0
   End Destructor

   Scope
      '' Create a MyObj type object
      '' Send the value of '10' to the constructor
     Dim As MyObj Bar = 10
     
      '' See if the integer's been created.  Print its value.
     Print "The Value of our integer is: " & *Bar.Foo
     Print ""
     
     Sleep
   End Scope
     '' We've just gone out of a scope.  The Destructor should be called now
     '' Because our objects are being deleted.
   Sleep

More advanced construction example, showing constructor overloading among 
other things.
   Type sample

     _text As String

     Declare Constructor ()
     Declare Constructor ( a As Integer )
     Declare Constructor ( a As Single  ) 
     Declare Constructor ( a As String, b As Byte ) 

     Declare Operator Cast () As String

   End Type

   Constructor sample ()
     Print "constructor sample ()"
     Print
     this._text = "Empty"
   End Constructor

   Constructor sample ( a As Integer )
     Print "constructor sample ( a as integer )"
     Print "  a = "; a
     Print
     this._text = Str(a)
   End Constructor

   Constructor sample ( a As Single )
     Print "constructor sample ( a as single )"
     Print "  a = "; a
     Print
     this._text = Str(a)
   End Constructor

   Constructor sample ( a As String, b As Byte )
     Print "constructor sample ( a as string, b as byte )"
     Print "  a = "; a
     Print "  b = "; b
     Print
     this._text = Str(a) + "," + Str(b)
   End Constructor

   Operator sample.cast () As String
     Return this._text
   End Operator

   Print "Creating x1"
   Dim x1 As sample

   Print "Creating x2"
   Dim x2 As sample = 1

   Print "Creating x3"
   Dim x3 As sample = 99.9

   Print "Creating x4"
   Dim x4 As sample = sample( "aaa", 1 )

   Print "Values:"
   Print "  x1 = "; x1
   Print "  x2 = "; x2
   Print "  x3 = "; x3
   Print "  x4 = "; x4

Example of copy constructor.
   Type UDT
     Dim As String Ptr p                     ''pointer to string
     Declare Constructor ()                  ''default constructor
     Declare Constructor (ByRef rhs As UDT)  ''copy constructor
     Declare Destructor ()                   ''destructor
   End Type

   Constructor UDT ()
     This.p = CAllocate(1, SizeOf(String))
   End Constructor

   Constructor UDT (ByRef rhs As UDT)
     This.p = CAllocate(1, SizeOf(String))
     *This.p = *rhs.p
   End Constructor

   Destructor UDT ()
     *This.p = ""
     Deallocate This.p
   End Destructor

   Dim As UDT u0
   *u0.p = "copy constructor exists"
   Dim As UDT u = u0
   *u0.p = ""  ''to check the independance of the result copy with the object copied
   Print *u.p
   Sleep

Dialect Differences
   * Object-related features are supported only in the -lang fb option

Differences from QB
   * New to FreeBASIC

See also
   * Class
   * Constructor (Module)
   * New Expression
   * Destructor
   * Type
   * Coercion and Conversion



------------------------------------------------ KeyPgModuleConstructor ----
Constructor (Module)

Specifies execution of a procedure before module-level code

Syntax
   [Public | Private] Sub procedure_name [Alias "external_identifier"] [()] 
   Constructor [priority] [Static]
      { procedure body }
   End Sub

Description
   The Constructor keyword is used in Sub definitions (forbidden at 
   declaration line level) to force execution of the procedure prior to 
   that of module-level code. Procedures defined as constructors may be 
   used the same way as ordinary procedures, that is, they may be called 
   from within module-level code, as well as other procedures.

   The procedure must have an empty parameter list.  A compile-time error 
   will be generated if the Constructor keyword is used in a Sub definition 
   having one or more parameters. In a set of overloaded procedures, only 
   one (1) constructor may be defined because of the ambiguity of having 
   multiple Subs which take no arguments.

   In a single module, depending on the build and run-time environment of 
   the target system:
      * constructors may execute in which they are defined, or reverse 
        order
      * constructors may execute before or after global static variables 
        having constructors
      * constructors may execute before or after other module constructors 
        having priority attribute
      * constructors with priority attribute may execute before or after 
        global static variables having constructors

   The priority attribute, an integer between 101 and 65535, can be used to 
   force constructors to be executed in a certain order, relative to other 
   constructors also having priority attribute.  The value of priority has 
   no specific meaning, only the relationship of the number with other 
   constructor priorities.  101 is the highest priority and is executed 
   first, relative to other constructors also having priority attribute.

   A module may define multiple constructor procedures, and multiple 
   modules may define additional constructors provided no two Public 
   constructors share the same procedure_name.

   When linking with modules that also define constructors, the order of 
   execution is not guaranteed at link-time unless the priority attribute 
   is used. Therefore, special care should be taken when using constructors 
   that may call on a secondary module also defining a constructor.  In 
   such a case it is advisable to use a single constructor that explicitly 
   calls initialization procedures in those modules.

   Public static member procedures (a Sub having an empty parameter list), 
   of user defined Type can be defined as a module constructor, by adding 
   the Constructor keyword used in the sub procedure definition.

   Initialization of static simple numeric type variables, that have a 
   value that can be determined at compile time (for example, default zero, 
   constants, pointers to static objects, pointers to functions, etc), are 
   initialized before any code is executed.  These values are part of the 
   executable image and have an initial value when the executable is loaded 
   in to memory.  Trivial static globals where no code is needed to 
   initialize, are guaranteed to be initialized and can be reliably used in 
   all code, including global static object constructors and module 
   constructors.

   The module constructor feature exposes a low-level link-time feature of 
   the build and run-time environment.  Accessing global static objects 
   having constructors from module constructors should be avoided due to 
   variations in execution order on different build systems.

Example
   '' ConDesExample.bas : An example program that defines two sets of
   '' constructors and destructors. Demonstrates when and in what order
   '' they are called when linking a single module.

   Sub Constructor1() Constructor
      Print "Constructor1() called"
   End Sub

   Sub Destructor1() Destructor
      Print "Destructor1() called"
   End Sub

   Sub Constructor2() Constructor
      Print "Constructor2() called"
   End Sub

   Sub Destructor2() Destructor
      Print "Destructor2() called"
   End Sub

      '' ----------------------
      Print "module-level code"

      End 0
      '' ----------------------

   Output:

   Constructor2() called
   Constructor1() called
   module-level code
   Destructor1() called
   Destructor2() called

Differences from QB
   * New to FreeBASIC

See also
   * Constructor (Class)
   * Destructor (Module)
   * Sub



--------------------------------------------------------- KeyPgContinue ----
Continue

Control flow statement to continue next iteration of a loop

Syntax
   Continue {Do | For | While}

Description
   Skips all code until the end clause of a loop structure, i.e. Do...Loop, 
   For...Next, or a While...Wend block, then executes the limit condition 
   check. In the case of a For...Next, the variable is incremented 
   according to the Step specified.

   Where there are multiple Do / For / While blocks nested, it will 
   continue on the innermost block of that type, i.e. the last one entered. 
   You can continue an earlier block of that type by giving the word 
   multiple times, separated by commas.  e.g. continue while, while

Example
   Dim As Integer n

   Print "Here are odd numbers between 0 and 10!"
   Print
   For n = 0 To 10

     If ( n Mod 2 ) = 0 Then 
      Continue For
     End If
     
     Print n
     
   Next n

    '' simple prime number finder

   Print "Here are the prime numbers between 1 and 20!"
   Print

   Dim n As Integer, d As Integer

   For n = 2 To 20
      
      For d = 2 To Int(Sqr(n))
         
         If ( n Mod d ) = 0 Then ' d divides n
            
            Continue For, For ' n is not prime, so try next n
            
         End If
         
      Next d
      
      Print n
      
   Next n

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Continue.

Differences from QB
   * New to FreeBASIC

See also
   * Exit



-------------------------------------------------------------- KeyPgCos ----
Cos

Returns the cosine of an angle

Syntax
   Declare Function Cos ( ByVal angle As Double ) As Double

Usage
   result = Cos( angle )

Parameters
   angle
      the angle (in radians)

Return Value
   Returns the cosine of the argument angle as a Double within the range of 
   -1.0 to 1.0.

Description
   The argument number is measured in radians (not degrees).

   The value returned by this function is undefined for values of angle 
   with an absolute value of 2 ^ 63 or greater.

   Cos can be overloaded as operator to accept user-defined types.

Example
   Const PI As Double = 3.1415926535897932
   Dim a As Double
   Dim r As Double
   Input "Please enter an angle in degrees: ", a
   r = a * PI / 180   'Convert the degrees to Radians
   Print ""
   Print "The cosine of a" ; a; " degree angle is"; Cos ( r ) 
   Sleep

Output:

   Please enter an angle in degrees: 30
   The cosine of a 30 degree angle Is 0.8660254037844387

Differences from QB
   * None

See also
   * Acos
   * Sin
   * Tan
   * A Brief Introduction To Trigonometry



------------------------------------------------------------- KeyPgCptr ----
CPtr

Converts a pointer expression to a specified data type pointer

Syntax
   CPtr( PointerDataType, expression )

Description
   Converts expression to PointerDataType.

   PointerDataType must be a Pointer type (e.g. a DataType Ptr or an Any Ptr
   ), or a Type (Alias) to one.
   expression may have a different pointer type or be an Integer.

   Note: Currently, FB does not actually enforce that PointerDataType must 
   be a pointer.  This will likely change in future versions though.  
   Currently, it may display a warning if you try to convert to a 
   non-pointer (for any conversion type if you compile with the -w pedantic 
   compiler switch).

Example
   Dim intval As Integer
   Dim intptr As Integer Ptr
   intval = &h0080
   intptr = @intval
   '' will print -128 and 128, as the first expression will be "seen" as an signed byte
   Print *CPtr( Byte Ptr, intptr ), *intptr

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Cptr.

Differences from QB
   * New to FreeBASIC

See also
   * Ptr
   * Cast
   * CByte
   * CShort
   * CInt
   * CLngInt
   * CSng
   * CDbl 



----------------------------------------------------------- KeyPgCshort ----
CShort

Converts numeric or string expression to an integer (Short)

Syntax
   Declare Function CShort ( ByVal expression As datatype ) As Short

   Type typename
      Declare Operator Cast ( ) As Short
   End Type

Usage
   result = CShort( numeric expression )
   result = CShort( string expression )
   result = CShort( user defined type )

Parameters
   expression
      a numeric, string, or pointer expression to cast to a Short value
   datatype
      any numeric, string, or pointer data type
   typename
      a user defined type

Return Value
   A Short value.

Description
   The CShort function rounds off the decimal part and returns a 16-bit 
   Short value.  The function does not check for an overflow, and results 
   are undefined for values which are less than -32 768 or larger than 32 
   767.

   The name can be explained as 'Convert to Short'.

   If the argument is a string expression, it is converted to numeric by 
   using ValInt.

Example
   ' Using the CSHORT function to convert a numeric value

   'Create an SHORT variable
   Dim numeric_value As Short

   'Convert a numeric value
   numeric_value = CShort(-4500.66)

   'Print the result, should return -4501
   Print numeric_value
   Sleep

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Cshort.

Differences from QB
   * New to FreeBASIC

See also
   * CByte
   * CUByte
   * CUShort
   * CInt
   * CUInt
   * CLng
   * CULng
   * CLngInt
   * CULngInt
   * CSng
   * CDbl



------------------------------------------------------------ KeyPgCsign ----
CSign

Converts an expression to signed

Syntax
   CSign ( expression )

Usage
   variable = CSign ( expression )

Description
   Converts an unsigned expression to a signed one, useful to force signed 
   behavior of division or multiplication (including with Shl and Shr).

   This is the opposite of CUnsg.

Example
   Dim value As UShort = 65535
   Print CSign(value)  '' will print -1

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Csign.

Differences from QB
   * New to FreeBASIC

See also
   * CUnsg



------------------------------------------------------------- KeyPgCsng ----
CSng

Converts numeric or string expression to Single precision floating point

Syntax
   Declare Function CSng ( ByVal expression As datatype ) As Single

   Type typename
      Declare Operator Cast ( ) As Single
   End Type

Usage
   result = CSng( numeric expression )
   result = CSng( string expression )
   result = CSng( user defined type )

Parameters
   expression
      a numeric, string, or pointer expression to cast to a Single value
   datatype
      any numeric, string, or pointer data type
   typename
      a user defined type

Return Value
   A Single precision value.

Description
   The CSng function returns a 32-bit Single value. The function does not 
   check for an overflow, so be sure not to pass a value outside the 
   representable range of the Single data type. The name can be explained 
   as 'Convert to SiNGle'.

   If the argument to CSng is a string expression, it is first converted to 
   numeric by using Val.

Example
   ' Using the CSNG function to convert a numeric value

   'Create an SINGLE variable
   Dim numeric_value As Single

   'Convert a numeric value
   numeric_value = CSng(-12345.123)

   'Print the result, should return -12345.123
   Print numeric_value
   Sleep

Differences from QB
   * The string argument was not allowed in QB

See also
   * CByte
   * CUByte
   * CShort
   * CUShort
   * CInt
   * CUInt
   * CLng
   * CULng
   * CLngInt
   * CULngInt
   * CDbl



----------------------------------------------------------- KeyPgCsrlin ----
CsrLin

Returns the row position of the cursor

Syntax
   Declare Function CsrLin ( ) As Integer

Usage
   result = CsrLin

Return Value
   An Integer specifying the current row of the cursor.

Description
   Returns the current row the cursor is on (i.e. the "cursor line").  The 
   topmost row is number 1.

Example
   Print "The cursor is on row:"; CsrLin

Differences from QB
   * None

See also
   * Locate
   * Pos



----------------------------------------------------------- KeyPgCubyte ----
CUByte

Converts numeric or string expression to an unsigned byte (UByte)

Syntax
   Declare Function CUByte ( ByVal expression As datatype ) As UByte

   Type typename
      Declare Operator Cast ( ) As UByte
   End Type

Usage
   result = CUByte( numeric expression )
   result = CUByte( string expression )
   result = CUByte( user defined type )

Parameters
   expression
      a numeric, string, or pointer expression to cast to a UByte value
   datatype
      any numeric, string, or pointer data type
   typename
      a user defined type

Return Value
   A UByte value.

Description
   The CUByte function rounds off the decimal part and returns a 8-bit UByte
   value. The function does not check for an overflow, and results are 
   undefined for values which are less than 0 or larger than 255.

   The name can be explained as 'Convert to Unsigned Byte'.

   If the argument is a string expression, it is converted to numeric by 
   using ValUInt.

Example
   ' Using the CUBYTE function to convert a numeric value

   'Create an UNSIGNED BYTE variable
   Dim numeric_value As UByte

   'Convert a numeric value
   numeric_value = CUByte(123.55)

   'Print the result, should return 124
   Print numeric_value
   Sleep

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Cubyte.

Differences from QB
   * New to FreeBASIC

See also
   * CByte
   * CShort
   * CUShort
   * CInt
   * CUInt
   * CLng
   * CULng
   * CLngInt
   * CULngInt
   * CSng
   * CDbl



------------------------------------------------------------ KeyPgCuint ----
CUInt

Converts numeric or string expression to a UInteger or UInteger<bits>

Syntax
   Declare Function CUInt ( ByVal expression As datatype ) As UInteger
   Declare Function CUInt<bits> ( ByVal expression As datatype ) As UInteger
   <bits>

   Type typename
      Declare Operator Cast ( ) As UInteger
      Declare Operator Cast ( ) As UInteger<bits>
   End Type

Usage
   result = CUInt( numeric expression )
   result = CUInt( string expression )
   result = CUInt( user defined type )

Parameters
   bits
      A numeric constant expression indicating the size in bits of unsigned 
      integer desired.  The values allowed are 8, 16, 32 or 64.
   expression
      a numeric, string, or pointer expression to cast to a UInteger or 
      UInteger<bits> value
   datatype
      any numeric, string, or pointer data type
   typename
      a user defined type

Return Value
   A UInteger or UInteger<bits> containing the converted value.

Description
   The CUInt function rounds off the decimal part and returns a UInteger 
   value, or if a bits value is supplied, an unsigned integer type of the 
   given size.

   The function does not check for an overflow; for example, for a 32-bit 
   UInteger results are undefined for values which are less than 0 or 
   larger than 4 294 967 296.

   The name can be explained as 'Convert to Unsigned INTeger'.

   If the argument is a string expression, it is converted to numeric by 
   using ValUInt or ValULng, depending on the size of the result type.

Example
   ' Using the CUINT function to convert a numeric value

   'Create an UNSIGNED INTEGER variable
   Dim numeric_value As UInteger

   'Convert a numeric value
   numeric_value = CUInt(300.23)

   'Print the result = 300
   Print numeric_value

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Cuint.

Differences from QB
   * New to FreeBASIC

See also
   * CByte
   * CUByte
   * CShort
   * CUShort
   * CInt
   * CLng
   * CULng
   * CLngInt
   * CULngInt
   * CSng
   * CDbl
   * UInteger



------------------------------------------------------------ KeyPgCulng ----
CULng

Converts numeric or string expression to ULong

Syntax
   Declare Function CULng ( ByVal expression As datatype ) As ULong

   Type typename
      Declare Operator Cast ( ) As ULong
   End Type

Usage
   result = CULng( numeric expression )
   result = CULng( string expression )
   result = CULng( user defined type )

Parameters
   expression
      a numeric, string, or pointer expression to cast to a ULong value
   datatype
      any numeric, string, or pointer data type
   typename
      a user defined type

Return Value
   A ULong value.

Description
   The CULng function rounds off the decimal part and returns a 32 bit ULong
   value. The function does not check for an overflow. The name can be 
   explained as 'Convert to Unsigned LoNG'.

   If the argument is a string expression, it is converted to numeric by 
   using ValUInt or ValULng.

Example
   ' Using the CULNG function to convert a numeric value

   'Create an UNSIGNED LONG variable
   Dim numeric_value As ULong

   'Convert a numeric value
   numeric_value = CULng(300.23)

   'Print the result = 300
   Print numeric_value
   Sleep

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Culng.

Differences from QB
   * New to FreeBASIC

See also
   * CByte
   * CUByte
   * CShort
   * CUShort
   * CInt
   * CUInt
   * CLng
   * CLngInt
   * CULngInt
   * CSng
   * CDbl



--------------------------------------------------------- KeyPgCulngint ----
CULngInt

Converts numeric or string expression to 64-bit unsigned integer (ULongInt)

Syntax
   Declare Function CULngInt ( ByVal expression As datatype ) As ULongInt

   Type typename
      Declare Operator Cast ( ) As ULongInt
   End Type

Usage
   result = CULngInt( numeric expression )
   result = CULngInt( string expression )
   result = CULngInt( user defined type )

Parameters
   expression
      a numeric, string, or pointer expression to cast to a ULongInt value
   datatype
      any numeric, string, or pointer data type
   typename
      a user defined type

Return Value
   A ULongInt value.

Description
   The CULngInt function rounds off the decimal part and returns a 64-bit 
   ULongInt value.  The function does not check for an overflow, and 
   results are undefined for values which are less than 0 or larger than 18 
   446 744 073 709 551 615.  Additionally, casts from floating-point 
   expressions are currently not guaranteed to work for values higher than 
   2^63 (9 223 372 036 854 775 808).

   The name can be explained as 'Convert to Unsigned LoNG INTeger'.

   If the argument is a string expression, it is converted to numeric by 
   using ValULng.

Example
   ' Using the CLNGINT function to convert a numeric value

   'Create an UNSIGNED LONG INTEGER variable
   Dim numeric_value As ULongInt

   'Convert a numeric value
   numeric_value = CULngInt(12345678.123)

   'Print the result, should return 12345678
   Print numeric_value
   Sleep

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Culngint.

Differences from QB
   * New to FreeBASIC

See also
   * CByte
   * CUByte
   * CShort
   * CUShort
   * CInt
   * CUInt
   * CLng
   * CULng
   * CLngInt
   * CSng
   * CDbl



------------------------------------------------------------ KeyPgCunsg ----
CUnsg

Converts an expression to unsigned

Syntax
   CUnsg ( expression )

Usage
   variable = CUnsg ( expression )

   Converts a signed expression to an unsigned one, useful to force 
   unsigned behavior of division or multiplication (including with Shl and 
   Shr).

   This is the opposite of CSign.

Example
   Dim value As Short = -1
   Print CUnsg(value)  '' will print 65535

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Cunsg.

Differences from QB
   * New to FreeBASIC

See also
   * CSign



----------------------------------------------------------- KeyPgCurdir ----
CurDir

Returns the current directory/folder

Syntax
   Declare Function CurDir ( ) As String

Usage
   result = CurDir

Return Value
   A String which is set to the name of the current directory/folder.

Description
   Returns the current directory/folder.

Example
   Print CurDir

   output will vary.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Curdir.

Differences from QB
   * New to FreeBASIC

See also
   * Open
   * Dir
   * ChDir
   * MkDir
   * RmDir



---------------------------------------------------------- KeyPgCushort ----
CUShort

Converts numeric or string expression to an unsigned integer (UShort)

Syntax
   Declare Function CUShort ( ByVal expression As datatype ) As UShort

   Type typename
      Declare Operator Cast ( ) As UShort
   End Type

Usage
   result = CUShort( numeric expression )
   result = CUShort( string expression )
   result = CUShort( user defined type )

Parameters
   expression
      a numeric, string, or pointer expression to cast to a UShort value
   datatype
      any numeric, string, or pointer data type
   typename
      a user defined type

Return Value
   A UShort value.

Description
   The CUShort function rounds off the decimal part and returns a 16-bit 
   UShort value.  The function does not check for an overflow, and results 
   are undefined for values which are less than 0 or larger than 65 535.

   The name can be explained as 'Convert to Unsigned Short'.

   If the argument is a string expression, it is converted to numeric by 
   using ValUInt.

Example
   ' Using the CUSHORT function to convert a numeric value

   'Create an USHORT variable
   Dim numeric_value As UShort

   'Convert a numeric value
   numeric_value = CUShort(36000.4)

   'Print the result, should return 36000
   Print numeric_value
   Sleep

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Cushort.

Differences from QB
   * New to FreeBASIC

See also
   * CByte
   * CUByte
   * CShort
   * CInt
   * CUInt
   * CLng
   * CULng
   * CLngInt
   * CULngInt
   * CSng
   * CDbl



-------------------------------------------------------- KeyPgCustomgfx ----
Custom

Parameter to the Put graphics statement which selects a custom method

Syntax
   Put [ target, ] [ STEP ] ( x,y ), source [ ,( x1,y1 )-( x2,y2 ) ], 
   Custom, custom_function_ptr [, parameter]

Parameters
   Custom
      Required.
   custom_function_ptr
      name of the custom user defined function.
   parameter
      optional Pointer to be passed to the custom function; if omitted, the 
      default value is zero (0).

Description
   Custom selects a custom user defined function as the method for blitting 
   an image buffer.

   The Custom method uses a user-defined function to calculate the final 
   pixel values to be drawn to the destination buffer. This function will 
   be called once for every pixel of the source image, and will receive the 
   source and destination pixel values, and a data pointer passed by the Put
   function. The pixel value returned will be the value used to draw to the 
   destination buffer. The function has the form:

   Declare Function identifier ( _
      ByVal source_pixel As UInteger, _
      ByVal destination_pixel As UInteger, _
      ByVal parameter As Any Ptr _
      ) As UInteger

   identifier is the name of the function.
   source_pixel is the current pixel value of the source image.
   destination_pixel is the current pixel value of the destination image.
   parameter is the parameter that is passed by the Put command.  If it was 
   omitted, its value will be zero.

Example
   Function dither ( ByVal source_pixel As UInteger, ByVal destination_pixel As UInteger, ByVal parameter As Any Ptr ) As UInteger
      
      ''either returns the source pixel or the destination pixel, depending on the outcome of rnd
      
      Dim threshold As Single = 0.5
      If parameter <> 0 Then threshold = *CPtr(Single Ptr, parameter)
      
      If Rnd() < threshold Then
         Return source_pixel
      Else
         Return destination_pixel
      End If
      
   End Function

   Dim img As Any Ptr, threshold As Single

   '' set up a screen
   ScreenRes 320, 200, 16, 2
   ScreenSet 0, 1

   '' create an image
   img = ImageCreate(32, 32)
   Line img, ( 0,  0)-(15,  15), RGB(255,   0,   0), bf
   Line img, (16,  0)-(31,  15), RGB(  0,   0, 255), bf
   Line img, ( 0, 16)-(15,  31), RGB(  0, 255,   0), bf
   Line img, (16, 16)-(31,  31), RGB(255,   0, 255), bf

   '' dither the image with varying thresholds
   Do Until Len(Inkey)
      
      Cls
      
      threshold = 0.2
      Put ( 80 - 16, 100 - 16), img, Custom, @dither, @threshold
      
      '' default threshold = 0.5
      Put (160 - 16, 100 - 16), img, Custom, @dither
      
      threshold = 0.8
      Put (240 - 16, 100 - 16), img, Custom, @dither, @threshold
      
      ScreenCopy
      Sleep 25
      
   Loop

   '' free the image memory
   ImageDestroy img

Dialect Differences
   * Not available in the -lang qb dialect.

Differences from QB
   * New to FreeBASIC

See also
   * Put (Graphics)



----------------------------------------------------------- KeyPgCvaArg ----
Cva_Arg

Macro to obtain the next argument from a variadic argument list object.

Syntax
   variable = Cva_Arg ( argument_list, datatype )

Parameters
   argument_list
      Cva_List data type variable to access for next value
   datatype
      The datatype of the next value in the variable argument list 
      argument_list

Description
   The Cva_Arg macro allows the use of a variable number of arguments 
   within a function:
      * 	Cva_Arg returns the current argument in the list, argument_list, 
        with an expected data type of datatype.
      * 	Before first Cva_Arg use, argument_list must be initialized with 
        the command Cva_Start or Cva_Copy.
      * 	Cva_Arg automatically increments argument_list to the next 
        argument within the list after obtaining the value of the current 
        argument.

Example
   '' Example of a simple custom printf
   Sub myprintf cdecl(ByRef formatstring As String, ...)
      Dim As Cva_List args

      '' Initialize the cva_list object to first var-arg
      Cva_Start( args, formatstring )

      '' For each char in format string...
      Dim As UByte Ptr p = StrPtr(formatstring)
      Dim As Integer todo = Len(formatstring)
      While (todo > 0)
         Dim As Integer char = *p
         p += 1
         todo -= 1

         '' Is it a format char?
         If (char = Asc("%")) Then
            If (todo = 0) Then
               '' % at the end
               Print "%";
               Exit While
            End If

            '' The next char should tell the type
            char = *p
            p += 1
            todo -= 1

            '' Print var-arg, depending on the type
            Select Case char
            '' integer?
            Case Asc("i")
               Print Str(Cva_Arg(args, Integer));

            '' long integer? (64-bit)
            Case Asc("l")
               Print Str(Cva_Arg(args, LongInt));

            '' single or double?
            '' Note: because the C ABI, all singles passed on
            '' var-args are converted to doubles.
            Case Asc( "f" ), Asc( "d" )
               Print Str(Cva_Arg(args, Double));

            '' string?
            Case Asc("s")
               '' Strings are passed byval, so the length is unknown
               Print *Cva_Arg(args, ZString Ptr);

            End Select

         '' Ordinary char, just print as-is
         Else
            Print Chr( char );
         End If
      Wend

      Cva_End( args )

   End Sub

   Dim As String s = "bar"

   myprintf(!"integer=%i, longint=%l single=%f, double=%d, string=%s, string=%s\n", _
          1, 1ll Shl 32, 2.2, 3.3, "foo", s)

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __cva_arg.

Differences from QB
   * New to FreeBASIC

See also
   * ... (Ellipsis)
   * Cva_Copy
   * Cva_End
   * Cva_List
   * Cva_Start



---------------------------------------------------------- KeyPgCvaCopy ----
Cva_Copy

Macro to initialize variadic argument list object variable from an already 
initialized variadic argument list object variable

Syntax
   Cva_Copy( dst_list, src_list )

Parameters
   dst_list
      destination Cva_List variable to initialize
   src_list
      source Cva_List variable to copy from

Description
   Copies one Cva_List type variable to another Cva_List type variable.  
   dst_list is initialized using current state of src_list

   src_list must already have been initialized with a previous Cva_Start or 
   Cva_Copy statement.

   Cva_Copy is like a copy constructor for the a variadic argument list 
   object and must eventually have a matching call to Cva_End, which is 
   like the destructor.  After Cva_End for dst_list has been called, 
   dst_list can be reused and reinitialized with another call to Cva_Start 
   or Cva_Copy.  The Cva_Copy and Cva_End calls must both be called in the 
   same procedure (for cross platform compatibility).

Example
   '' example of using cva_copy to create
   '' a copy of the variable argument list

   Sub proc cdecl(count As Integer, ... )
      Dim args1 As Cva_List
      Dim args2 As Cva_List

      '' first list
      Cva_Start( args1, count )

      '' create a copy
      Cva_Copy( args2, args1 )

      For i As Integer = 1 To count
         Print Cva_Arg( args1, Integer ), Cva_Arg( args2, Integer )
      Next
      
      '' clean-up
      Cva_End( args2 )
      Cva_End( args1 )

   End Sub

   proc( 4, 4000, 300, 20, 1 )

   '' example of using cva_copy to create
   '' a copy of the variable argument list
   '' and pass it to another procedure

   Sub vproc cdecl(count As Integer, ByRef args As Cva_List )

      '' if we don't know that caller made a copy
      '' of args, it is safe to make our own copy
      '' and leave the passed in args untouched

      Dim a As Cva_List
      Cva_Copy( a, args )

      Print "vproc"
      For i As Integer = 1 To count
         Print Cva_Arg( a, Integer )
      Next
      
      '' clean-up
      Cva_End( a )

   End Sub

   Sub proc cdecl(count As Integer, ... )

      Dim args As Cva_List
      Cva_Start( args, count )

      '' if don't know that the called procedure
      '' will make it's own copy, it is safe to
      '' make a copy here and pass that instead

      Dim tmp As Cva_List
      Cva_Copy( tmp, args )
      vproc( count, tmp )
      Cva_End( tmp )

      '' args is still valid, we can use it
      Print "proc"
      For i As Integer = 1 To count
         Print Cva_Arg( args, Integer )
      Next
      
      '' clean-up
      Cva_End( args )

   End Sub

   proc( 4, 4000, 300, 20, 1 )

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __cva_copy.

Differences from QB
   * New to FreeBASIC

See also
   * ... (Ellipsis)
   * Cva_Arg
   * Cva_End
   * Cva_List
   * Cva_Start



----------------------------------------------------------- KeyPgCvaEnd ----
Cva_End

Macro to clean-up a variadic argument list object variable

Syntax
   Cva_End( argument_list )

Parameters
   argument_list
      Cva_List variable to clean up

Description
   Cleans-up a Cva_List type variable that was previously initialized with 
   Cva_Start or Cva_Copy, like a destructor.

   argument_list must already have been initialized with a previous 
   Cva_Start or Cva_Copy statement in the same procedure as Cva_End (for 
   cross platform compatibility).

Example
   Sub proc cdecl(count As Integer, ... )
      Dim args As Cva_List

      Cva_Start( args, count )

      For i As Integer = 1 To count
         Print Cva_Arg( args, Integer )
      Next
      
      Cva_End( args )
   End Sub

   proc( 4, 4000, 300, 20, 1 )

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __cva_end.

Differences from QB
   * New to FreeBASIC

See also
   * ... (Ellipsis)
   * Cva_Arg
   * Cva_Copy
   * Cva_List
   * Cva_Start



---------------------------------------------------------- KeyPgCvaList ----
Cva_List

Variadic argument list object type

Syntax
   Dim variable As Cva_List

Description
   Cva_List is a built in data type for working with the variable length 
   argument list in a variadic procedure.

   Use Cva_Start to initialize the Cva_List variable (constructor).
   Use Cva_Copy to copy a Cva_List variable (copy constructor).
   Use Cva_Arg to obtain the value of the next argument.
   Use Cva_End when finished with a Cva_List variable (destructor).

   The exact type and size of Cva_List varies depending on the target 
   platform.  This builtin type provides a layer of abstraction over the 
   underlying mechanism for obtaining the values passed to a variadic 
   procedure.

   fbc will select a default Cva_List type depending on -target, -arch, and 
   -gen command line options, as described in the following code.
   #if (__FB_BACKEND__ = "gcc")
      #if defined( __FB_64BIT__ ) 
         #if defined( __FB_ARM__ )
            Type __va_list Alias "__va_list"
               As Any Ptr __stack
               As Any Ptr __gr_top
               As Any Ptr __vr_top
               As Long __gr_offs
               As Long __vr_offs
            End Type
            Type Cva_List As __va_list Alias "__builtin_va_list"
         #elseif defined( __FB_WIN32__ )
            Type Cva_List As Any Alias "__builtin_va_list" Ptr
         #else
            Type __va_list_tag Alias "__va_list_tag"
               As ULong gp_offset
               As ULong fp_offset
               As Any Ptr overflow_arg_area
               As Any Ptr reg_save_area
            End Type  
            Type Cva_List As __va_list_tag Alias "__builtin_va_list[]"
         #endif   
      #else
         Type Cva_List As Any Alias "__builtin_va_list" Ptr
      #endif
   #else
      Type Cva_List As Any Alias "char" Ptr
   #endif

Example
   Function average cdecl(count As Integer, ... ) As Double

      Dim sum As Double = 0
      Dim i As Integer

      Dim args As Cva_List '' argument list object
      Cva_Start( args, count ) '' constructor
      For i = 1 To count
         sum += Cva_Arg(args, Double)
      Next
      Cva_End( args ) '' destructor
      
      Return sum / count
   End Function

   Print average(4, 3.4 ,5.0, 3.2, 4.1) '' all passed variable arguments must be of type double
   Print average(2, 65.2, 454.65481)    '' all passed variable arguments must be of type double

The output would look like:

    3.925
    259.927405

   '' pass the args list to a function taking an cva_list type argument
   #include "crt/stdio.bi"

   Sub myprintf cdecl( fmt As ZString Ptr, ... )
      Dim args As Cva_List
      Cva_Start( args, fmt )
      vprintf( fmt, args )
      Cva_End( args )
   End Sub

   Dim As String s = "bar"

   myprintf( !"integer=%i, longint=%lli float=%f\n", _
      1, 1ll Shl 32, 3.3 )

   myprintf( !"string=%s, string=%s\n", "foo", s )

Platform Differences
   * The exact type and size of Cva_List depends on -target, -arch, -gen 
     command line options.
   * In -gen gas, Cva_List is a pointer
   * In -gen gcc, Cva_List is a pointer, a struct, or a struct array.  The 
     Cva_List type is replaced by "__builtin_va_list" in gcc.
   * On 32-bit targets, gas backend: type Cva_List as any alias "char" ptr
     .
   * On 32-bit targets, gcc backend: type Cva_List as any alias 
     "__builtin_va_list" ptr
   * On Windows 64-bit, gcc backend: type Cva_List as any alias 
     "__builtin_va_list" ptr
   * On Linux x86_64, gcc backend: type Cva_List as "__va_list_tag" alias 
     "__builtin_va_list[]"
   * On arm64, gcc backend: type Cva_List as __va_list alias 
     "__builtin_va_list"

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __cva_list.

Differences from QB
   * New to FreeBASIC

See also
   * ... (Ellipsis)
   * Cva_Arg
   * Cva_Start
   * Cva_Copy
   * Cva_End



--------------------------------------------------------- KeyPgCvaStart ----
Cva_Start

Macro to initialize variadic argument list object variable

Syntax
   Cva_Start( argument_list, last_param )

Parameters
   argument_list
      Cva_List data type variable to initialize
   last_param
      The last parameter in the procedures parameter list before the 
      Ellipsis ...

Description
   In a variadic procedure definition, argument_list is a variable having 
   the Cva_List type and must be initialized with Cva_Start to work with 
   the variable length argument list passed to the procedure.

   last_param is the last parameter before the Ellipsis ... in the variadic 
   procedure definition.

   Cva_Start can only be used in variadic procedures.  A variadic procedure 
   is declared or defined by specifying the Ellipsis ... as the last 
   parameter, and will accept a variable number of arguments when calling 
   the procedure.

   Cva_Start is like a constructor for the variadic argument_list object 
   and must eventually have a matching call to Cva_End, which is like a 
   destructor.  After Cva_End for argument_list has been called, 
   argument_list can be reused and reinitialized with another call to 
   Cva_Start.  The Cva_Start and Cva_End calls must both be called in pairs 
   in the same procedure (for cross platform compatibility).

   Cva_Copy is similar to Cva_Start except it initializes a variadic 
   argument_list object from an already initialized variadic argument_list 
   object, like a copy constructor.

Example
   '' typical usage of iterating through all arguments

   Sub proc cdecl(count As Integer, ... )
      Dim args As Cva_List
      Cva_Start( args, count )
      For i As Integer = 1 To count
         Print Cva_Arg( args, Integer )
      Next
      Cva_End( args )
   End Sub

   proc( 4, 4000, 300, 20, 1 )

   '' example of using cva_start to get the first argument
   '' then restarting to get all the arguments

   Sub proc cdecl(count As Integer, ... )
      Dim args As Cva_List

      '' get the first argument only
      Cva_Start( args, count )
      Print Cva_Arg( args, Integer )
      Cva_End( args )

      '' restart and get all the arguments
      Cva_Start( args, count )
      For i As Integer = 1 To count
         Print Cva_Arg( args, Integer )
      Next
      Cva_End( args )

   End Sub

   proc( 4, 4000, 300, 20, 1 )

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __cva_start.

Differences from QB
   * New to FreeBASIC

See also
   * ... (Ellipsis)
   * Cva_Arg
   * Cva_Copy
   * Cva_End
   * Cva_List



-------------------------------------------------------------- KeyPgCvd ----
CVD

Converts a 64-bit integer or 8-byte string to a double-precision value

Syntax
   Declare Function CVD ( ByVal l As LongInt ) As Double
   Declare Function CVD ( ByRef str As Const String ) As Double

Usage
   result = CVD( l )
   result = CVD( str )

Parameters
   l
      A 64-bit LongInt with a binary copy of a double-precision variable 
      stored in it.
   str
      A String at least 8 bytes in length with a binary copy of a 
      double-precision variable stored in it.

Return Value
      Returns a Double value holding a binary copy of the input value.

Description
   Does a binary copy from a 64-bit LongInt or 8-byte String to a Double 
   variable.  A value of zero (0.0) is returned if the string is less than 
   8 bytes in length.  The result will make sense only if the parameter 
   contained a IEEE-754 formatted double-precision value, such as one 
   generated by CVLongInt or MKD.

   This function is useful to read numeric values from buffers without 
   using a Type definition.

Example
   Dim d As Double, l As LongInt
   d = 1.125
   l = CVLongInt(d)

   Print Using "l = _&H&"; Hex(l)
   Print Using "cvd(i) = &"; CVD(l)

Differences from QB
   * QB did not support integer arguments.

See also
   * MKD
   * CVS
   * CVLongInt



-------------------------------------------------------------- KeyPgCvi ----
CVI

Converts a floating-point number or string to an integer variable using a 
binary copy

Syntax
   32-bit:
   Declare Function CVI ( ByVal f As Single ) As Integer
   64-bit:
   Declare Function CVI ( ByVal f As Double ) As Integer

   Declare Function CVI ( ByRef str As Const String ) As Integer
   Declare Function CVI<bits> ( expr As DataType ) As Integer<bits>

Usage
   result = CVI( sng )
   result = CVI( str )
   result = CVI<bits>( expr )

Parameters
   f
      A floating-point number with a binary copy of an integer variable 
      stored in it.  Its precision (Single or Double) depends on the size 
      of Integer on the current platform
   str
      A String with a binary copy of an integer variable stored in it.
   bits
      Specifies a size of integer type to return.  The types and sizes of 
      expr accepted will depend on the corresponding function called.
   expr
      An expression that will be copied into an Integer<bits>.

Return Value
   An Integer or Integer<bits> variable containing a binary copy of the 
   input expression.

Description
   Returns an integer value using the binary data contained in a 
   floating-point value, or a String.  A value of zero (0) is returned if 
   the string contains fewer characters than the size of the return type.

   CVI can be used to convert strings created with MKI.

   This function can also be used to convert Integer-sized values from a 
   memory or file buffer without the need for a Type structure.  However, 
   just as with the type structure, special care should be taken when using 
   CVI to convert strings that have been read from a buffer.

   CVI supports an optional <bits> parameter before the argument.  If bits 
   is 16, CVShort will be called instead; if bits is 32, CVL will be 
   called; if bits is 64, CVLongInt will be called.  The return type and 
   accepted argument types will depend on which function is called.  See 
   each function's page for more information.

   CVI's behaviour changes depending on the size of the Integer data type 
   on the current platform.
   * For 16-bit Integer (-lang qb), a 16-bit value is returned, and no 
     floating-point types are accepted.
   * For 32-bit Integer, a 32-bit value is returned, and numeric arguments 
     are interpreted as Single precision values.
   * For 64-bit Integer, a 64-bit value is returned, and numeric arguments 
     are interpreted as Double precision values.

Example
   Dim i As Integer, s As String
   s = "ABCD"
   i = CVI(s)
   Print Using "s = ""&"""; s
   Print Using "i = _&H&"; Hex(i)

Dialect Differences
   * In the -lang qb dialect, CVI expects a 2-byte string, since a QB 
     integer is only 16 bits.  Only the first two bytes of the string are 
     used, even if the string happens to be longer than two bytes.
   * In the -lang qb dialect, CVI will not take a floating-point argument, 
     since a QB integer is only 16 bits and there is no 16-bit 
     floating-point data type.  Instead, CVI<32>/CVI<64> or CVL/CVLongInt 
     may be used.

Differences from QB
   * In QB an error occurs if the string passed is fewer than two bytes in 
     length.
   * QB did not support floating-point arguments.
   * QB did not support a <bits> parameter.

See also
   * MKI
   * CVShort
   * CVL
   * CVLongInt
   * Integer



-------------------------------------------------------------- KeyPgCvl ----
CVL

Converts a single-precision floating-point number or four-byte string to an 
integer (Long) variable

Syntax
   Declare Function CVL ( ByVal sng As Single ) As Long
   Declare Function CVL ( ByRef str As Const String ) As Long

Usage
   result = CVL( sng )
   result = CVL( str )

Parameters
   sng
      A Single floating-point number with a binary copy of an integer 
      variable stored in it.
   str
      A String at least four bytes in length with a binary copy of an 
      integer variable stored in it.

Return Value
      A Long variable to copy the binary copy of a integer to.

Description
   Returns a 32-bit Long integer value using the binary data contained in a 
   Single, or a String of at least four bytes in length.  A value of zero (
   0) is returned if the string is less than four bytes in length.

   CVL is used to convert 4-byte strings created with MKL.

   This function can also be used to convert 32-bit integer values from a 
   memory or file buffer without the need for a Type structure.  However, 
   just as with the type structure, special care should be taken when using 
   CVL to convert strings that have been read from a buffer.

Example
   Dim l As Long, s As String
   s = "ABCD"
   l = CVL(s)
   Print Using "s = ""&"""; s
   Print Using "l = &"; l

Differences from QB
   * In QB an error occurs if the string passed is less than four bytes in 
     length.
   * QB did not support floating-point arguments.

See also
   * MKL
   * CVShort
   * CVI
   * CVLongInt



-------------------------------------------------------- KeyPgCvlongint ----
CVLongInt

Converts a double-precision floating-point number or eight-byte string to a 
LongInt variable

Syntax
   Declare Function CVLongInt ( ByVal dbl As Double ) As LongInt
   Declare Function CVLongInt ( ByRef str As Const String ) As LongInt

Usage
   result = CVLongInt( dbl )
   result = CVLongInt( str )

Parameters
   dbl
      A Double floating-point number with a binary copy of a LongInt 
      variable stored in it.
   str
      A String at least eight bytes in length with a binary copy of a 
      LongInt variable stored in it.

Return Value
      A LongInt variable holding a binary copy of the input variable.

Description
   Returns a 64-bit LongInt value using the binary data contained in a 
   Double, or a String of at least eight bytes in length.  A value of zero 
   (0) is returned if the string is less than eight bytes in length.

   CVLongInt is used to convert 8-byte strings created with MKLongInt.

   This function can also be used to convert 64-bit integer values from a 
   memory or file buffer without the need for a Type structure.  However, 
   just as with the type structure, special care should be taken when using 
   CVLongInt to convert strings that have been read from a buffer.

Example
   Dim ll As LongInt, s As String
   s = "ABCDEFGH"
   ll = CVLongInt(s)
   Print Using "s = ""&"""; s
   Print Using "ll = _&H&"; Hex(ll)

Differences from QB
   * In QB an error occurs if the string passed is less than eight bytes 
     in length.
   * QB did not support floating-point arguments.

See also
   * MKLongInt
   * CVShort
   * CVI
   * CVL



-------------------------------------------------------------- KeyPgCvs ----
CVS

Converts a 32-bit integer or 4-byte string to a single-precision variable

Syntax
   Declare Function CVS ( ByVal i As Integer ) As Single
   Declare Function CVS ( ByRef str As Const String ) As Single

Usage
   result = CVS( i )
   result = CVS( str )

Parameters
   i
      A 32-bit Integer with a binary copy of a single-precision variable 
      stored in it.
   str
      A String at least 4 bytes in length with a binary copy of a 
      single-precision variable stored in it.

Return Value
      Returns a Single value holding a binary copy of the input value.

Description
   Does a binary copy from a 32-bit Integer or 4-byte String to a Single 
   variable.  A value of zero (0.0) is returned if the string is less than 
   4 bytes in length.  The result will make sense only if the parameter 
   contained a IEEE-754 formatted single-precision value, such as one 
   generated by CVI or MKS.

   This function is useful to read numeric values from buffers without 
   using a Type definition.

Example
   Dim f As Single, i As Integer
   f = 1.125
   i = CVI(f)

   Print Using "i = _&H&"; Hex(i)
   Print Using "cvs(i) = &"; CVS(i)

Differences from QB
   * QB did not support integer arguments.

See also
   * MKS
   * CVD
   * CVI



---------------------------------------------------------- KeyPgCvshort ----
CVShort

Converts a two-byte string to a Short integer variable

Syntax
   Declare Function CVShort ( ByRef str As Const String ) As Short

Usage
   result = CVShort( str )

Parameters
   str
      A String at least two bytes in length with a binary copy of a Short 
      integer variable stored in it.

Return Value
    Short variable holding the binary copy of a Keypgshort.

Description
   Returns a 16-bit Short integer value using the binary data contained in 
   a String of at least two bytes in length.  A value of zero (0) is 
   returned if the string is less than two bytes in length.

   CVShort is used to convert 2-byte strings created with MKShort.

   This function can also be used to convert 16-bit integer values from a 
   memory or file buffer without the need for a Type structure.  However, 
   just as with the type structure, special care should be taken when using 
   CVShort to convert strings that have been read from a buffer.

Example
   Dim si As Short, s As String
   s = "AB"
   si = CVShort(s)
   Print Using "s = ""&"""; s
   Print Using "si = _&H&"; Hex(si)

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Cvshort.

Differences from QB
   * In QB this function is called CVI

See also
   * MKShort
   * CVI
   * CVL
   * CVLongInt




============================================================================
    D

------------------------------------------------------------- KeyPgData ----
Data

Statement to store data at compile time.

Syntax
   Data constant_expression1 [,constant_expression2]...

Description
   Data stores a list of constant numeric or alphabetical expressions that 
   are evaluated at compile time (except with -lang qb) and stored as 
   constants that can be read into variables by using Read.

   All the Data statements in the program behave as a single chained list; 
   after the last element of one Data statement is read, the first element 
   of the following Data statement will be read.
   The program should not attempt to Read after the last Data element.  The 
   results are (in all dialects) undefined,  and the program may crash 
   (Page Fault).

   Data statements are only visible from within the module in which they 
   are defined; they must be only entered in module-level code.

   Data constants can only be of simple types (numeric or string).  A 
   numeric value can be read as a numeric literal into a string. A string 
   read into a numeric variable will be evaluated by the Val function.  
   Consts can be used as items of data except in the -lang qb dialect, 
   where their names are considered as normal text.

   The "Restore label" statement makes the first Data item after the label 
   the next item to be read, allowing the user to choose specific sections 
   of data to read.

   Data is normally used to initialize variables. FreeBASIC also allows the 
   initialization of static variables when they are Dimensioned - see 
   Variable Initializers for more information.

Example
   ' Create an array of 5 integers and a string to hold the data.
   Dim As Integer h(4)
   Dim As String hs
   Dim As Integer readindex

   ' Set up to loop 5 times (for 5 numbers... check the data)
   For readindex = 0 To 4

     ' Read in an integer.
     Read h(readindex)

     ' Display it.
     Print "Number" ; readindex ; " = " ; h(readindex)

   Next readindex

   ' Spacer.
   Print

   ' Read in a string.
   Read hs

   ' Print it.
   Print  "String = " + hs

   ' Await a keypress.
   Sleep

   ' Exit program.
   End

   ' Block of data.
   Data 3, 234, 435/4, 23+433, 87643, "Good" + "Bye!"

Dialect Differences
   * -lang fb and -lang fblite considers data items as constant 
     expressions that are evaluated during compilation and its result 
     stored in the program.
   * -lang qb considers unquoted words, including names of variables and 
     constants, as literal strings, and stores them without change, as in 
     QBASIC.  Unquoted strings are delimited by commas, and a colon or a 
     line-break signifies the end of the Data statement.  Unquoted strings 
     are trimmed of whitespace at the beginning and end.

Differences from QB
   * Outside of the -lang qb dialect, alphabetic string literals must be 
     enclosed within quotation marks, in QBASIC this was optional.
   * In QBASIC empty items evaluated to number 0 or to empty strings, in 
     FreeBASIC they give a compile error. In QBASIC a comma at the end of 
     the statement made an additional, empty item, evaluated to 0 or an 
     empty string. In FreeBASIC they give a compile error.

See also
   * Read
   * Restore



------------------------------------------------------------- KeyPgDate ----
Date

Returns the current system date as a string

Syntax
   Declare Function Date ( ) As String

Usage
   result = Date

Return Value
   Returns the current system date, in the format mm-dd-yyyy

Description
   None

Example
   Print Date ' prints the current date

Differences from QB
   * The QB DATE statement (to set the system date) is now called SetDate.

See also
   * SetDate
   * Time
   * Timer



---------------------------------------------------------- KeyPgDateAdd ----
DateAdd

Offset a date with a specified interval

Syntax
   Declare Function DateAdd ( ByRef interval As Const String, ByVal number 
   As Double, ByVal date_serial As Double ) As Double

Usage
   #include "vbcompat.bi"
   result = DateAdd( interval, number, date_serial )

Parameters
   interval
      string indicating which period of time corresponds to one unit of 
      number
   number
      the number of intervals to add to the base date.  The number will be 
      rounded to the nearest integer.
   date_serial
      the base date

Return Value
   Returns a Date Serial corresponding to the received date_serial plus the 
   number of intervals.

Description
   Interval is specified as follows:

      +-----+---------------------+
      |value|interval             |
      |yyyy |years                |
      |q    |quarter(three months)|
      |m    |months               |
      |ww   |weeks                |
      |d,w,y|days                 |
      |h    |hours                |
      |n    |minutes              |
      |s    |seconds              |
      +-----+---------------------+
  

   The compiler will not recognize this function unless vbcompat.bi or 
   datetime.bi is included.

Example
   #include "vbcompat.bi"

   Const fmt = "ddddd ttttt"
   Dim d As Double
   d = Now()

   Print "1 hour from now is ";
   Print Format( DateAdd( "h", 1, d ), fmt )

   Print "1 day from now is ";
   Print Format( DateAdd( "d", 1, d ), fmt )

   Print "1 week from now is ";
   Print Format( DateAdd( "ww", 1, d ), fmt )

   Print "1 month from now is ";
   Print Format( DateAdd( "m", 1, d ), fmt )

Differences from QB
   * Did not exist in QB. This function appeared in Visual Basic.

See also
   * Date Serials

   


--------------------------------------------------------- KeyPgDateDiff ----
DateDiff

Gets the difference of two dates measured by a specified interval

Syntax
   Declare Function DateDiff ( ByRef interval As Const String, ByVal 
   serial1 As Double, ByVal serial2 As Double, ByVal firstdayofweek As Long 
   = fbUseSystem, ByVal firstdayofyear As Long = fbUseSystem ) As Long

Usage
   #include "vbcompat.bi"
   result = DateDiff( interval, date_serial1, date_serial2 [, 
   firstdayofWeek [, firstweekofyear ] ] )

Parameters
   interval
      the unit of time (interval) with which to measure the difference
   date_serial1
      starting date serial
   date_serial2
      end date serial
   firstdayofweek
      first day of the week
   firstdayofyear
      first day of the year

Return Value
   Returns an integer corresponding to the number of intervals found 
   between two Date Serials.

   If date_serial1 > date_serial2, the result is negative.

Description
   interval is specified as follows:

         +-----+---------------------+
         |value|interval             |
         |yyyy |years                |
         |q    |quarter(three months)|
         |m    |months               |
         |w    | seven day periods   |
         | ww  |calendar weeks       |
         |d,y  |days                 |
         |h    |hours                |
         |n    |minutes              |
         |s    |seconds              |
         +-----+---------------------+
  

   first_dayofweek Affects the counting when 'ww' interval is used.

         +-------+-----------------+-----------+
         |value  |first day of week|constant   |
         |omitted|sunday           |           |
         |0      |local settings   |fbUseSystem|
         |1      |sunday           |fbSunday   |
         |2      |monday           |fbMonday   |
         |3      |tuesday          |fbTuesday  |
         |4      |wednesday        |fbWednesday|
         |5      |thursday         |fbThursday |
         |6      |friday           |fbFriday   |
         |7      |saturday         |fbSaturday |
         +-------+-----------------+-----------+

   first_weekofyear specifies which year (previous or next) that the week 
   which spans the end of one year and the beginning of the next should 
   included with.

         +-----+-------------------------------------+---------------+
         |value|first week of year                   |constant       |
         |0    |local settings                       |fbUseSystem    |
         |1    |January 1's week                     |fbFirstJan1    |
         |2    |first weeks having 4 days in the year|fbFirstFourDays|
         |3    |first full week of year              |fbFirstFullWeek|
         +-----+-------------------------------------+---------------+

   Notice if you do an arithmetical subtraction of two date serials you get 
   the difference in days.

   The compiler will not recognize this function unless vbcompat.bi or 
   datetime.bi is included.

Example
   #include "vbcompat.bi"

   Dim s As String, d1 As Double, d2 As Double

   Line Input "Enter your birthday: ", s

   If IsDate( s ) Then
     d1 = DateValue( s )
     d2 = Now()

     Print "You are " & DateDiff( "yyyy", d1, d2 ) & " years old."
     Print "You are " & DateDiff( "d", d1, d2 ) & " days old."
     Print "You are " & DateDiff( "s", d1, d2 ) & " seconds old."

   Else
     Print "Invalid date"

   End If

Differences from QB
   * Did not exist in QB. This function appeared in Visual Basic.

See also
   * Date Serials



--------------------------------------------------------- KeyPgDatePart ----
DatePart

Gets an interval from a date

Syntax
   Declare Function DatePart ( ByRef interval As Const String, ByVal 
   date_serial As Double, ByVal firstdayofweek As Long = fbUseSystem, ByVal 
   firstdayofyear As Long = fbUseSystem ) As Long

Usage
   #include "vbcompat.bi"
   result = DatePart( interval, date_serial, first_dayofWeek [, 
   first_week_of_year ] )

Parameters
   interval
      string indicating which part of the date is required
   date_serial
      the date serial to decode 
   firstdayofweek
      first day of the week
   firstdayofyear
      first day of the year

Return Value
   Return an integer representing  the interval in the Date Serial.

Description

   interval string indicating which part of the date is required is 
   specified as follows:

         +-----+---------------------+
         |value|interval             |
         |yyyy |years                |
         |q    |quarter(three months)|
         |m    |months               |
         | w   | weekday             |
         | ww  | week of the year    |
         |y    |day of the year      |
         |d    |day of the month     |
         |h    |hours                |
         |n    |minutes              |
         |s    |seconds              |
         +-----+---------------------+
  

   first_dayofweek Affects the output when 'w' interval is required.

         +-------+-----------------+-----------+
         |value  |first day of week|constant   |
         |omitted|sunday           |           |
         |0      |local settings   |fbUseSystem|
         |1      |sunday           |fbSunday   |
         |2      |monday           |fbMonday   |
         |3      |tuesday          |fbTuesday  |
         |4      |wednesday        |fbWednesday|
         |5      |thursday         |fbThursday |
         |6      |friday           |fbFriday   |
         |7      |saturday         |fbSaturday |
         +-------+-----------------+-----------+

   first_weekofyear  specifies which year (previous or next) that the week 
   which spans the end of one year and the beginning of the next should 
   included with. Affects the output when 'ww' interval is required.

         +-----+-------------------------------------+---------------+
         |value|first week of year                   |constant       |
         |0    |local settings                       |fbUseSystem    |
         |1    |January 1's week                     |fbFirstJan1    |
         |2    |first weeks having 4 days in the year|fbFirstFourDays|
         |3    |first full week of year              |fbFirstFullWeek|
         +-----+-------------------------------------+---------------+

   The compiler will not recognize this function unless vbcompat.bi or 
   datetime.bi is included.

Example
   #include "vbcompat.bi"

   Dim d As Double

   d = Now()

   Print "Today is day " & DatePart( "y", d );
   Print " in week " & DatePart( "ww", d );
   Print " of the year " & DatePart( "yyyy", d )

Differences from QB
   * Did not exist in QB. This function appeared in Visual Basic.

See also
   * Date Serials



------------------------------------------------------- KeyPgDateSerial ----
DateSerial

Creates a date serial

Syntax
   Declare Function DateSerial ( ByVal year As Long, ByVal month As Long, 
   ByVal day As Long ) As Long

Usage
   #include "vbcompat.bi"
   result = DateSerial( year, month, day )

Parameters
   year
      the year
   month
      the month of the year
   day
      the day of the month

Return Value
   Returns a date serial containing the date formed by the values in the 
   year, month and day parameters.The date serial returned has no decimal 
   part.

Description
   The compiler will not recognize this function unless vbcompat.bi or 
   datetime.bi is included.

Example
   #include "vbcompat.bi"

   Dim a As Double = DateSerial(2005, 11, 28)

   Print Format(a, "yyyy/mm/dd hh:mm:ss") 

Differences from QB
   * Did not exist in QB. This function appeared in PDS and VBDOS

See also
   * Date Serials
   * DateSerial
   * TimeValue
   * DateValue



-------------------------------------------------------- KeyPgDateValue ----
DateValue

Returns a Date Serial from a string

Syntax
   Declare Function DateValue ( ByRef date_string As String ) As Double

Usage
   #include "vbcompat.bi"
   result = DateValue( date_string )

Parameters
   date_string
      the string to convert to a date serial

Return Value
   Returns a Date Serial from a date string.

Description
   The date string must be in the format set in the regional settings of 
   the Operating System. 

   DateValue( Date() ) will work correctly only if the regional settings 
   specify the same short date format QB used (mm-dd-yyyy).  Consider using 
   the Now function in the expression Fix(Now()) to obtain the current date 
   as a date serial.

   The compiler will not recognize this function unless vbcompat.bi or 
   datetime.bi is included.

Example
   #include "vbcompat.bi"

   Dim As Integer v1, v2
   Dim As String  s1, s2

   Print "Enter first date: ";
   Line Input s1

   If IsDate( s1 ) = 0 Then
     Print "not a date"
     End
   End If

   Print "Enter second date: ";
   Line Input s2

   If IsDate( s2 ) = 0 Then
     Print "not a date"
     End
   End If

   '' convert the strings to date serials
   v1 = DateValue( s1 )
   v2 = DateValue( s2 )

   Print "Number of days between dates is " & Abs( v2 - v1 )

Differences from QB
   * Did not exist in QB. This function appeared in PDS and VBDOS

See also
   * Date Serials
   * DateSerial
   * TimeValue



-------------------------------------------------------------- KeyPgDay ----
Day

Gets the day of the month from a Date Serial

Syntax
   Declare Function Day ( ByVal date_serial As Double ) As Long

Usage
   #include "vbcompat.bi"
   result = Day( date_serial )

Parameters
   date_serial
      the date

Return Value
   Returns the day of the month from a  variable containing a date in  
   Date Serial  format. 

Description

   The compiler will not recognize this function unless vbcompat.bi is 
   included.

Example
   #include "vbcompat.bi"

   Dim ds As Double = DateSerial(2005, 11, 28)

   Print Format(ds, "yyyy/mm/dd "); Day(ds)

Differences from QB
   * Did not exist in QB. This function appeared in PDS and VBDOS

See also
   * Date Serials



------------------------------------------------------- KeyPgDeallocate ----
Deallocate

Frees previously allocated memory

Syntax
   Declare Sub Deallocate cdecl ( ByVal pointer As Any Ptr )

Usage
   Deallocate( pointer )

Parameters
   pointer
      the address of the previously allocated buffer.

Description
   This procedure frees memory that was previously allocated with Allocate. 
   pointer must be a valid pointer. After the procedure returns, pointer 
   will be rendered invalid (pointing to an invalid memory address), and 
   its use (dereferencing or calling Deallocate again) will result in 
   undefined behavior.

   Calling Deallocate on a null pointer induces no action.

   Deallocate is an alias for the C runtime library's free, so it's not 
   guaranteed to be thread safe in all platforms.

Example
The following example shows how to free previously allocated memory. Note 
that the pointer is set to null following the deallocation:

   Sub DeallocateExample1()
      Dim As Integer Ptr integerPtr = Allocate( Len( Integer ) )  '' initialize pointer to
                                                   '' new memory address

      *integerPtr = 420                                     '' use pointer
      Print *integerPtr

      Deallocate( integerPtr )                              '' free memory back to system
      integerPtr = 0                                        '' and zero the pointer
   End Sub

      DeallocateExample1()
      End 0

Although in this case it is unnecessary since the function immediately 
exits afterwards, setting the pointer to null is a good habit to get into. 
If the function deallocated memory from a pointer that was passed in by 
reference, for instance, the pointer that was used in the function call 
will be rendered invalid, and it is up to the caller to either reassign the 
pointer or set it to null. Example 3 shows how to correctly handle this 
kind of situation, and the next example shows the effects of deallocating 
memory with multiple references.

In the following example, a different pointer is used to free previously 
allocated memory.

   '' WARNING: "evil" example showing how things should NOT be done

   Sub DeallocateExample2()
      Dim As Integer Ptr integerPtr = Allocate( Len( Integer ) )  
      '' initialize ^^^ pointer to new memory

      Dim As Integer Ptr anotherIntegerPtr = integerPtr
      '' initialize ^^^ another pointer to the same memory

      *anotherIntegerPtr = 69                     '' use other pointer
      Print *anotherIntegerPtr

      Deallocate( anotherIntegerPtr )             '' free memory back to system
      anotherIntegerPtr = 0                       '' and zero other pointer

   '' *integerPtr = 420                           '' undefined behavior; original
                                       '' pointer is invalid
   End Sub

      DeallocateExample2()
      End 0

Note that after the deallocation, both pointers are rendered invalid. This 
illustrates another one of the ways that bugs can arise when working with 
pointers. As a general rule, only deallocate memory previously allocated 
when you know that there is only one (1) pointer currently pointing at it.

   Function createInteger() As Integer Ptr
      Return Allocate( Len( Integer ) )                     '' return pointer to newly
   End Function                                             '' allocated memory

   Sub destroyInteger( ByRef someIntegerPtr As Integer Ptr )
      Deallocate( someIntegerPtr )                          '' free memory back to system
      someIntegerPtr = 0                                    '' null original pointer
   End Sub

   Sub DeallocateExample3()
      Dim As Integer Ptr integerPtr = createInteger()       '' initialize pointer to
                                              '' new memory address

      *integerPtr = 420                                     '' use pointer
      Print *integerPtr

      destroyInteger( integerPtr )                          '' pass pointer by reference
      Assert( integerPtr = 0 )                              '' pointer should now be null
   End Sub

      DeallocateExample3()
      End 0

In the program above, a reference pointer in a function is set to null 
after deallocating the memory it points to. An Assert macro is used to test 
if the original pointer is in fact null after the function call. This 
example implies the correct way to pass pointers to functions that 
deallocate the memory they point to is by reference.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Deallocate.

Differences from QB
   * New to FreeBASIC

See also
   * Allocate
   * Reallocate



---------------------------------------------------------- KeyPgDeclare ----
Declare

Declares a module-level or member procedure

Syntax
   Declare Sub name [ param_list ]
   Declare Function name [ param_list ] [ ByRef ] As return_type
   Declare Operator op_symbol param_list [ [ ByRef ] As return_type ]

   Type T
      Declare Constructor [ param_list ]
      Declare Destructor
      Declare Sub name [ param_list ]
      Declare Function name [ param_list ] [ ByRef ] As return_type
      Declare Operator name [ param_list ] [ [ ByRef ] As return_type ]
      Declare Property name [ ( [ param_list ] ) ] [ [ ByRef ] As 
      return_type ]
   End Type

Parameters
   param_list
      Parenthesized comma-separated list of parameters.
   return_type
      The return type of a Function, Operator, or Property procedure.
   name
      The name or symbol of the routine.
   op_symbol
      The name or symbol of an operator.
   T
      The name of a new user-defined type.

Description
   The Declare statement declares a Sub, Function, Operator, Constructor, 
   or Destructor. We will refer to one of these as a routine. 
   The routine can be referred to in code without seeing its definition, 
   although it must be defined somewhere. Essentially, the Declare 
   statement introduces a routine, and states that its definition is 
   elsewhere. For example, a function can be declared at the top of a 
   source module, called, then defined at the bottom of the source file, as 
   shown below the example.

   A routine's declaration is almost identical to the first line of its 
   definition, except the declaration is preceded by the Declare keyword 
   and has no body. Also, attributes such as Export are left off the 
   declaration.

   FreeBASIC, as QB, does not require the declaration of the functions 
   unless they are defined in a different source file or in the same file 
   past the point where they are called. This is no longer true for 
   routines declared inside a Type body, which must always be declared 
   first in the Type's body before use. If you do not declare Type routines 
   you will receive an error.

    As every file using a function must have its declaration, declarations 
   are usually kept in one or more include files to allow usage of the 
   function by any module that needs it using the #include statement. 

Example
Module-level Function:
   '' declare the function sum which takes two integers and returns an integer
   Declare Function sum( As Integer, As Integer ) As Integer

      Print "the sum of 420 and 69 is: " & sum( 420, 69 )    '' call the function sum

   '' define the function sum which takes two integers and returns an integer
   Function sum( a As Integer, b As Integer ) As Integer
      Return a + b
   End Function

Type-level Sub:
   Type my_type
      my_data As Integer
      Declare Sub increment_data( )
   End Type

   Sub my_type.increment_data( )
      my_data += 1
   End Sub

   Dim As my_type an_instance

   an_instance.my_data = 68

   an_instance.increment_data( )

   Print an_instance.my_data

Dialect Differences
   * In the -lang fb dialect, ByVal is the default parameter passing 
     convention.
   * In the -lang qb and -lang deprecated dialects, ByRef is the default 
     parameter passing convention.
   * Type-level Sub/Function/Operator/Constructor/Destructor's are only 
     allowed in -lang fb

Differences from QB
   * In FreeBASIC, the parameter names are optional.

See also
   * Sub
   * Function
   * Operator
   * Property
   * Constructor
   * Destructor
   * Constructor (Module)
   * Destructor (Module)
   * Type
   * Dim
   * Alias (Name)
   * Alias (Modifier)

   

---------------------------------------------------------- KeyPgDefbyte ----
DefByte

Specifies a default data type for a range of variable names

Syntax
   DefByte start_letter[-end_letter ][, ...]

Parameters
   start_letter
      the first letter in the range
   end_letter
      the last letter in the range

Description
   DefByte specifies that variables and arrays which aren't declared with a 
   data type - or not declared at all - are implicitly declared of type Byte
   if the first letter of their names matches a certain letter or lies 
   within an inclusive range of letters.

Example
   This will make bNumber a Byte number since it's first letter starts with 
   b:
   '' Compile with -lang fblite or qb

   #lang "fblite"

   DefByte b
   Dim bNumber

Dialect Differences
   * Available in the -lang fblite dialect.
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Defbyte.

Differences from QB
   * New to FreeBASIC

See also
   * Byte
   * DefInt
   * DefUByte
   * Dim



----------------------------------------------------------- KeyPgDefdbl ----
DefDbl

Specifies a default data type for a range of variable names

Syntax
   DefDbl start_letter[-end_letter ][, ...]

Parameters
   start_letter
      the first letter in the range
   end_letter
      the last letter in the range

Description
   DefDbl specifies that variables and arrays which aren't declared with a 
   data type - or not declared at all - are implicitly declared of type 
   Double if the first letter of their names matches a certain letter or 
   lies within an inclusive range of letters.

Example
   This will make aNum a Double-precision decimal number since it is in the 
   range of a-d:
   '' Compile with -lang fblite or qb

   #lang "fblite"

   DefDbl a-d
   Dim aNum 'implicit: As Double

   Print Len(aNum) ' Prints 8, the number of bytes in a double.

Dialect Differences
   * Only available in the -lang qb and -lang fblite dialects.

Differences from QB
   * None

See also
   * DefInt
   * DefSng
   * Dim
   * Double



---------------------------------------------------------- KeyPgDefined ----
defined

Preprocessor function to test if a symbol has been defined

Syntax
   defined (symbol_name)

Parameters
   symbol_name
      Name of the symbol to test

Return Value
   Returns non-zero (-1) if the symbol has been defined, otherwise returns 
   zero (0).

Description
   Given the symbol name, the defined() preprocessor function returns true 
   if the symbol has been defined - or false if the symbol is unknown.

   This is used mainly with #if.

   Similar to #ifdef except it allows more than one check to occur because 
   of its flexibility.

Example
   'e.g. - which symbols are defined out of a, b, c, and d ?

   Const a = 300
   #define b 12
   Dim c As Single

   #if defined(a)
    Print "a is defined"
   #endif
   #if defined(b)
    Print "b is defined"
   #endif
   #if defined(c)
    Print "c is defined"
   #endif
   #if defined(d)
    Print "d is defined"
   #endif

Differences from QB
   * New to FreeBASIC

See also
   * #define
   * #macro
   * #if
   * #else 
   * #elseif 
   * #endif 
   * #ifdef
   * #ifndef
   * #undef



----------------------------------------------------------- KeyPgDefint ----
DefInt

Specifies a default data type for a range of variable names

Syntax
   DefInt start_letter[-end_letter ][, ...]

Parameters
   start_letter
      the first letter in the range
   end_letter
      the last letter in the range

Description
   DefInt specifies that variables and arrays which aren't declared with a 
   data type - or not declared at all - are implicitly declared of type 
   Integer if the first letter of their names matches a certain letter or 
   lies within an inclusive range of letters.

Example
   This will make iNumber an Integer number since its first letter starts 
   with i.
   '' Compile with -lang fblite or qb

   #lang "fblite"

   DefInt i
   Dim iNumber

Dialect Differences
   * Only available in the -lang qb and -lang fblite dialects.

Differences from QB
   * None

See also
   * DefByte
   * DefDbl
   * DefLng
   * DefLongInt
   * DefShort
   * DefSng
   * DefStr
   * Integer



----------------------------------------------------------- KeyPgDeflng ----
DefLng

Specifies a default data type for a range of variable names

Syntax
   DefLng start_letter[-end_letter ][, ...]

Parameters
   start_letter
      the first letter in the range
   end_letter
      the last letter in the range

Description
   DefLng specifies that variables and arrays which aren't declared with a 
   data type - or not declared at all - are implicitly declared of type Long
   if the first letter of their names matches a certain letter or lies 
   within an inclusive range of letters.

Example
   This will make lNumber a Long integer number since it starts with l.
   '' Compile with -lang fblite or qb

   #lang "fblite"

   DefLng l
   Dim lNumber ' implicit: As Long

   Print Len(lNumber) ' Displays 4, the number of bytes in a long.

Dialect Differences
   * Only available in the -lang qb and -lang fblite dialects.

Differences from QB
   * None

See also
   * DefInt
   * Defulongint
   * Dim
   * LongInt



------------------------------------------------------- KeyPgDeflongint ----
DefLongInt

Specifies a default data type for a range of variable names

Syntax
   DefLongInt start_letter[-end_letter ][, ...]

Parameters
   start_letter
      the first letter in the range
   end_letter
      the last letter in the range

Description
   DefLongInt specifies that variables and arrays which aren't declared 
   with a data type - or not declared at all - are implicitly declared of 
   type LongInt if the first letter of their names matches a certain letter 
   or lies within an inclusive range of letters.

Example
   This will make lNumber a LongInt number since it's first letter starts 
   with l.
   '' Compile with -lang fblite

   #lang "fblite"

   DefLongInt l
   Dim lNumber

Dialect Differences
   * Available in the -lang fblite dialect.
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Deflongint.

Differences from QB
   * New to FreeBASIC

See also
   * DefInt
   * Defulongint
   * Dim
   * LongInt



--------------------------------------------------------- KeyPgDefshort ----
DefShort

Specifies a default data type for a range of variable names

Syntax
   DefShort start_letter[-end_letter ][, ...]

Parameters
   start_letter
      the first letter in the range
   end_letter
      the last letter in the range

Description
   DefShort specifies that variables and arrays which aren't declared with 
   a data type - or not declared at all - are implicitly declared of type 
   Short if the first letter of their names matches a certain letter or 
   lies within an inclusive range of letters.

Example
   This will make sNumber a Short number since its first letter starts with 
   s.
   '' Compile with -lang fblite or qb

   #lang "fblite"

   DefShort s
   Dim sNumber

Dialect Differences
   * Available in the -lang fblite dialect.
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Defshort.

Differences from QB
   * New to FreeBASIC
   * In QBasic, to make variables default to a 2 byte integer, DEFINT is 
     used.

See also
   * DefInt
   * DefUShort
   * Dim
   * Integer
   * Short



----------------------------------------------------------- KeyPgDefsng ----
DefSng

Specifies a default data type for a range of variable names

Syntax
   DefSng start_letter[-end_letter ][, ...]

Parameters
   start_letter
      the first letter in the range
   end_letter
      the last letter in the range

Description
   DefSng specifies that variables and arrays which aren't declared with a 
   data type - or not declared at all - are implicitly declared of type 
   Single if the first letter of their names matches a certain letter or 
   lies within an inclusive range of letters.

Example
   This will make sNumber and yNumber a Single-precision decimal number 
   since it is in the range of s-z.
   '' Compile with -lang fblite or qb

   #lang "fblite"

   DefSng s-z
   Dim sNumber, yNumber

Dialect Differences
   * Only available in the -lang qb and -lang fblite dialects.

Differences from QB
   * None

See also
   * DefInt
   * DefDbl
   * Single



----------------------------------------------------------- KeyPgDefstr ----
DefStr

Specifies a default data type for a range of variable names

Syntax
   DefStr start_letter[-end_letter ][, ...]

Parameters
   start_letter
      the first letter in the range
   end_letter
      the last letter in the range

Description
   DefStr specifies that variables and arrays which aren't declared with a 
   data type - or not declared at all - are implicitly declared of type 
   String if the first letter of their names matches a certain letter or 
   lies within an inclusive range of letters.

Example
   This will make sMessage a String since it starts with s.
   '' Compile with -lang fblite or qb

   #lang "fblite"

   DefStr s
   Dim sMessage

Dialect Differences
   * Only available in the -lang qb and -lang fblite dialects.

Differences from QB
   * None

See also
   * DefInt
   * DefSng
   * DefLng
   * DefDbl
   * Dim
   * String



--------------------------------------------------------- KeyPgDefubyte ----
DefUByte

Specifies a default data type for a range of variable names

Syntax
   DefUByte start_letter[-end_letter ][, ...]

Parameters
   start_letter
      the first letter in the range
   end_letter
      the last letter in the range

Description
   DefUByte specifies that variables and arrays which aren't declared with 
   a data type - or not declared at all - are implicitly declared of type 
   UByte if the first letter of their names matches a certain letter or 
   lies within an inclusive range of letters.

Example
   This will make uNumber a UByte number since it's first letter starts 
   with u.
   '' Compile with -lang fblite

   #lang "fblite"

   DefUByte u
   Dim uNumber

Dialect Differences
   * Available in the -lang fblite dialect.
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Defubyte.

Differences from QB
   * New to FreeBASIC

See also
   * DefByte
   * DefInt
   * Dim
   * UByte



---------------------------------------------------------- KeyPgDefuint ----
DefUInt

Specifies a default data type for a range of variable names

Syntax
   DefUInt start_letter[-end_letter ][, ...]

Parameters
   start_letter
      the first letter in the range
   end_letter
      the last letter in the range

Description
   DefUInt specifies that variables and arrays which aren't declared with a 
   data type - or not declared at all - are implicitly declared of type 
   UInteger if the first letter of their names matches a certain letter or 
   lies within an inclusive range of letters.

Example
   This will make uNumber a UInteger number since its first letter starts 
   with u.
   '' Compile with -lang fblite

   #lang "fblite"

   DefInt u
   Dim uNumber

Dialect Differences
   * Available in the -lang fblite dialect.
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Defuint.

Differences from QB
   * New to FreeBASIC

See also
   * DefInt
   * Dim
   * UInteger



------------------------------------------------------ KeyPgDefulongint ----
Defulongint

Specifies a default data type for a range of variable names

Syntax
   Defulongint start_letter[-end_letter ][, ...]

Parameters
   start_letter
      the first letter in the range
   end_letter
      the last letter in the range

Description
   Defulongint specifies that variables and arrays which aren't declared 
   with a data type - or not declared at all - are implicitly declared of 
   type ULongInt if the first letter of their names matches a certain 
   letter or lies within an inclusive range of letters.

Example
   This will make lNumber a ULongInt number since its first letter starts 
   with l.
   '' Compile with -lang fblite

   #lang "fblite"

   defulongint l
   Dim lNumber

Dialect Differences
   * Available in the -lang fblite dialect.
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Defulongint.

Differences from QB
   * New to FreeBASIC

See also
   * DefInt
   * DefLongInt
   * Dim
   * ULongInt



-------------------------------------------------------- KeyPgDefushort ----
DefUShort

Specifies a default data type for a range of variable names

Syntax
   DefUShort start_letter[-end_letter ][, ...]

Parameters
   start_letter
      the first letter in the range
   end_letter
      the last letter in the range

Description
   DefUShort specifies that variables and arrays which aren't declared with 
   a data type - or not declared at all - are implicitly declared of type 
   UShort if the first letter of their names matches a certain letter or 
   lies within an inclusive range of letters.

Example
   This will make uNumber a UShort number since its first letter starts 
   with u.
   '' Compile with -lang fblite

   #lang "fblite"

   DefUShort u
   Dim uNumber

Dialect Differences
   * Available in the -lang fblite dialect.
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Defushort.

Differences from QB
   * New to FreeBASIC

See also
   * DefInt
   * DefShort
   * Dim
   * UShort



--------------------------------------------------------- KeyPgOpDelete ----
Operator Delete Statement

Operator to destroy data and free memory allocated with the 
Operator New Expression

Usage
   Delete buf
      or
   Delete[] buf

Parameters
   buf 
      A pointer to memory that has been allocated by New Expression 
      operator or New[] Expression operator, the array-version of 
      New Expression operator (a typed pointer must be provided in 
      accordance to the data type to delete).

Description
   The Delete Statement operator is used to destroy and free the memory of 
   an object created with New Expression operator. When deleting a TYPE, 
   its destructor will be called. Delete Statement operator should only be 
   used with addresses returned from New Expression operator.

   The array version of Delete Statement operator, Delete[] Statement 
   operator, is used to destroy an array of objects previously created with 
   New[] Expression operator, the array-version of New Expression operator. 
   Destructors will be called here as well.

   Delete Statement operator must be used with addresses returned from 
   New Expression operator, and Delete[] Statement operator with New[] 
   Expression operator, the array-version of New Expression operator. You 
   cannot mix and match the different versions of the operators.

   After the memory is deleted, the buf pointer will be pointing at invalid 
   memory. Calling Delete Expression twice on the same pointer value leads 
   to undefined behavior. It may be a good idea to set the buf pointer to 
   null (0), in order to guard against later code using it accidentally, 
   since null pointer dereferences are easier to find and debug.

   Calling Delete Statement operator on a null pointer induces no action.

   The memory deallocation process part provided by the Delete Statement 
   operator can be overloaded for user-defined types as a member operator 
   Delete Overload. The previous process part for data destruction can 
   never be modified.

   Note: Any operator Delete[] Statement (or the only overload operator 
   Delete Statement) is not compatible with sub-type polymorphism, even 
   using Override Virtual Destructor that may in addition induce crashing.
   Instead of having to call such an operator Delete([]) Statement on 
   derived-type pointer, the safest way is to simply call (on base-type 
   pointer) an overridden user Virtual member procedure that will 
   automatically launch the operator Delete([]) Statement at derived-type 
   level.

Example
   Type Rational
      As Integer numerator, denominator
   End Type

   ' Create and initialize a Rational, and store its address.
   Dim p As Rational Ptr = New Rational(3, 4)

   Print p->numerator & "/" & p->denominator

   ' Destroy the rational and give its memory back to the system. 
   Delete p

   ' Set the pointer to null to guard against future accesses
   p = 0

   ' Allocate memory for 100 integers, store the address of the first one.
   Dim p As Integer Ptr = New Integer[100]

   ' Assign some values to the integers in the array.
   For i As Integer = 0 To 99
      p[i] = i
   Next

   ' Free the entire integer array.
   Delete[] p

   ' Set the pointer to null to guard against future accesses
   p = 0

Dialect Differences
   * Only available in the -lang fb dialect.

Differences from QB
   * New to FreeBASIC

See also
   * New Expression
   * Delete Overload
   * Deallocate



------------------------------------------------------- KeyPgDestructor ----
Destructor

Called automatically when a class or user defined type goes out of scope or 
is destroyed

Syntax
   Type typename
      field declarations
      Declare Destructor ( )
   End Type

   Destructor typename ( ) [ Export ]
      statements
   End Destructor

Parameters
   typename 
      name of the Type of Class

Description
   The destructor method is called when a user defined Type or Class 
   variable goes out of scope or is destroyed explicitly with the 
   Delete Statement operator.

   typename is the name of the type for which the Destructor method is 
   declared and defined.  Name resolution for typename follows the same 
   rules as procedures when used in a Namespace.

   The Destructor method is passed a hidden This parameter having the same 
   type as typename.

   The destructor in a type is called before the destructors on any of its 
   fields.  Therefore, all fields are accessible with the hidden This 
   parameter in the destructor body.

   Only one destructor may be declared and defined per type (but several 
   destructors can be called in a chained way if the type contains or 
   inherits other types with their own destructors).

   Since the End statement does not close any scope, object destructors 
   will not automatically be called if the End statement is used to 
   terminate the program.

   Destructor can be also called directly from the typename instance like 
   the other member methods (Sub) and with the same syntax, i.e. using a 
   member access operator, e.g. obj.Destructor(). The object, and all its 
   members, are assumed to be constructed and in a valid state, otherwise 
   its effects are undefined and may cause crashes.  This syntax is useful 
   in cases where obj has been constructed manually, e.g. with obj.
   Constructor() or Placement New.

Example
   Type T
     value As ZString * 32
     Declare Constructor ( init_value As String )
     Declare Destructor ()
   End Type

   Constructor T ( init_value As String )
     value = init_value
     Print "Creating: "; value
   End Constructor

   Destructor T ()
     Print "Destroying: "; value
   End Destructor

   Sub MySub
     Dim x As T = ("A.x")
   End Sub

   Dim x As T = ("main.x")

   Scope
     Dim x As T = ("main.scope.x")
   End Scope

   MySub

Output:

   Creating: main.x
   Creating: main.scope.x
   Destroying: main.scope.x
   Creating: A.x
   Destroying: A.x
   Destroying: main.x

Dialect Differences
   * Object-related features are supported only in the -lang fb dialect.

Differences from QB
   * New to FreeBASIC

See also
   * Class
   * Constructor
   * Delete Statement
   * Destructor (Module)
   * Type



------------------------------------------------- KeyPgModuleDestructor ----
Destructor (Module)

Specifies execution of a procedure at program termination

Syntax
   [Public | Private] Sub identifier [Alias "external_identifier"] [()] 
   Destructor [priority] [Static]
      { procedure body }
   End Sub

Description
   Defines a procedure to be automatically called from a compiled program's 
   end-code.  End-code is generated by the compiler and is executed when 
   the program terminates normally.  Procedures defined as destructors may 
   be used the same way as ordinary procedures, that is, they may be called 
   from within module-level code, as well as other procedures.  

   The procedure must have an empty parameter list.  A compile-time error 
   will be generated if the Destructor keyword is used in a Sub definition 
   having one or more parameters. In a set of overloaded procedures, only 
   one (1) destructor may be defined because of the ambiguity of having 
   multiple Subs which take no arguments.

   In a single module, depending on the build and run-time environment of 
   the target system:
      * destructors may execute in which they are defined, or reverse 
        order
      * destructors may execute before or after global static variables 
        having dstructors
      * destructors may execute before or after other module destructors 
        having priority attribute
      * destructors with priority attribute may execute before or after 
        global static variables having destructors

   The priority attribute, an integer between 101 and 65535, can be used to 
   force destructors to be executed in a certain order.  The value of 
   priority has no specific meaning, only the relationship of the number 
   with other destructor priorities. 101 is the lowest priority and is 
   executed last, relative to other destructors also having priority 
   attribute.

   A module may define multiple destructor procedures.  Destructor 
   procedures may also appear in more than one module. All procedures 
   defined with the syntax shown above will be added to the list of 
   procedures to be called during the program's termination.

   The order in which destructors defined in multiple modules are executed 
   is known only at link time.  Therefore, special care should be taken 
   when using destructors that may call on a secondary module also defining 
   a destructors.  In such a case it is advisable to use a single 
   destructor that explicit calls termination procedures in multiple 
   modules to ensure a graceful termination of the application.

   Destructors will be called if the program terminates normally or if 
   error-checking is enabled and the program terminates abnormally.

   Public static member procedures (a Sub having an empty parameter list), 
   of user defined Type can be defined as a module destructor, by adding 
   the Constructor keyword used in the sub procedure definition.

   The module destructor feature exposes a low-level link-time feature of 
   the build and run-time environment.  Accessing global static objects 
   having destructors from module destructors should be avoided due to 
   variations in execution order on different build systems.

Example
   Sub pauseonexit Destructor
      
      '' If the program reaches the end, or aborts with an error, 
      '' it will run this destructor before closing
      
      Print "Press any key to end the program..."
      Sleep
      
   End Sub

   Dim array(0 To 10, 0 To 10) As Integer
   Dim As Integer i = 0, j = 11

   '' this next line will cause the program to abort with an 
   '' error if you compile with array bounds checking enabled (fbc -exx ...)
   Print array(i, j)

Differences from QB
   * New to FreeBASIC

See also
   * Destructor (Class)
   * Constructor (Module)
   * Sub



-------------------------------------------------------------- KeyPgDim ----
Dim

Declares a variable

Syntax
      Dim [Shared] name1 As DataType [, name2 As DataType, ...]
   or
      Dim [Shared] As DataType name1 [, name2, ...]

   Arrays:
      Dim name ( [lbound To] ubound [, ...] ) As DataType
      Dim name ( Any [, Any...] ) As DataType
      Dim name ( ) As DataType

   Initializers:
      Dim scalar_symbol As DataType = expression | Any
      Dim array_symbol (arraybounds) As DataType = { expression [, ...] } | 
      Any
      Dim udt_symbol As DataType = ( expression [, ...] ) | Any

Description
   Declares a variable by name and reserves memory to accommodate it.

   Variables must be declared before they can be used in the -lang fb 
   dialect or when using Option Explicit in the other dialects.  Only in 
   the -lang qb and -lang fblite dialects variables may be used without 
   first declaring them, in such a case they are called implicit variables.

   Dim can be used to declare and assign variables of any of the supported 
   data types, user defined types, or enumerations.

   Depending on where and how a variable or array is declared can change 
   how it is allocated in memory.  See Storage Classes.

   More than one variable may be declared in a single Dim statement by 
   separating each variable declaration with a comma.

   '' Variable declaration examples

   '' One variable per DIM statement
   Dim text As String
   Dim x As Double

   '' More than one variable declared, different data types
   Dim k As Single, factor As Double, s As String

   '' More than one variable declared, all same data types
   Dim As Integer mx, my, mz ,mb

   '' Variable having an initializer
   Dim px As Double Ptr = @x

Explicit Variables with Implicit Data Types
   In the -lang qb and -lang fblite dialects, even if the variable is 
   declared explicitly, it will be given a default data type if the data 
   type is not explicitly given either by name or by type suffix.  The 
   default data type is Single in the -lang qb dialect and Integer in the 
   -lang fblite dialect.  The default data type can be changed throughout a 
   source listing by use of the Def### statements. (for example, DefInt, 
   DefStr, DefSng)

   '' Compile with -lang qb

   '$lang: "qb"

   '' All variables beginning with A through N will default to the INTEGER data type
   '' All other variables default to the SINGLE data type
   DefInt I-N

   Dim I, J, X, Y, T$, D As Double
   '' I and J are INTEGERs
   '' X and Y are SINGLEs
   '' T$ is STRING
   '' D is DOUBLE

Arrays
   As with most BASIC dialects, FreeBASIC supports arrays with indexes 
   ranging from a lower bound to an upper bound.  In the syntaxes shown, 
   lbound refers to the lower bound, or the smallest index.  ubound refers 
   to the upper bound, or the largest index.  If a lower bound is not 
   specified, it is assumed to be zero by default, unless Option Base is 
   used.

   Const upperbound = 10

   '' Declare an array with indexes ranging from 0 to upperbound, 
   '' for a total of (upperbound + 1) indexes.
   Dim array(upperbound) As Single

   Multidimensional arrays can be declared as well, and are stored in this 
   definite order: values differing only in the last index are contiguous 
   (row-major order).
   The maximum number of dimensions of a multidimensional array is 8. 

   '' declare a three-dimensional array of single 
   '' precision floating-point numbers.
   Dim array(1 To 2, 6, 3 To 5) As Single

   '' The first dimension of the declared array 
   '' has indices from 1 to 2, the second, 0 to 6, 
   '' and the third, 3 to 5.

			

   For more information on arrays see Arrays Overview.

   If the values used  with Dim to declare the dimensions of an array are 
   all constants, the array will be created fixed length (of Static size, 
   unless Option Dynamic is specified), while using one or more variables 
   to declare the dimensions of an array makes it variable length, even if 
   Option Static is in effect.

   Arrays can be declared as variable length in several ways: Using Dim 
   with an empty set of indexes (Dim x()), using Dim with indexes that are 
   variables or using the keyword ReDim, or using Any in place of the array 
   bounds, or declaring it past the metacommand $Dynamic. Variable length 
   arrays can't use initializers.

   Arrays declared with Dim having constant indexes and not preceeded by 
   Option Dynamic are fixed length (not resizable at runtime) and can use 
   initializers.

   The upper bound can be an ellipsis (..., 3 dots).  This will cause to 
   upper bound to be set automatically based on the number of elements 
   found in the initializer.  When ellipsis is used in this manner, an 
   initializer must be used, and it may not be Any.  See the Ellipsis page 
   for a short example.

   See also Fixed-Length Arrays and Variable-Length Arrays.

Initializers
   Arrays, variables, strings, and user defined types (UDTs) are 
   initialized to zero (or False for Boolean) or null strings by default 
   when they are created.

   To avoid the overhead of default variable initialization, the Any 
   initializer can be used with Dim to tell the compiler to only reserve 
   the place for the variable in memory but not initialize it, so the 
   variable will contain garbage. In this case the programmer should not 
   make assumptions about the initial values.

   Fixed-length arrays, variables, zstrings and UDTs may be given a value 
   at the time of their declaration by following the variable declaration 
   with an initializer.  Note the difference between initializing different 
   types. Arrays, variables and UDTs are initialized as they would in a 
   normal assignment, using an equal ( = ) sign.  The => sign can be used, 
   allowing to avoid the declaration resembling an expression when 
   declaring fixed length strings.

   Array values are given in comma-delimited values enclosed by curly 
   brackets, and UDT values are given in comma delimited values enclosed by 
   parenthesis.  These methods of initializing variables can be nested 
   within one another for complex assignments. Nesting allows for arrays of 
   any dimension to be initialized.

   '' Declare an array of 2 by 5 elements
   '' and initialize
   Dim array(1 To 2, 1 To 5) As Integer => {{1, 2, 3, 4, 5}, {1, 2, 3, 4, 5}}

			

   '' declare a simple UDT
   Type mytype
      var1 As Double
      var2 As Integer
   End Type

   '' declare a 3 element array and initialize the first
   '' 2 mytype elements
   Dim myvar(0 To 2) As mytype => {(1.0, 1), (2.0, 2)}

	
   For module-level, fixed-length, or global variables, initialized values 
   must be constant expressions.  FreeBASIC will report a compile-time 
   error if otherwise.

   Note: Initializing UDT's with strings is not supported at this time. 
   Initializing UDT containing data-field initializer or string is not 
   valid.

Explicit Variables with Type Suffixes
   In the -lang qb and -lang fblite dialects, the data type of a variable 
   may be indicated with a type suffix ( $ % # ! & ).

   '' Compile with -lang qb or fblite

   '$lang: "qb"

   '' A string variable using the $ type suffix
   Dim strVariable$

   '' An integer variable using the % type suffix
   Dim intVariable%

   '' A long variable using the & type suffix
   Dim lngVariable&

   '' A single precision floating point variable using the ! type suffix
   Dim sngVariable!

   '' A double precision floating point variable using the # type suffix
   Dim dblVariable#

Example
   Dim a As Byte
   Dim b As Short
   Dim c As Integer
   Dim d As LongInt
   Dim au As UByte
   Dim bu As UShort
   Dim cu As UInteger
   Dim du As ULongInt
   Dim e As Single
   Dim f As Double
   Dim g As Integer Ptr
   Dim h As Byte Ptr
   Dim s1 As String * 10   '' fixed length string
   Dim s2 As String        '' variable length string
   Dim s3 As ZString Ptr   '' zstring

   s1 = "Hello World!"
   s2 = "Hello World from FreeBASIC!"
   s3 = Allocate( Len( s2 ) + 1 )
   *s3 = s2

   Print "Byte: "; Len(a)
   Print "Short: "; Len(b)
   Print "Integer: "; Len(c)
   Print "Longint: "; Len(d)
   Print "UByte: "; Len(au)
   Print "UShort: "; Len(bu)
   Print "UInteger: "; Len(cu)
   Print "ULongint: "; Len(du)
   Print "Single: "; Len(e)
   Print "Double: "; Len(f)
   Print "Integer Pointer: "; Len(g)
   Print "Byte Pointer: "; Len(h)
   Print "Fixed String: "; Len(s1)
   Print "Variable String: "; Len(s2)
   Print "ZString: "; Len(*s3)

   Deallocate(s3)

Dialect Differences
   * In the -lang qb and -lang fblite dialects, variables have procedure 
     scope if the variable is defined inside a procedure, and for the 
     entire module if the variable is defined with Dim Shared.
   * In the -lang qb dialect, variables cannot be initialised.  In the 
     -lang fblite dialect, the variable is initialised with a default value 
     at the start of the procedure/module, and assigned its initial value 
     if/when the Dim statement is executed at runtime.
   * In the -lang fb and -lang deprecated dialects, variables defined 
     inside compound block statements (For..Next, While..Wend, Do..Loop, 
     If..Then, Select..End Select, With..End With, Scope..End Scope) have 
     local working scopes, and are visible only within these blocks.
   * In the -lang fb dialect, Option statements (e.g. Option Base, 
     Option Dynamic), metacommands(e.g. $Static) and Def### statements 
     (e.g. DefInt) are not allowed.

Differences from QB
   * Variable Initializers are new to FreeBASIC.
   * The alternate syntax Dim As DataType symbolname, [...] is new to 
     FreeBASIC.
   * Multidimensional arrays are stored in this definite order: values 
     differing only in the last index are contiguous (row-major order), 
     they were stored in opposite order in QB by default: values differing 
     only in the first index were contiguous (column-major order).
   * Variable length arrays up to 2 GiB in size are possible in FreeBASIC. 
     In QB, $STATIC arrays were limited to 64 KiB , or to the DOS memory 
     available (several 100 KiB at best) if made $DYNAMIC and /AH was used.
   * The ellipsis form for upper bounds is new to FreeBASIC.

See also
   * Var
   * Common
   * Extern
   * ReDim
   * Preserve
   * Shared
   * Static
   * Byref (Variables)
   * Erase
   * LBound
   * UBound
   * ... (Ellipsis)
   * Any
   * Pointers to Procedures



-------------------------------------------------------------- KeyPgDir ----
Dir

Searches for and returns information about an item in the filesystem; 
performs a directory searchattrib

Syntax
   # Include "dir.bi"

   Declare Function Dir ( ByRef item_spec As Const String, ByVal 
   attrib_mask As Integer = fbNormal, ByRef out_attrib As Integer ) As 
   String
   Declare Function Dir ( ByRef item_spec As Const String, ByVal 
   attrib_mask As Integer = fbNormal, ByVal p_out_attrib As Integer Ptr = 0 
   ) As String
   Declare Function Dir ( ByVal attrib_mask As Integer = fbNormal, ByRef 
   out_attrib As Integer ) As String
   Declare Function Dir ( ByVal attrib_mask As Integer = fbNormal, ByVal 
   p_out_attrib As Integer Ptr = 0 ) As String

Usage
   result = Dir( item_spec, [ attrib_mask ], out_attrib ] )
   result = Dir( item_spec [, [ attrib_mask ] [, p_out_attrib ] ] )
   result = Dir( out_attrib )
   result = Dir( [ p_out_attrib ] )

Parameters
   item_spec
      The pattern to match an item's name against.
   attrib_mask
      The bit mask to match an item's attributes against.
   out_attrib
      Reference to a bit mask that's assigned each of the found item's 
      attributes, if any.
   p_out_attrib
      Pointer to a bit mask that's assigned each of the found item's 
      attributes, if any.

Return Value
   If no item matching the name item_spec or the attribute mask attrib_mask 
   was found, then out_attrib (or *p_out_attrib) is assigned to zero and an 
   empty string is returned. Otherwise, out_attrib (or *p_out_attrib) is 
   assigned the attribute mask of the item, and the item name, without a 
   path, is returned.

Description
   Dir returns the first filesystem item that matches the item_spec passed 
   as an argument. To retrieve the next file items that match this 
   item_spec pattern, call Dir again without this argument (or with an 
   empty string).
   So to obtain a list of items in a directory, Dir needs to be invoked 
   multiple times returning one item per invocation.

   If item_spec contains an absolute path, then the first procedure 
   searches the filesystem for an item that matches the name item_spec and 
   whose attributes are all contained in attrib_mask. Otherwise, it 
   searches relative to the current directory (see CurDir). In any case, if 
   a matching item is not found, out_attrib is assigned to zero and an 
   empty string is returned. Otherwise, out_attrib is assigned with the 
   attribute flags of the item, and the name of the item, without a path, 
   is returned.
   item_spec may include an asterisk (*, for matching any adjacent 
   characters) or one or more question marks (?, for matching any 
   individual character). If it does, the procedure searches for the first 
   such item.

   If an item is found, subsequent calls with item_spec omitted, or set to 
   an empty string, will return the next item matching the name item_spec 
   until no more such items are found. If attrib_mask is omitted from these 
   subsequent calls, the procedure searches for items with the same 
   attributes as in the previous call.

   The second syntax behaves the same as Dir( item_spec, attrib_mask, *
   p_out_attrib ).
   The third syntax behaves the same as Dir( "", , out_attrib ).
   The fourth syntax behaves the same as Dir( "", , *p_out_attrib ).

File Attributes:
   Files and directories and other items can be said to possess so-called 
   file attributes; metadata that describes the item. The meaning of this 
   metadata may vary depending on the operating system and the file system 
   it uses.
   The following defined constants are used as bit-flags in attrib_mask and 
   in out_attrib or *p_out_attrib. Their values can be combined to form a 
   mask using Operator Or.  These values are the metadata that the returned 
   files are allowed to have.  For example, fbDirectory will only allow the 
   directory attribute not to be set, meaning that only files or 
   directories with no other attributes set will be matched.  (fbReadOnly Or
   fbDirectory) will allow read-only directories and files, and writable 
   directories and files.
   More powerful filtering can be done by checking the returned out_attrib 
   for specifc flags using Operator And. To access the defined flags, you 
   must #include "dir.bi".

    # define fbReadOnly &h01 
      The item cannot be written to or deleted.
      DOS & Windows: The item has the "read-only" attribute set.
      Linux:The item has no write permissions associated with the current 
      user or group, nor is it globally writable.  (Whether or not the user 
      has root permissions is ignored.)

    # define fbHidden &h02 
      The item is hidden in ordinary directory listings.
      DOS & Windows: The item has the "hidden" attribute set.
      Linux: The item's name has a period (.) as the first character.

    # define fbSystem &h04 
      The item is used almost exclusively by the system.
      DOS & Windows: The item has the "system" attribute set.
      Linux: The item is either a character device, block device, named 
      pipe (FIFO) or Unix socket.

    # define fbDirectory &h10  
      The item is a directory. Includes the current (.) and parent (..) 
      directories as well.
      DOS & Windows & Linux: The item is a directory.

    # define fbArchive &h20 
      The item may be backed up after some automated operations.
      DOS & Windows: The item has the "archive" attribute set 
      (automatically set after every write access to a file).
      Linux: The item is not a directory; typical filesystems do not 
      support this metadata.

    # define fbNormal (fbReadOnly or fbArchive) 
      The item is read-only or "archived".

   (If attrib_mask does not include fbArchive, then Dir may widen the check 
   to include fbDirectory, but it is recommended to add fbDirectory 
   explicitly, if that is the behaviour sought.)

   Items found having no attributes are always matched, regardless of the 
   value of attrib_mask.  An item will not be matched if it has one or more 
   attributes that aren't specified in attrib_mask.  For example, fbArchive 
   Or fbDirectory will match against archived files, archived directories, 
   non-archived files and non-archived directories.  It will not match 
   against, for example, read-only files.

   In general it is not possible to use attrib_mask to include a 
   file/folder with one set of attributes while excluding a file/folder 
   with a different set.  For example, it is not possible to scan for 
   read-only directories while excluding read-only files (unless the files 
   also have other attributes).  Finer control can be gained by checking 
   the out_attrib value for the desired set of attributes.

Example
   #include "dir.bi" 'provides constants to use for the attrib_mask parameter

   Sub list_files (ByRef filespec As String, ByVal attrib As Integer)
      Dim As String filename = Dir(filespec, attrib) ' Start a file search with the specified filespec/attrib *AND* get the first filename.
      Do While Len(filename) > 0 ' If len(filename) is 0, exit the loop: no more filenames are left to be read.
         Print filename
         filename = Dir() ' Search for (and get) the next item matching the initially specified filespec/attrib.
      Loop
   End Sub

   Print "directories:"
   list_files "*", fbDirectory

   Print
   Print "archive files:"
   list_files "*", fbArchive

   '' Example of using DIR function and retrieving attributes

   #include "dir.bi" '' provides constants to match the attributes against

   '' set input attribute mask to allow files that are normal, hidden, system or directory
   Const attrib_mask = fbNormal Or fbHidden Or fbSystem Or fbDirectory ' = &h37

   Dim As UInteger out_attr '' unsigned integer to hold retrieved attributes

   Dim As String fname '' file/directory name returned with
   Dim As Integer filecount, dircount

   fname = Dir("*.*", attrib_mask, out_attr) '' Get first file name/attributes, according to supplied file spec and attribute mask

   Print "File listing in " & CurDir & ":"

   Do Until Len(fname) = 0 '' loop until Dir returns empty string

      If (fname <> ".") And (fname <> "..") Then '' ignore current and parent directory entries

         Print fname,

         If (out_attr And fbDirectory) <> 0 Then
            Print "- directory";
            dircount += 1
         Else
            Print "- file";
            filecount += 1
         End If
         If (out_attr And fbReadOnly) <> 0 Then Print ", read-only";
         If (out_attr And fbHidden  ) <> 0 Then Print ", hidden";
         If (out_attr And fbSystem  ) <> 0 Then Print ", system";
         If (out_attr And fbArchive ) <> 0 Then Print ", archived";
         Print

      End If

      fname = Dir(out_attr) '' find next name/attributes

   Loop

   Print
   Print "Found " & filecount & " files and " & dircount & " subdirs"

Platform Differences
   * Linux requires the filename case to match the real name of the file. 
     Windows and DOS are case insensitive.
   * Path separators in Linux are forward slashes /. Windows uses 
     backslashes \ but it allows for forward slashes.  DOS uses 
     backslashes.
   * In DOS, the attrib mask value of &h37 (&h3F usually works also, but 
     &h37 is safer) returns all files and directories, including "." and 
     "..", but no Volume: the value 8 returns the Volume, even if current 
     directory is not the main directory.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Dir.

Differences from QB
   * Not found in QBasic but present in Visual Basic.  The out_attrib 
     parameter is new to FreeBASIC.

See also
   * Open
   * CurDir
   * ChDir
   * MkDir
   * RmDir



--------------------------------------------------------------- KeyPgDo ----
Do

Control flow statement for looping.

Syntax
   Do [ { Until | While } condition ]
      [ statement block ]
   Loop

   Do
      [ statement block ]
   Loop [ { Until | While } condition ]

Differences from QB
   * None

See also
   * Do...Loop

   

----------------------------------------------------------- KeyPgDoloop ----
Do...Loop

Control flow statement for looping

Syntax
   Do [ { Until | While } condition ]
      [ statement block ]
   Loop
or
   Do
      [ statement block ]
   Loop [ { Until | While } condition ]

Description
   The Do statement executes the statements in the following statement 
   block until/while the condition, if any,  evaluates to true.

   If Until is used, the Do statement stops repetition of the statement 
   block when condition evaluates to true. The While keyword has opposite 
   effect, stopping the loop if condition evaluates to false. If both 
   condition and either Until or While are omitted, the Do statement loops 
   indefinitely.

   If an Exit Do statement is encountered inside the statement block, the 
   loop is terminated, and execution resumes immediately following the 
   enclosing Loop statement. If a Continue Do statement is encountered, the 
   rest of the statement block is skipped and execution resumes at the Do 
   statement.

   In the first syntax, the condition is checked when the Do statement is 
   first encountered, and if the condition is met, the statement block will 
   be skipped. In the second syntax, condition is initially checked after 
   the statement block is executed. This means that the statement block is 
   always guaranteed to execute at least once.

   condition may be any valid expression that evaluates to False (zero) or 
   True (non-zero).

Example
   In this example, a Do loop is used to count the total number of odd 
   numbers from 1 to 10. It will repeat until its n > 10 condition is met:
   Dim As Integer n = 1                            '' number to check
   Dim As Integer total_odd = 0                    '' running total of odd numbers
   Do Until( n > 10 )
     If( ( n Mod 2 ) > 0 ) Then total_odd += 1    '' add to total if n is odd (has remainder from division by 2)
     n += 1
   Loop
   Print "total odd numbers: " ; total_odd         '' prints '5'

   End 0

   Here, an infinite DO loop is used to count the total number of evens. We 
   place the conditional check inside the loop via an If...Then statement, 
   which exits the loop if and when n > 10 becomes true:
      Dim As Integer n = 1                            '' number to check
      Dim As Integer total_even = 0                   '' running total of even numbers
      Do
        If( n > 10 ) Then Exit Do                    '' exit if we've scanned our 10 numbers
      
        If( ( n Mod 2 ) = 0 ) Then total_even += 1   '' add to total if n is even (no remainder from division by 2)
        n += 1
      Loop
      Print "total even numbers: " ; total_even       '' prints '5'

      End 0

Dialect Differences
   * In the -lang qb and -lang fblite dialects, variables declared inside 
     a Do..Loop block have a function-wide scope  as in QB 
   * In the -lang fb and -lang deprecated dialects, variables declared 
     inside a Do..Loop block are visible only inside the block, and can't 
     be accessed outside it.

Differences from QB
   * None

See also
   * Continue
   * Exit
   * For...Next
   * While...Wend



----------------------------------------------------------- KeyPgDouble ----
Double

Standard data type: 64 bit floating point

Syntax
   Dim variable As Double

Description
   Double is a 64-bit, floating-point data type used to store more precise 
   decimal numbers. They can hold positive values in the range 
   4.940656458412465e-324 to 1.797693134862316e+308, or negative values in 
   the range -4.940656458412465e-324 to -1.797693134862316e+308, or zero (0)
   . They contain at most 53 bits of precision, or about 15 decimal digits.

   Doubles have a greater range and precision than Singles, they still have 
   limited accuracy which can lead to significant inaccuracies if not used 
   properly.  They are dyadic numbers - i.e. they can only accurately hold 
   multiples of powers of two, which will lead to inaccuracies in most 
   base-10 fractions.

Example
   'Example of using a double variable.

   Dim a As Double
   a = 1.985766472453666
   Print a

   Sleep

Differences from QB
   * None

See also
   * Single Less precise float type
   * CDbl
   * Table with variable types overview, limits and suffixes



------------------------------------------------------------- KeyPgDraw ----
Draw

Statement for sequenced pixel plotting

Syntax
   Draw [target,] cmd

Parameters
   target
      the buffer to draw on
   cmd
      a string containing the sequence of commands

Description
   Drawing will take place onto the current work page set via ScreenSet or 
   onto the target Get/Put buffer if specified.
   The Draw statement can be used to issue several drawing commands all at 
   once; it is useful to quickly draw figures. The command string accepts 
   the following commands:

   Commands to plot pixels:
      +-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
      |Command|Description                                                                                                                                                   |
      |       |Commands to plot pixels:                                                                                                                                      |
      |B      |Optional prefix: move but do not draw.                                                                                                                        |
      |N      |Optional prefix: draw but do not move.                                                                                                                        |
      |M x,y  |Move to specified screen location. if a '+' or '-' sign precedes x, movement is relative to current cursor position.  x's sign has no effect on the sign of y.|
      |U [n]  |Move n units up. If n is omitted, 1 is assumed.                                                                                                               |
      |D [n]  |Move n units down. If n is omitted, 1 is assumed.                                                                                                             |
      |L [n]  |Move n units left. If n is omitted, 1 is assumed.                                                                                                             |
      |R [n]  |Move n units right. If n is omitted, 1 is assumed.                                                                                                            |
      |E [n]  |Move n units up and right. If n is omitted, 1 is assumed.                                                                                                     |
      |F [n]  |Move n units down and right. If n is omitted, 1 is assumed.                                                                                                   |
      |G [n]  |Move n units down and left. If n is omitted, 1 is assumed.                                                                                                    |
      |H [n]  |Move n units up and left. If n is omitted, 1 is assumed.                                                                                                      |
      |       |Commands to color:                                                                                                                                            |
      |C n    |Changes current foreground color to n.                                                                                                                        |
      |P p,b  |PAINTs (flood fills) region of border color b with color p.                                                                                                   |
      |       |Commands to scale and rotate:                                                                                                                                 |
      |S n    |Sets the current unit length, default is 4.  A unit length of 4 is equal to 1 pixel.                                                                          |
      |A n    |Rotate n*90 degrees (n ranges 0-3).                                                                                                                           |
      |TA n   |Rotate n degrees (n ranges 0-359).                                                                                                                            |
      |       |Extra commands:                                                                                                                                               |
      |X p    |Executes commands at p, where p is a STRING PTR.                                                                                                              |
      +-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+

   Commands to set the color, size and angle will take affect all 
   subsequent Draw operations.

Draw respects the current clipping region as set by the View (Graphics) 
statement, but its coordinates are not affected by the custom coordinates 
system.

Example
   Screen 13

   'Move to (50,50) without drawing
   Draw "BM 50,50"

   'Set drawing color to 2 (green)
   Draw "C2"

   'Draw a box
   Draw "R50 D30 L50 U30"

   'Move inside the box
   Draw "BM +1,1"

   'Flood fill with color 1 (blue) up to border color 2 
   Draw "P 1,2"

   Sleep

   '' Draws a flower on-screen

   Dim As Integer i, a, c
   Dim As String fill, setangle

   '' pattern for each petal
   Dim As Const String petal = _
      _
      ("X" & VarPtr(setangle)) _ '' link to angle-setting string
      _
      & "C15" _       '' set outline color (white)
      & "M+100,+10" _ '' draw outline
      "M +15,-10" _
      "M -15,-10" _
      "M-100,+10" _
      _
      & "BM+100,0" _              '' move inside petal
      & ("X" & VarPtr(fill)) _    '' flood-fill petal (by linking to fill string)
      & "BM-100,0"                '' move back out

   '' set screen
   ScreenRes 320, 240, 8

   '' move to center
   Draw "BM 160, 120"

   '' set initial angle and color number
   a = 0: c = 32

   For i = 1 To 24

      '' make angle-setting and filling command strings
      setangle = "TA" & a
      fill = "P" & c & ",15"

      '' draw the petal pattern, which links to angle-setting and filling strings
      Draw petal
      
      '' short delay
      Sleep 100

      '' increment angle and color number
      a += 15: c += 1

   Next i

   Sleep

Differences from QB
   * target is new to FreeBASIC
   * QB used the special pointer keyword VARPTR$ with the X p command.
   * FB does not currently allow sub-pixel movements: all movements are 
     rounded to the nearest integer coordinate.

See also
   * Draw String
   * Screen (Graphics)
   * VarPtr
   * Paint



------------------------------------------------------- KeyPgDrawString ----
Draw String

Graphics statement to render text to an image or screen.

Syntax
   Draw String [buffer,] [STEP] (x, y), text [,color [, font [, method [, (
   alpha|blender) [, parameter] ] ] ] ]

Usage
   Draw String [buffer,] [STEP] (x, y), text [, color]
   Draw String [buffer,] [STEP] (x, y), text , , font [, method [, alpha ] 
   ]
   Draw String [buffer,] [STEP] (x, y), text , , font, Custom, blender [, 
   parameter]

Parameters
   buffer
      the sprite to draw the string on. If this is not supplied, it will be 
      drawn to the screen.
   STEP
      use relative coordinates. If STEP is added, the x and y coordinates 
      are translated relative to the last drawn point.
   x, y
      the horizontal / vertical position to draw to, relative to the top 
      left hand corner of the screen (unless STEP is used - see above).  
      The top left corner of the text will be drawn at this position.
   text
      the string containing the text to draw
   color
      if no font is supplied, this allows you to choose the color of the 
      text.  If omitted, the default foreground Color is used.
      If a font is supplied, color is ignored, and the font itself 
      specifies the color for each pixel.
   font
      an image buffer containing a custom font. If no font is supplied, the 
      standard font for the current text resolution is used, and the 
      following parameters are ignored.
   method | Custom
      specifies how the font characters are drawn on top of the target 
      surface. The same methods as found for the Put statement are allowed, 
      with the only difference that the default method is Trans for this 
      function.  This parameter only applies to custom fonts.
   alpha
      alpha value, ranging 0-255.  This parameter only applies to the Add 
      or Alpha methods.
   blender
      custom blender function for the Custom drawing method; see 
      Put (Graphics) statement description for details.  This parameter 
      only applies to the Custom method.
   parameter
      optional Pointer to be passed to the custom blender function; if 
      omitted, the default value is zero (0).

Description
   This graphics keyword prints a string to the screen with pixel 
   positioning, transparent background, and can use an user-supplied font. 
   Draw String does not update any text or graphics cursor.  It doesn't 
   wrap at the end of line.  Tabs, carriage returns and other special 
   characters have no special behavior in Draw String, and are treated as 
   normal characters.

   In graphics mode, this function provides a flexible alternative to Print
   .  It has several key advantages:
      * Draw String can print text to any coordinate on the screen, while 
        Print is constrained to the character grid accessible by Locate.
      * Print will override the background behind the text with the 
        current background color.  Draw String does not do this: it leaves 
        the pixels in the background untouched.
      * Like Put, Draw String has several different methods for printing 
        text, such as Alpha and Custom.
      * Draw String isn't limited to a single character set: it is 
        possible to supply a custom font to be used instead.

   Note: If a custom font isn't supplied, Draw String will default to the 
   standard font, as used by Print, with character size dictated by Width.  
   method - if passed - will be ignored, and the text will be drawn using 
   the color supplied, with a transparent background.

   Draw String coordinates are affected by custom coordinates system set 
   via Window and View (Graphics) statements, and the drawn text respects 
   clipping rectangle set by View (Graphics).

   The custom font format:
   The font is stored in a standard Get/Put buffer; the font has to be 
   stored in a buffer using the same depth as the current color depth, 
   otherwise Draw String will bump out with an illegal function call 
   runtime error.

   The first line of pixels in the font buffer holds the header of the 
   font, on a byte (not pixel) basis. The very first byte identifies the 
   font header version; currently this must be 0. The second byte gives the 
   ascii code of the first supported character in the font; the third byte 
   gives the ascii code of the last supported character. So if the font 
   supports the full range 0-255, 0 and 255 will be the contents of these 
   two bytes.
   Next comes the width of each of the supported characters, each in a 
   byte. Supposing the font holds 96 characters, ranging from 32 to 127 
   (inclusive), the header would have the first three bytes holding 0, 32 
   and 127, followed by 96 bytes giving the widths of the corresponding 
   chars.

   The font height is obtained by subtracting 1 from the buffer height, 
   that is, while the first buffer line of pixels acts as a font header, 
   the remaining lines define the glyphs' layout. The buffer must be as 
   wide as necessary to hold all the supported character sprites in the 
   same row, one after another.

Example
   This gives an example of basic Draw String usage: it uses it to print 
   "Hello world" in the center of the screen:
   Const w = 320, h = 200 '' screen dimensions

   Dim x As Integer, y As Integer, s As String

   '' Open a graphics window
   ScreenRes w, h

   '' Draw a string in the centre of the screen:

   s = "Hello world"
   x = (w - Len(s) * 8) \ 2
   y = (h - 1 * 8) \ 2

   Draw String (x, y), s

   '' Wait for a keypress before ending the program
   Sleep

   This example shows you how to create and use your own custom font.  For 
   simplicity, it uses Draw String with the default font to create the 
   glyphs.
   '' Define character range
   Const FIRSTCHAR = 32, LASTCHAR = 127

   Const NUMCHARS = (LASTCHAR - FIRSTCHAR) + 1
   Dim As UByte Ptr p, myFont
   Dim As Integer i

   '' Open a 256 color graphics screen (320*200)
   ScreenRes 320, 200, 8

   '' Create custom font into PUT buffer

   myFont = ImageCreate(NUMCHARS * 8, 9)

    '' Put font header at start of pixel data

   #ifndef ImageInfo '' older versions of FB don't have the ImageInfo feature
   p = myFont + IIf(myFont[0] = 7, 32, 4)
   #else
   ImageInfo( myFont, , , , , p )
   #endif

   p[0] = 0
   p[1] = FIRSTCHAR
   p[2] = LASTCHAR

    '' PUT each character into the font and update width information
   For i = FIRSTCHAR To LASTCHAR
      
      '' Here we could define a custom width for each letter, but for simplicity we use
      '' a fixed width of 8 since we are reusing the default font glyphs
      p[3 + i - FIRSTCHAR] = 8
      
      '' Create character onto custom font buffer by drawing using default font
      Draw String myFont, ((i - FIRSTCHAR) * 8, 1), Chr(i), 32 + (i Mod 24) + 24
      
   Next i

   '' Now the font buffer is ready; we could save it using BSAVE for later use
   Rem BSave "myfont.bmp", myFont

   '' Here we draw a string using the custom font
   Draw String (10, 10), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", , myFont
   Draw String (10, 26), "abcdefghijklmnopqrstuvwxyz", , myFont
   Draw String (66, 58), "Hello world!", , myFont

   '' Free the font from memory, now we are done with it
   ImageDestroy myFont

   Sleep

Differences from QB
   * New to FreeBASIC

See also
   * Print
   * ?
   * Draw
   * ImageCreate
   * ImageDestroy
   * ImageInfo
   * Put (Graphics)
   * Width



-------------------------------------------------------- KeyPgDylibfree ----
DyLibFree

Unloads a dynamic link library from memory

Syntax
   Declare Sub DyLibFree ( ByVal library As Any Pointer )

Usage
   DyLibFree( library )

Parameters
   library
      The handle of a library to unload.

Description
   DyLibFree is used to release at runtime libraries previously linked to 
   your program with DyLibLoad. The argument is the handle to the library 
   returned by DyLibLoad.

Example
   See the dynamic loading example on the Shared Libraries page.

Platform Differences
   * Dynamic link libraries are not available in DOS, as the OS doesn't 
     support them.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Dylibfree.

Differences from QB
   * New to FreeBASIC

See also
   * DyLibSymbol
   * DyLibLoad
   * Export



-------------------------------------------------------- KeyPgDylibload ----
DyLibLoad

Loads to a Dynamic Link Library (DLL) into memory at runtime

Syntax
   Declare Function DyLibLoad ( ByRef filename As String ) As Any Pointer

Usage
   result = DyLibLoad ( filename )

Parameters
   filename
      A String containing the filename of the library to load.

Return Value
   The Pointer handle of the library loaded. Zero on error

Description
   DyLibLoad is used to link at runtime libraries to your program. This 
   function does the link and returns a handle that must be used with 
   DyLibSymbol when calling a function in the library and with DyLibFree 
   when releasing the library.

   Note: If the filename string (without extension) already includes a 
   character dot (.), it may be mandatory to explicitly specify the 
   filename extension to avoid any parser ambiguity.

Example
   See the dynamic loading example on the Shared Libraries page.

Platform Differences
   * Dynamic link libraries are not available in DOS, as the OS doesn't 
     support them.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Dylibload.

Differences from QB
   * New to FreeBASIC

See also
   * DyLibSymbol
   * DyLibFree
   * Export



------------------------------------------------------ KeyPgDylibsymbol ----
DyLibSymbol

Returns the address of a function or variable in a dll

Syntax
   Declare Function DyLibSymbol ( ByVal library As Any Ptr, ByRef symbol As 
   String ) As Any Ptr
   Declare Function DyLibSymbol ( ByVal library As Any Ptr, ByVal symbol As 
   Short ) As Any Ptr

Usage
   result = DyLibSymbol ( library, symbol )

Parameters
   library
      The Any Ptr handle of a DLL returned by DyLibLoad
   symbol
      A String containing name of the function, or variable in the library 
      to return the address of.  In Windows only, can also be a Short 
      containing the ordinal of the function/variable.

Return Value
   A Pointer to the function or variable in the library.

   If the function fails, the return value is 0.

Description
   DyLibSymbol returns a pointer to the variable or function named symbol , 
   in the dll pointed by libhandle. libhandle is obtained by loading the 
   dll with DyLibLoad. The symbol must have been Exported in the dll.
   If libhandle is 0, the symbol is searched in the current executable or 
   dll.

   If using cdecl functions, only the name of the procedure needs to be 
   specified. If dynamically linking to a function created using STDCALL 
   (default in windows), then the function must be decorated. To decorate a 
   function, use its name, '@', then the number of bytes passed as 
   arguments. For instance if the function FOO takes 3 integer arguments, 
   the decorated function would be 'FOO@12'. Remember, without an explicit 
   Alias, the procedure name will be uppercase.

   If linking to a dll created in Visual C++(tm), decoration need not be 
   used. For GCC, decoration is needed.

   Note: The dylibsymbol, if failing, will attempt to automatically 
   decorate the procedure, from @0 to @256, in 4 byte increments.

Example
   See the dynamic loading example on the Shared Libraries page.

Platform Differences
   * Dynamic link libraries are not available in DOS ,as the OS doesn't 
     support them.
   * Ordinals are not supported on Linux, 0 is always returned.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Dylibsymbol.

Differences from QB
   * New to FreeBASIC

See also
   * DyLibLoad
   * Export




============================================================================
    E

------------------------------------------------------------- KeyPgElse ----
Else

Control flow statement for conditional branching

Syntax
   If expression Then [statement(s)] [Else [statement(s)]] [End If]
or
   If expression Then : [statement(s)] [Else [statement(s)]] : End If
or
   If expression Then
      [statement(s)]
   [ ElseIf expression Then ]
      [statement(s)]
   [ Else ]
      [statement(s)]
   End If

   Remark: EndIf (without blank) is also supported like in QB for backward 
   compatibility.

Differences from QB
   * None

See also
   * If...Then



----------------------------------------------------------- KeyPgElseif ----
ElseIf

Control flow statement for conditional branching

Syntax
   If expression Then
      [statement(s)]
   [ ElseIf expression Then ]
      [statement(s)]
   [ Else ]
      [statement(s)]
   End If

   Remark: EndIf (without blank) is also supported like in QB for backward 
   compatibility.

Differences from QB
   * None

See also
   * If...Then



--------------------------------------------------------- KeyPgEncoding ----
Encoding

Specifies character format of a text file

Syntax
   Open filename for {Input|Output|Append} Encoding "utf-8"|"utf-16"|"
   utf-32"|"ascii" as [#]filenum 

Parameters
   filename for {Input|Output|Append}
      file name to open for Input, Output, or Append
   Encoding "utf-8"|"utf-16"|"utf-32"|"ascii"
      indicates encoding type for the file
   filenum
      unused file number to associate with the open file

Description
   Encoding specifies the format for an Unicode text file, so Winput # and 
   Print # use the correct encoding.  If omitted from an Open statement, 
   "ascii" encoding is the default.

   Only little endian character encodings are supported at the moment. 
      *"utf8", 
      *"utf16" 
      *"utf32" 
      *"ascii" (the default)

Example
   '' This example will:
   '' 1) Write a string to a text file with utf-16 encoding
   '' 2) Display the byte contents of the file
   '' 3) Read the text back from the file
   ''
   '' WSTRING's will work as well but STRING has been
   '' used in this example since not all consoles support
   '' printing WSTRING's.

   '' The name of the file to use in this example
   Dim f As String
   f = "sample.txt"

   ''
   Scope
     Dim s As String
     s = "FreeBASIC"

     Print "Text to write to " + f + ":"
     Print s
     Print

     '' open a file for output using utf-16 encoding
     '' and print a short message
     Open f For Output Encoding "utf-16" As #1

     '' The ascii string is converted to utf-16
     Print #1, s
     Close #1
   End Scope

   ''
   Scope
     Dim s As String, n As Integer

     '' open the same file for binary and read all the bytes
     Open f For Binary As #1
     n = LOF(1)
     s = Space( n )
     Get #1,,s
     Close #1
     
     Print "Binary contents of " + f + ":"
     For i As Integer = 1 To n
      Print Hex( Asc( Mid( s, i, 1 )), 2); " ";
     Next
     Print
     Print

   End Scope

   ''
   Scope
     Dim s As String
     
     '' open a file for input using utf-16 encoding
     '' and read back the message
     Open f For Input Encoding "utf-16" As #1

     '' The ascii string is converted from utf-16
     Line Input #1, s
     Close #1

     '' Display the text
     Print "Text read from " + f + ":"
     Print s
     Print
   End Scope

Output:

   Text To Write To sample.txt:
   FreeBASIC

   Binary contents of sample.txt:
   FF FE 46 00 72 00 65 00 65 00 42 00 41 00 53 00 49 00 43 00 0D 00 0A 00 

   Text Read from sample.txt:
   FreeBASIC

Platform Differences
   * Unicode (w)strings are not supported in the DOS port of FreeBASIC

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Encoding.

Differences from QB
   * QB had no support for Unicode

See also
   * Open



--------------------------------------------------------- KeyPgEndblock ----
End (Block)

Indicates the end of a compound statement block.

Syntax
   End { Sub | Function | If  | Select  | Type  | Enum  | Scope  | With  | 
   Namespace  | Extern  | Constructor  | Destructor  | Operator | Property 
   }

Description
   Used to indicate the end of the most recent code block.

   The type of the block must be included in the command: one of Sub, 
   Function, If, Select, Type, Enum, Scope, With, Namespace, Extern, 
   Constructor, Destructor, Operator, or Property.

   Ending a Sub, Function, If, Select, Scope, Constructor, Destructor, 
   Operator, or Property block also closes the scope for variables defined 
   inside that block.  When the scope is closed, variables defined inside 
   the scope are destroyed, calling their destructors as needed.

   To end a program, see End (Statement).

Example
   Declare Sub checkvalue( n As Integer )

   Dim variable As Integer

   Input "Give me a number: ", variable
   If variable = 1 Then
   Print "You gave me a 1"
   Else
   Print "You gave me a big number!"
   End If
   checkvalue(variable)

   Sub checkvalue( n As Integer )
   Print "Value is: " & n
   End Sub

Differences from QB
   * none

See also
   * Constructor
   * Destructor
   * End (Statement)
   * Enum
   * Extern
   * Function
   * If...Then
   * Namespace
   * Operator
   * Property
   * Scope
   * Select Case
   * Sub
   * Type
   * With



-------------------------------------------------------------- KeyPgEnd ----
End (Statement)

Control flow statement to end the program.

Syntax
   Declare Sub End ( ByVal retval As Long = 0 )

Usage
   End [ retval ]

Parameters
   retval
      Error code returned to system.

Description
   Used to exit the program, and return to the operating system. An 
   optional integer return value can be specified to indicate an error code 
   to the system. If no return value is given, a value of 0 is 
   automatically returned at the end of the program.

   Usage of this statement does not cleanly close scope. Local variables 
   will not have their destructors called automatically, because FreeBASIC 
   does not do stack unwinding. Only the destructors of global variables 
   will be called in this case.

   For this reason, it is discouraged to use End simply to mark the end of 
   a program; the program will come to an end automatically, and in a 
   cleaner fashion, when the last line of module-level code has executed.

Example
   '' This program requests a string from the user, and returns an error
   '' code to the OS if the string was empty

   Function main() As Integer

      '' assign input to text string
      Dim As String text
      Line Input "Enter some text ( try ""abc"" ): " , text

      '' If string is empty, print an error message and
      '' return error code 1 (failure)
      If( text = "" ) Then
         Print "ERROR: string was empty"
         Return 1
      End If

      '' string is not empty, so print the string and
      '' return error code 0 (success)
      Print "You entered: " & text
      Return 0

   End Function

   '' call main() and return the error code to the OS
   End main()

Differences from QB
   * The END statement supports specifying a custom return value to be 
     returned to the operating system.

See also
   * End (Block)
   * Return



------------------------------------------------------------ KeyPgEndif ----
End If

Control flow statement for conditional branching.

Syntax
   If expression Then [statement(s)] [Else [statement(s)]] [End If]
or
   If expression Then : [statement(s)] [Else [statement(s)]] : End If
or
   If expression Then
      [statement(s)]
   [ ElseIf expression Then ]
      [statement(s)]
   [ Else ]
      [statement(s)]
   End If

   Remark: EndIf (without blank) is also supported like in QB for backward 
   compatibility.

Differences from QB
   * END IF was not supported in single-line IFs in QBASIC.

See also
   * If...Then

   


------------------------------------------------------------- KeyPgEnum ----
Enum

Declares an enumerated type.

Syntax
   Enum [typename [ Explicit ] ]
      symbolname [= expression] [, ...]
      ...
   End Enum

Parameters
   typename
      Name of the Enum
   symbolname
      Name of the constant
   expression
      A constant expression
   Explicit
      Requires that symbols must be explicitly referred to by typename.
      symbolname

Description
   Enum, short for enumeration, declares a list of symbol names that 
   correspond to discrete values. If no initial value is given, the first 
   item will be set to 0.  Each subsequent symbol has a value one more than 
   the previous unless expression is given.

   Symbols may be each on their own line, or separated on a single line by 
   commas.

   An Enum is a useful way of grouping together a set of related Constants. 
   A symbol can be accessed like a constant, e.g: a = symbolname.  But if 
   the name clashes with another symbol, it must be resolved using typename
   .symbolname.  This resolution method is always required if you make the 
   enum Explicit.

   A non-Explicit Enum declared inside an Extern ... End Extern block will 
   add its constants to the parent namespace directly, as in C, instead of 
   acting as a namespace on its own. It disallows the typename.symbolname 
   style of access, and the constants may conflict with other symbols from 
   the parent namespace.

   An Enum can be passed as a user defined type to Overloaded operator 
   functions.

Example
   Enum MyEnum
      option1 = 1
      option2
      option3
   End Enum

   Dim MyVar As MyEnum

   MyVar = option1

   Select Case MyVar
      Case option1
         Print "Option 1"
      Case option2
         Print "Option 2"
      Case option3
         Print "Option 3"
   End Select

Dialect Differences
   * Explicit Enum not available in the -lang qb dialect unless referenced 
     with the alias __Explicit.

Differences from QB
   * New to FreeBASIC

See also
   * Const
   * Operator



------------------------------------------------------- KeyPgSetenviron ----
SetEnviron

Sets a system environment variable

Syntax
   Declare Function SetEnviron ( ByRef varexpression As String ) As Long

Usage
   result = SetEnviron( varexpression )

Parameters
   varexpression
      Name and setting of an environment variable in the following (or 
      equivalent) form: varname=varstring.
      (varname being the name of the environment variable, and varstring 
      being its text value to set)

Return Value
   Return zero (0) if successful, non-zero otherwise.

Description
   Modifies system environment variables.  There are several variables 
   available for editing other than the default ones on your system.  An 
   example of this would be fbgfx, where you can choose the form of 
   graphics driver the FreeBASIC graphics library will use.

Example
   'e.g. to set the system variable "path" to "c:":

   Shell "set path" 'shows the value of path
   SetEnviron "path=c:"
   Shell "set path" 'shows the new value of path

     '' WINDOWS ONLY EXAMPLE! - We just set the graphics method to use
     '' GDI rather than DirectX.
     '' You may note a difference in FPS.
   SetEnviron("fbgfx=GDI")

     '' Desktop width/height
   Dim As Integer ScrW, ScrH, BPP
   ScreenInfo ScrW, ScrH, BPP

     '' Create a screen at the width/height of your monitor.
     '' Normally this would be slow, but GDI is fairly fast for this kind
     '' of thing.
   ScreenRes ScrW, ScrH, BPP

     '' Start our timer/
   Dim As Double T = Timer

     '' Lock our page
   ScreenLock
   Do
     
      '' Print time since last frame
     Locate 1, 1
     Print "FPS: " & 1 / ( Timer - T )
     T = Timer
     
      '' Flip our screen
     ScreenUnlock
     ScreenLock
      '' Commit a graphical change to our screen.
     Cls
     
   Loop Until Len(Inkey)

     '' unlock our page.
   ScreenUnlock

Differences from QB
   * In QB, SetEnviron was called Environ.

See also
   * Environ
   * Shell



---------------------------------------------------------- KeyPgEnviron ----
Environ

Returns the value of a system environment variable

Syntax
   Declare Function Environ ( ByRef varname As Const String ) As String

Usage
   result = Environ( varname )

Parameters
   varname
      The name of an environment variable.

Return Value
   Returns the text value of the environmental variable, or the empty 
   string ("") if the variable does not exist.

Description
   Environ returns the text value of a system environment variable.

Example
   'e.g. to show the system variable "path":

   Print Environ("path")

Differences from QB
   * The Environ statement is now called SetEnviron.

See also
   * SetEnviron
   * Shell



-------------------------------------------------------------- KeyPgEof ----
EOF

Checks to see if the end of an open file has been reached

Syntax
   Declare Function EOF ( ByVal filenum As Long ) As Long

Usage
   result = EOF( filenum )

Parameters
   filenum
      File number of an open file.

Return Value
   Returns true (-1) if end-of-file has been reached, zero (0) otherwise.

Description
   When reading from files opened for Input (File Mode), it is useful to 
   know when the end of the file has been reached, thus avoiding errors 
   caused by reading past the ends of files. Use EOF to determine this. EOF 
   expects a valid file number from an already opened file. Use FreeFile to 
   retrieve an available file file number.

   For file numbers bound to files opened for Output, EOF always returns 0.

Example
   '' This code finds a free file number to use and attempts to open the file
   '' "file.ext" and if successful, binds our file number to the opened file. It
   '' reads the file line by line, outputting it to the screen. We loop until eof()
   '' returns true, in this case we ignore the loop if file is empty.

   Dim As String file_name
   Dim As Integer file_num

   file_name = "file.ext"
   file_num = FreeFile( )                 '' retrieve an available file number

   '' open our file and bind our file number to it, exit on error
   If( Open( file_name For Input As #file_num ) ) Then
      Print "ERROR: opening file " ; file_name
      End -1
   End If

   Do Until EOF( file_num )               '' loop until we have reached the end of the file
      Dim As String text
      Line Input #file_num, text               '' read a line of text ...
      Print text                             '' ... and output it to the screen
   Loop

   Close #file_num                        '' close file via our file number

   End 0

Differences from QB
   * In QB the comm port signaled an EOF when there were no chars waiting 
     to be read.
   * In QB, for files opened in RANDOM or BINARY mode, EOF returned 
     non-zero only after a read past the end of file has been attempted.  
     In FreeBASIC, EOF returns true after the last item is read.

See also
   * LOF
   * LOC
   * FreeFile



------------------------------------------------------------ KeyPgOpEqv ----
Operator Eqv (Equivalence)

Returns the bitwise-and (equivalence) of two numeric values

Syntax
   Declare Operator Eqv ( ByRef lhs As T1, ByRef rhs As T2 ) As Ret

Usage
   result = lhs Eqv rhs

Parameters
   lhs
      The left-hand side expression.
   T1
      Any numeric or boolean type.
   rhs
      The right-hand side expression.
   T2
      Any numeric or boolean type.
   Ret
      A numeric or boolean type (varies with T1 and T2).

Return Value
   Returns the bitwise-equivalence of the two operands.

Description
   This operator returns the bitwise-equivalence of its operands, a logical 
   operation that results in a value with bits set depending on the bits of 
   the operands (for conversion of a boolean to an integer, false or true 
   boolean value becomes 0 or -1 integer value).

   The truth table below demonstrates all combinations of a 
   boolean-equivalence operation:

      +-------+-------+------+
      |Lhs Bit|Rhs Bit|Result|
      |0      |0      |1     |
      |1      |0      |0     |
      |0      |1      |0     |
      |1      |1      |1     |
      +-------+-------+------+

   No short-circuiting is performed - both expressions are always 
   evaluated.

   The return type depends on the types of values passed. Byte, UByte and 
   floating-point type values are first converted to Integer. If the left 
   and right-hand side types differ only in signedness, then the return 
   type is the same as the left-hand side type (T1), otherwise, the larger 
   of the two types is returned. Only if the left and right-hand side types 
   are both Boolean, the return type is also Boolean.

   This operator can be overloaded for user-defined types.

Example
   Dim As UByte a = &b00110011
   Dim As UByte b = &b01010101, c
   c = a Eqv b '' c = &b10011001

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * None

See also
   * Operator Truth Tables



------------------------------------------------------------ KeyPgErase ----
Erase

Statement to erase arrays

Syntax
   Declare Sub Erase ( array As Any [, ... ] )

Usage
   Erase( array0 [, array1 ... arrayN ] )

Parameters
   array
      An array to be erased.

Description
   Using Erase on a fixed-length array resets all elements without freeing 
   the allocated memory.
   In case of objects, there is destruction then re-construction.

   Using Erase on a variable-length array (array already sized) frees the 
   memory allocated for the array elements, but the array remains declared 
   at its same scope level (with the same datatype and number of 
   dimensions).
   In case of objects, there is destruction before freeing memory.

   Note: Erase can not be used on fixed-size arrays passed as parameters in 
   a procedure. FreeBASIC can not prevent you from trying this at 
   compile-time, but the results at run-time will be undefined (up to 
   crashing).

Example
   Dim MyArray1(1 To 10) As Integer
   ReDim MyArray2(1 To 10) As Integer 

   Erase MyArray1, MyArray2

Differences from QB
   * None

See also
   * Common
   * Dim
   * Extern
   * LBound
   * ReDim
   * Static
   * UBound
   * Var



------------------------------------------------------------- KeyPgErfn ----
Erfn

Error reporting function

Syntax
   Declare Function Erfn ( ) As ZString Ptr

Usage
   result = Erfn ( ) 

Return Value
   Returns a pointer to the string identifying the function where the error 
   occurred.

   Returns NULL if the source is not compiled with the -exx compiler 
   option.

Description
   An error reporting function returning a pointer to the name of the 
   function.

Example
   '' test.bas
   '' compile with fbc -exx -lang fblite test.bas

   #lang "fblite"

   Sub Generate_Error
     On Error Goto Handler
     Error 1000
     Exit Sub
   Handler:
     Print "Error Function: "; *Erfn()
     Print "Error Module  : "; *Ermn()
     Resume Next
   End Sub

   Generate_Error

Output:
   Error Function: GENERATE_ERROR
   Error Module  : test.bas

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Erfn.

Differences from QB
   * New to FreeBASIC

See also 
   * Erl
   * Ermn
   * On...Error



-------------------------------------------------------------- KeyPgErl ----
Erl

Error handling function to return the line where the error occurred

Syntax
   Declare Function Erl ( ) As Integer

Usage
   result = Erl

Return Value
   An Integer return value containing the line number where the last error 
   occurred.

Description
   Erl will return the line number where the last error occurred. If no 
   error has occurred, Erl will return 0.

   Erl cannot always be used effectively -- QB-like error handling must be 
   enabled.

   Erl is reset by RESUME and RESUME NEXT

Example

   ' compile with -lang fblite or qb

   #lang "fblite"

   ' note: compilation with '-ex' option is required

   On Error Goto ErrorHandler

   ' Generate an explicit error
   Error 100

   End

   ErrorHandler:
     Dim num As Integer = Err
     Print "Error "; num; " on line "; Erl
     Resume Next

   ' Expected output is
   ' Error  100 on line  6

Differences from QB
   * FreeBASIC returns the source code line number and ignores the values 
     of all explicit line numbers, where as QB returns the last encountered 
     explicit line number, and will return zero (0) when explicit line 
     numbers are not used.

See also
   * Error Handling
   * Err



------------------------------------------------------------- KeyPgErmn ----
Ermn

Error reporting function

Syntax
   Declare Function Ermn ( ) As ZString Ptr

Usage
   result = Ermn ( ) 

Return Value
   Returns a pointer to the string identifying the module where the error 
   occurred.

   Returns NULL if the source is not compiled with the -exx compiler 
   option.

Description
   An error reporting function returning a pointer to the name of the 
   module.

Example
   '' test.bas
   '' compile with fbc -exx -lang fblite test.bas

   #lang "fblite"

   Sub Generate_Error
     On Error Goto Handler
     Error 1000
     Exit Sub
   Handler:
     Print "Error Function: "; *Erfn()
     Print "Error Module  : "; *Ermn()
     Resume Next
   End Sub

   Generate_Error

Output:
   Error Function: GENERATE_ERROR
   Error Module  : test.bas

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Ermn.

Differences from QB
   * New to FreeBASIC

See also 
   * Erfn
   * Erl
   * On...Error



-------------------------------------------------------------- KeyPgErr ----
Err

Get or set the run-time error number

Usage
   result = Err( )
      or
   Err = number

Description
   The Err() function returns the FreeBASIC run-time error number (a 32 bit 
   Long) which can be set by the built-in statements and functions, or by 
   the program through Err = number or Error. Unlike Error, Err = number 
   sets the error number without invoking an error handler.

   See Runtime Error Codes for a listing of the predefined runtime error 
   numbers and their associated meaning. The program may use additional 
   custom error numbers.

   Err can always be used, even if QB-like error handling is not enabled. 
   Err is reset by Resume and Resume Next.

   Note: Care should be taken when calling an internal function (such as 
   Print) after an error occurred, because it will reset the error value 
   with its own error status. To preserve the Err value, it is a good idea 
   to store it in a variable as soon as the error handler is entered.

   Remark: Some procedures used in their function version return directly 
   the error code (a 32 bit Long).
   That is the case for: BLoad, BSave, Close, FileCopy, GetJoystick, 
   GetMouse, ImageInfo, Kill, Open, Open Com, Open Cons, Open Err, Open Lpt
   , Open Pipe, Open Scrn, ScreenRes, ScreenSync, SetDate, SetMouse, SetTime
   .

Example
An example using QBasic style error handling (compile with -ex option)
   '' Compile with -lang fblite or qb

   #lang "fblite"

   On Error Goto Error_Handler
   Error 150
   End

   Error_Handler:
     n = Err()
     Print "Error #"; n
     Resume Next

An example using inline error handling (note: Open can also return its own 
error status when called as a function)
   '' compile without -e switch

   Dim filename As String

   Do
      Line Input "Input filename: ", filename
      If filename = "" Then End
      Open filename For Input As #1
   Loop Until Err() = 0

   Print Using "File '&' opened successfully"; filename
   Close #1

Differences from QB
   * Error numbers are not the same as in QB.

See also
   * On Error
   * Error
   * Error Handling
   * Runtime Error Codes



------------------------------------------------------------ KeyPgError ----
Error

Error handling statement to force an error to be generated

Syntax
   Declare Sub Error ( errno As Integer )

Usage
   Error number

Parameters
   number
      The error number to generate

Description
   Error invokes the error handler specified with On Error or, in case 
   there was none set, aborts the program, printing an error message 
   similar to those generated by the compiler's -exx run-time error 
   checking. It's possible to use the built-in run-time error numbers 
   and/or other custom error numbers for number. This can be used to 
   simulate custom error numbers.

Example
   To send an error alert of error 150 (just some arbitrary error code) one 
   would do the following:
   Error 150

Differences from QB
   * Error numbers are not the same as in QB.

See also
   * Err
   * Error Handling
   * Runtime Error Codes



------------------------------------------------------------ KeyPgEvent ----
Event (Message Data From Screenevent)

Pre-defined structure (UDT) from fbgfx.bi used by ScreenEvent to return 
event data 

Syntax
   #include once "fbgfx.bi"
   using fb
   Dim variable As Event

Description
   Here we report the EVENT structure for clarity:

   Type Event Field = 1
      Type As Long
      Union
         Type
            scancode As Long
            ascii As Long
         End Type
         Type
            x As Long
            y As Long
            dx As Long
            dy As Long
         End Type
         button As Long
         z As Long
         w As Long
      End Union
   End Type

   The Type field will contain the event type ID, while the remaining 4 
   integers will hold sensitive data to the event type. 

   Event types
      The event type is identified by an ID number returned into the first 
      integer of the event buffer (the .type field in the EVENT structure). 
      Known event type IDs - and their values at time of writing - are:

      * EVENT_KEY_PRESS (1) A key was pressed on the keyboard. The 
        .scancode field contains the platform independent scancode value 
        for the key; if the key has an ascii representation, it is held 
        into the .ascii field, which otherwise has a value of 0.
      * EVENT_KEY_RELEASE (2) A key was released on the keyboard. The 
        .scancode and .ascii fields have the same meaning as with the 
        EVENT_KEY_PRESS event.
      * EVENT_KEY_REPEAT (3) A key is being held down repeatedly. The 
        .scancode and .ascii fields have the same meaning as with the 
        EVENT_KEY_PRESS event.
      * EVENT_MOUSE_MOVE (4) The mouse was moved while it was on the 
        program window. The .x and .y fields contain the new mouse position 
        relative to the upper-left corner of the screen, while the .dx and 
        .dy fields contain the motion deltas.
      * EVENT_MOUSE_BUTTON_PRESS (5) One of the mouse buttons was pressed. 
        The .button field has one bit set identifying the button that was 
        pressed; bit 0 identifies the left mouse button, bit 1 the right 
        mouse button and bit 2 the middle mouse button.
      * EVENT_MOUSE_BUTTON_RELEASE (6) One of the mouse buttons was 
        released. The .button field has the same meaning as with the 
        EVENT_MOUSE_BUTTON_PRESS event.
      * EVENT_MOUSE_DOUBLE_CLICK (7)  One of the mouse buttons was double 
        clicked. The .button field has the same meaning as with the 
        EVENT_MOUSE_BUTTON_PRESS event.
      * EVENT_MOUSE_WHEEL (8) The mouse wheel was used; the new wheel 
        position is returned into the .z field.
      * EVENT_MOUSE_ENTER (9) The mouse was moved into the program window.
      * EVENT_MOUSE_EXIT (10) The mouse was moved out of the program 
        window.
      * EVENT_WINDOW_GOT_FOCUS (11) The program window has got focus.
      * EVENT_WINDOW_LOST_FOCUS (12) The program window has lost focus.
      * EVENT_WINDOW_CLOSE (13) The user attempted to close the program 
        window.
      * EVENT_MOUSE_HWHEEL (14) The horizontal mouse wheel was used; the 
        new horizontal wheel position is returned into the .w field.

   The fbgfx.bi header file contains a definition of the EVENT user data 
   type, so it is not necessary to declare it manually.

Dialect Differences
   * In lang fb, the structure and constants are stored in the FB Namespace
     . This is not the case in other dialects.

Differences from QB
   * New to FreeBASIC

See also
   * ScreenEvent



------------------------------------------------------------- KeyPgExec ----
Exec

Temporarily transfers execution to an external program

Syntax
   Declare Function Exec ( ByRef program As Const String, ByRef arguments As
   Const String ) As Long

Usage
   result = Exec( program, arguments )

Parameters
   program
      The file name (including file path) of the program (executable) to 
      transfer control to.
   arguments
      The command-line arguments to be passed to the program.

Return Value
   The exit status of the program, or negative one (-1) if the program 
   could not be executed.

Description
   Transfers control over to an external program. When the program exits, 
   execution resumes immediately after the call to Exec.

Example
   'A Windows based example but the same idea applies to Linux
   Const exename = "NoSuchProgram.exe"
   Const cmdline = "arg1 arg2 arg3"
   Dim result As Integer
   result = Exec( exename, cmdline )
   If result = -1 Then
      Print "Error running "; exename
   Else
      Print "Exit code:"; result
   End If

Platform Differences
   * Linux requires the program case matches the real name of the file. 
     Windows and DOS  are case insensitive. The program being executed may 
     be case sensitive for its command line parameters.
   * Path separators in Linux are forward slashes / . Windows uses 
     backward slashes \ but it allows for forward slashes .  DOS uses 
     backward  \ slashes. 
   * Exit code is limited to 8 bits in DOS.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Exec.

Differences from QB
   * New to FreeBASIC

See also
   * Chain transfer temporarily, without arguments
   * Run one-way transfer
   * Command pick arguments



---------------------------------------------------------- KeyPgExepath ----
ExePath

Returns the path of the running program

Syntax
   Declare Function ExePath ( ) As String

Usage
   result = ExePath

Return Value
   A String variable set to the path of the running program.

Description
   Returns the path (the location) of the calling program. This is not 
   necessarily the same as CurDir.

Example
   Dim pathname As String = ExePath
   Print "This program's initial directory is: " & pathname

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Exepath.

Differences from QB
   * New to FreeBASIC

See also
   * CurDir



------------------------------------------------------------- KeyPgExit ----
Exit

Control flow statement to exit a compound statement block

Syntax
   Exit {Do | For | While | Select }
   Exit {Sub | Function | Operator | Constructor | Destructor | Property }

   Exit {Do [, Do [ , ...] ] |
         For [, For [ , ...] ] | 
         While [, While, [...] ] | 
         Select [, Select [ , ...] ] }

Description
   Leaves a code block such as a Sub, Function, Operator, Constructor, 
   Destructor, Property, Do...Loop, For...Next, While...Wend, or a  
   Select Case block. The execution skips the rest of the block and goes to 
   the line after its end.

   Where there are multiple Do / For / While / Select blocks nested, it 
   will skip to the end of the innermost block of that type.  You can skip 
   to the end of multiple blocks of that type by giving the word multiple 
   times, separated by commas.
   For example: Exit While, While

Example
   'e.g. the print command will not be seen

   Do
      Exit Do ' Exit the Do...Loop and continues to run the code after Loop
      Print "I will never be shown"
   Loop

   Dim As Integer i, j
   For i = 1 To 10
      
      For j = 1 To 10
         
         Exit For, For
         
      Next j
      
      Print "I will never be shown"
      
   Next i

Differences from QB
   * EXIT OPERATOR, EXIT CONSTRUCTOR, EXIT DESTRUCTOR, EXIT PROPERTY, EXIT 
     WHILE and EXIT SELECT are new to FreeBASIC.

See also
   * Sub
   * Function
   * Do...Loop
   * For...Next
   * While...Wend
   * Continue



-------------------------------------------------------------- KeyPgExp ----
Exp

Returns e raised to the power of a given number

Syntax
   Declare Function Exp cdecl ( ByVal number As Double ) As Double

Usage
   result = Exp( number )

Parameters
   number
      The Double number that e is raised to the power of.

Return Value
   Returns the Double value of e raised to power of number.

Description
   The mathematical constant e, also called Euler's constant, is the base 
   of the Exp and Log and is an irrational and transcendental number. The 
   value of e to twenty significant figures is: 2.7182818284590452354. The 
   required number argument can be any valid numeric expression within 
   range of the function. If number is too large, Exp returns infinity.  If 
   number is too small, Exp returns zero (0.0).  If number is zero, 1.0 is 
   returned. The exact limit on number is based on the math processor.

   Exp can be overloaded as operator to accept user-defined types.

Example
   'Compute Continuous Compound Interest
   Dim r As Double
   Dim p As Double
   Dim t As Double
   Dim a As Double

   Input "Please enter the initial investment (principal amount): "; p
   Input "Please enter the annual interest rate (as a decimal): "; r
   Input "Please enter the number of years to invest: "; t

   a = p * Exp ( r * t )
   Print ""
   Print "After";t;" years, at an interest rate of"; r * 100; "%, your initial investment of"; p; " would be worth";a

The output would look like:

   Please enter the initial investment (principal amount): 100
   Please enter the annual interest rate (As a decimal): .08
   Please enter the number of years To invest: 20
   After 20 years, at an interest rate of 8%, your initial investment of 100 would be worth 495.3032424395115

Differences from QB
   * None

See also
   * Log
   * Operator ^ (Exponentiate)



----------------------------------------------------------- KeyPgExport ----
Export

Declaration specifier to indicate that a procedure in a DLL should be 
visible from other programs

Syntax
   { Sub | Function } proc_name ( argumentlist ) [ [ ByRef ] As datatype ] 
   Export

Description
   If a function is declared with this clause in a DLL, it is added to the 
   public export table, so external programs can dynamically link to it 
   using DyLibSymbol.
   (specifier to be put at procedure definition level, forbidden at 
   procedure declaration line level)

Example
   See the examples on the Shared Libraries page.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Export.

Platform Differences
   * Dynamic link libraries are not available in DOS, as the OS doesn't 
     support them.

Differences from QB
   * New to Freebasic

See also
   * DyLibLoad
   * DyLibSymbol
   * Alias



---------------------------------------------------------- KeyPgExtends ----
Extends

Specifies a base type from which to derive a new type

Syntax
   Type|Union typename Extends base_typename
      ...
   End Type|Union

Description
   Extends declares typename to be derived from base_typename. The derived 
   user-defined type, typename, inherits fields and methods of the 
   base_typename base type. typename objects may be used in place of 
   base_typename objects. Fields and methods inherited from base_typename 
   will be implicitly accessible like members of typename.
   However, a member will shadow an inherited member if they have the same 
   identifier. The Base (Member Access) keyword can be used to explicitly 
   access members of the base type shadowed by local members.

   User-defined types that extend another type will include the base type 
   structure at their beginning, and their size as reported by Sizeof() is 
   the sum of their base type's size plus the size needed for any regular 
   data fields (non-static data fields). Since the inherited members make 
   sure that the structure is not empty, a derived type is not required to 
   have regular data fields of its own.

   In typename (the derived user-defined type), the fields can share the 
   same memory space than the base_typename only if typename is a Union. 
   Here it does not matter whether base_typename is a Union or not.
   If only base_typename is a Union, then it will not be affected by fields 
   from typename (the derived user-defined type).
   As a Union is not allowed to have complex fields (i.e. user-defined 
   types with constructor/destructor, or dynamic strings), a derived Union 
   cannot be allowed to have (contain) a complex base_typename.

   The Base (Initializer) keyword can be used at the top of constructor of 
   derived user-defined type. It allows to specify an initializer or 
   constructor call for the base type.

   Extending the built-in Object type allows a user-defined type to be used 
   with Operator Is to perform run-time type checks, to support Virtual and 
   Abstract methods, and to use the Override method attribute.

    Note: UDT pointer can only be cast to pointer types of "widened 
   compatibility" (up or even down in the inheritance hierarchy), or to Any 
   Ptr. Otherwise, cast to Any Ptr first (or to Object Ptr first if both 
   types are directly or indirectly derived from Object).

Example
   Type SchoolMember 'Represents any school member'
      Declare Constructor ()
      Declare Sub Init (ByRef _name As String, ByVal _age As Integer)
      As String Name
      As Integer age
   End Type

   Constructor SchoolMember ()
      Print "Initialized SchoolMember"
   End Constructor

   Sub SchoolMember.Init (ByRef _name As String, ByVal _age As Integer)
      This.name = _name
      This.age = _age
      Print "Name: "; This.name; "   Age:"; This.age
   End Sub

   Type Teacher Extends SchoolMember 'Represents a teacher derived from SchoolMember'
      Declare Constructor (ByRef _name As String, ByVal _age As Integer, ByVal _salary As Integer)
      As Integer salary
      Declare Sub Tell ()
   End Type

   Constructor Teacher (ByRef _name As String, ByVal _age As Integer, ByVal _salary As Integer)
      Print "Initialized Teacher"
      This.Init(_name, _age) 'implicit access to base member procedure'
      This.salary = _salary
   End Constructor

   Sub Teacher.Tell ()
      Print "Salary:"; This.salary
   End Sub

   Type Student Extends SchoolMember 'Represents a student derived from SchoolMember'
      Declare Constructor (ByRef _name As String, ByVal _age As Integer, ByVal _marks As Integer)
      As Integer marks
      Declare Sub Tell ()
   End Type

   Constructor Student (ByRef _name As String, ByVal _age As Integer, ByVal _marks As Integer)
      Print "Initialized Student"
      This.Init(_name, _age) 'implicit access to base member procedure'
      This.marks = _marks
   End Constructor
      
   Sub Student.Tell ()
      Print "Marks:"; This.marks
   End Sub

   Dim As Teacher t = Teacher("Mrs. Shrividya", 40, 30000)
   t.Tell()
   Print
   Dim As Student s = Student("Swaroop", 22, 75)
   s.Tell()

   ' Example using all eight keywords of inheritance:
   '   'Extends', 'Base.', 'Base()', 'Object', 'Is' operator, 'Virtual', 'Abstract', 'Override'

   Type root Extends Object ' 'Extends' to activate RTTI by inheritance of predefined Object type
     Declare Function ObjectHierarchy () As String
     Declare Abstract Function ObjectRealType () As String ' 'Abstract' declares function without local body
                                             '    which must be overriden
     Dim Name As String
     Declare Virtual Destructor () ' 'Virtual' declares destructor with body ('Abstract' forbidden)
   Protected:
     Declare Constructor () ' to avoid user construction from root
     Declare Constructor (ByRef rhs As root) '' to avoid user copy-construction from root
   End Type ' derived type may be member data empty

   Constructor root ()
   End Constructor

   Function root.ObjectHierarchy () As String
     Return "Object(forRTTI) <- root"
   End Function

   Virtual Destructor root ()
     Print "root destructor"
   End Destructor

   Type animal Extends root ' 'Extends' to inherit of root
     Declare Constructor (ByRef _name As String = "")
     Declare Function ObjectHierarchy () As String
     Declare Virtual Function ObjectRealType () As String Override ' 'Virtual' declares function with local
                                                   '    body which can be overriden
                                                   ' 'Override' to check if the function is
                                                   '    well an override
     Declare Virtual Destructor () Override ' 'Virtual' declares destructor with local body
                                  ' 'Override' to check if the destructor is well an override
   End Type

   Constructor animal (ByRef _name As String = "")
     This.name = _name
   End Constructor

   Function animal.ObjectHierarchy () As String
     Return Base.ObjectHierarchy & " <- animal" ' 'Base.' allows to access to parent member function
   End Function

   Virtual Function animal.ObjectRealType () As String
     Return "animal"
   End Function

   Virtual Destructor animal ()
     Print "  animal destructor: " & This.name
   End Destructor

   Type dog Extends animal ' 'Extends' to inherit of animal
     Declare Constructor (ByRef _name As String = "")
     Declare Function ObjectHierarchy () As String
     Declare Function ObjectRealType () As String Override ' 'Override' to check if the function is well an
                                             '    override
     Declare Destructor () Override ' 'Override' to check if the destructor is well an override
   End Type ' derived type may be member data empty

   Constructor dog (ByRef _name As String = "")
     Base(_name) ' 'Base()' allows to call parent constructor
   End Constructor

   Function dog.ObjectHierarchy () As String
     Return Base.ObjectHierarchy & " <- dog" ' 'Base.' allows to access to parent member function
   End Function

   Function dog.ObjectRealType () As String
     Return "dog"
   End Function

   Destructor dog ()
     Print "    dog destructor: " & This.name
   End Destructor

   Type cat Extends animal ' 'Extends' to inherit of animal
     Declare Constructor (ByRef _name As String = "")
     Declare Function ObjectHierarchy () As String
     Declare Function ObjectRealType () As String Override ' 'Override' to check if the function is well an
                                             '    override
     Declare Destructor () Override ' 'Override' to check if the destructor is well an override
   End Type ' derived type may be member data empty

   Constructor cat (ByRef _name As String = "")
     Base(_name) ' 'Base()' allows to call parent constructor
   End Constructor

   Function cat.ObjectHierarchy () As String
     Return Base.ObjectHierarchy & " <- cat" ' 'Base.' allows to access to parent member function
   End Function

   Function cat.ObjectRealType () As String
     Return "cat"
   End Function

   Destructor cat ()
     Print "    cat destructor: " & This.name
   End Destructor

   Sub PrintInfo (ByVal p As root Ptr) ' must be put after definition of animal type, dog type and cat type
     Print "  " & p->Name, "  " & p->ObjectRealType, "           ";
     If *p Is dog Then ' 'Is' allows to check compatibility with type symbol
      Print  Cast(dog Ptr, p)->ObjectHierarchy
     ElseIf *p Is cat Then ' 'Is' allows to check compatibility with type symbol
      Print Cast(cat Ptr, p)->ObjectHierarchy
     ElseIf *p Is animal Then ' 'Is' allows to check compatibility with type symbol
      Print Cast(animal Ptr, p)->ObjectHierarchy
     End If
   End Sub

   Print "Name:", "Object (real):         Hierarchy:"
   Dim a As root Ptr = New animal("Mouse")
   PrintInfo(a)
   Dim d As root Ptr = New dog("Buddy")
   PrintInfo(d)
   Dim c As root Ptr = New cat("Tiger")
   Printinfo(c)
   Print
   Delete a
   Delete d
   Delete c

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Extends.

Differences from QB
   * New to FreeBASIC

See also
   * Type
   * Union
   * Base (Initializer)
   * Base (Member Access)
   * Object
   * Operator Is
   * Virtual
   * Abstract
   * Override
   * Extends Zstring
   * Extends Wstring



--------------------------------------------------- KeyPgExtendsWstring ----
Extends Wstring

Specifies a type which inherits a Wstring behavior

Syntax
   Type|Union typename Extends Wstring [, base_typename]
      ...
   End Type|Union

Description
   Extends Wstring declares typename to inherit properties and behaviors of 
   a WString. Purpose is to allow users to create custom string types (with 
   i.e. dynamic memory management) that can integrate well in to existing 
   fbc compiler built ins (good interoperability with fbc's WString type).

   This declaration of such a UDT with a suitable Cast operator will 
   instruct compiler to convert the UDT to a WString (in addition, other 
   suitable operators as Let, [] (Pointer Index), Len, ..., can be also 
   declared).

   WString behaviour can be inherited directly, or indirectly and singly 
   from a base-type.
   WString behaviour can be inherited by a UDT also extending base_typename 
   (a kind of pseudo multiple-inheritance).

   Note: By declaring a type (directly or indirectly) as Extends Wstring 
   (in addition to defining a suitable Cast operator only), this promotes 
   it fully compatible even with StrPtr/SAdd, LSet/RSet, and Select Case, 
   but currently not yet with the built in functions Val/ValInt/ValLng/
   ValUInt/Valunlg and Left/Right.

Example
   See Extends Zstring for similar examples.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Extends __Wstring, but unusable because no member procedure is 
     allowed in this dialect.

Differences from QB
   * New to FreeBASIC

See also
   * Type
   * Union
   * Extends
   * WString
   * Extends Zstring



--------------------------------------------------- KeyPgExtendsZstring ----
Extends Zstring

Specifies a type which inherits a Zstring behavior

Syntax
   Type|Union typename Extends Zstring [, base_typename]
      ...
   End Type|Union

Description
   Extends Zstring declares typename to inherit properties and behaviors of 
   a ZString. Purpose is to allow users to create custom string types (with 
   i.e. dynamic memory management) that can integrate well in to existing 
   fbc compiler built ins (good interoperability with fbc's ZString type).

   This declaration of such a UDT with a suitable Cast operator will 
   instruct compiler to convert the UDT to a ZString (in addition, other 
   suitable operators as Let, [] (Pointer Index), Len, ..., can be also 
   declared).

   ZString behaviour can be inherited directly, or indirectly and singly 
   from a base-type.
   ZString behaviour can be inherited by a UDT also extending base_typename 
   (a kind of pseudo multiple-inheritance).

   Note: By declaring a type (directly or indirectly) as Extends Zstring 
   (in addition to defining a suitable Cast operator only), this promotes 
   it fully compatible even with StrPtr/SAdd, LSet/RSet, and Select Case, 
   but currently not yet with the built in functions Val/ValInt/ValLng/
   ValUInt/Valunlg and Left/Right.

Example
   Type myZstring Extends ZString
     Public:
      Declare Constructor (ByRef z As Const ZString = "")
      Declare Operator Cast () ByRef As Const ZString
      Declare Operator Let (ByRef z As Const ZString)
     Private:
      Dim As String s
   End Type

   Constructor myZstring (ByRef z As Const ZString = "")
     This.s = z
   End Constructor

   Operator myZstring.Cast () ByRef As Const ZString
     Return *StrPtr(This.s)
   End Operator

   Operator myZstring.Let (ByRef z As Const ZString)
     This.s = z
   End Operator

   Dim As myZstring z = "FreeBASIC"
   Print "'" & z & "'"

   z &= " compiler"
   Print "'" & z & "'"

   Sleep

   Type vZstring Extends ZString
     Public:
      Declare Constructor (ByVal pz As Const ZString Ptr = 0)
      Declare Operator Cast () ByRef As ZString
      Declare Operator Let (ByVal pz As Const ZString Ptr)
      Declare Operator [] (ByVal index As Integer) ByRef As UByte
      Declare Destructor ()
     Private:
      Dim As ZString Ptr p
      Dim As UInteger l
   End Type

   Constructor vZstring (ByVal pz As Const ZString Ptr = 0)
     This.l = Len(*pz)
     This.p = CAllocate(This.l + 1, SizeOf(ZString))
     *This.p = *pz
   End Constructor

   Operator vZstring.Cast () ByRef As ZString
     Return *This.p
   End Operator

   Operator vZstring.Let (ByVal pz As Const ZString Ptr)
     If This.l < Len(*pz) Then
      Deallocate(This.p)
      This.l = Len(*pz)
      This.p = CAllocate(This.l + 1, SizeOf(ZString))
     End If
     *This.p = *pz
   End Operator

   Operator vZstring.[] (ByVal index As Integer) ByRef As UByte
     Return This.p[index]
   End Operator

   Destructor vZstring ()
     Deallocate(This.p)
   End Destructor

   Operator Len (ByRef v As vZstring) As Integer
     Return Len(Type<String>(v))        '' found nothing better than this ('vZstring.l' being private)
   End Operator                         ''     (or: 'Return Len(Str(v))')

   Dim As vZstring v = "FreeBASIC"
   Print "'" & v & "'", Len(v)

   Dim As ZString * 256 z
   z = *StrPtr(v)                       '' 'error 24: Invalid data types' without 'Extends Zstring'
   Print "'" & z & "'", Len(z)

   v &= Space(2)
   Print "'" & v & "'", Len(v)
   RSet v, "FreeBASIC"                  '' 'error 24: Invalid data types' without 'Extends Zstring'
   Print "'" & v & "'", Len(v)          ''     ('Cast' must return a modifiable reference)

   Select Case v                        '' 'error 24: Invalid data types' without 'Extends Zstring'
   Case Type<vZstring>(Trim(v) & "  ")
     Print "Left justified"
   Case Type<vZstring>("  " & Trim(v))
     Print "Right justified"
   End Select

   v[0] = Asc("-")
   Print "'" & v & "'", Len(v)

   'Print "'" & Right(v, 5) & "'"      '' 'Right' does not yet support types with 'Extends Zstring'
   Print "'" & Right(Str(v), 5) & "'"  '' workaround (or: 'Right(Type<String>(v), 5)')

   Sleep

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Extends __Zstring, but unusable because no member procedure is 
     allowed in this dialect.

Differences from QB
   * New to FreeBASIC

See also
   * Type
   * Union
   * Extends
   * ZString
   * Extends Wstring



----------------------------------------------------------- KeyPgExtern ----
Extern

Declares a variable, array or object having external linkage

Syntax
   Extern [ Import ] symbolname[ (subscripts) ] [ Alias "aliasname" ] As 
   DataType [, ...]

Parameters
   symbolname
      The name of the variable, array or object.
   aliasname
      An alternate external name for the variable, array or object.

Description
   Declares symbolname as an external name, meaning it is global to 
   external modules. Extern only declares variables, arrays and objects, 
   and does not define them (different from Common or Dim). It also has the 
   effect of making symbolname a shared name, meaning it is visible within 
   procedures (see Shared). A symbolname declared as external name can be 
   (re)defined (using Dim or Redim) only in a single external module.

   If Alias is used, aliasname will be used as the external name rather 
   than symbolname, and its case will be preserved.

   If Import is used, the name will be added to the dynamic library import 
   list so its address can be fixed at run-time.

Example
   '' extern1.bas

   Extern Foo Alias "foo" As Integer

   Sub SetFoo
      foo = 1234
   End Sub

   '' extern2.bas

   Declare Sub SetFoo

   Extern Foo Alias "foo" As Integer

   Dim foo As Integer = 0

   SetFoo

   Print Foo

Output:

    1234

Dialect Differences
   * Not available in the -lang qb dialect.

Differences from QB
   * New to FreeBASIC

See also
   * Extern...End Extern
   * Common
   * Dim
   * Shared
   * Alias (Name)
   * Alias (Modifier)



------------------------------------------------------ KeyPgExternBlock ----
Extern...End Extern

Statement block to allow calling of functions compiled for specific 
languages or platforms.

Syntax
   Extern { "C" | "C++" | "Windows" | "Windows-MS" } [ Lib "libname" ]
      declarative statements
   End Extern

Description
   Extern blocks provide default calling conventions for procedures and 
   mandate a certain name decoration.

   Extern "C" blocks provide a default cdecl calling convention to 
   procedures, and also preserve the case of all names declared within 
   them. The same effect can be achieved without the EXTERN block by using 
   cdecl together with an Alias string containing the exact procedure name.

   Extern "C++" blocks are exactly like Extern "C" blocks but they also 
   mangle the names declared within them in a way compatible to that of g++
   -4.x.

   Extern "Windows" blocks provide a default stdcall calling convention to 
   procedures, preserve the case of all names declared within them, and on 
   the Windows platform, append an "@N" suffix to procedure names, where N 
   is the total size in bytes of any procedure parameters. Similar to the 
   Extern "C" block, the same effect can be achieved by using stdcall and 
   Alias.

   Extern "Windows-MS" blocks are exactly like Extern "Windows" blocks but 
   do not append the "@N" suffix to procedure names on Windows.

   Lib "libname" can be used to specify a library which will be linked in 
   as if #Inclib "Libname" or -l libname had been used. Additionally, all 
   procedure declarations inside the Extern block will use the specified Lib
   "libname" as if it was specified as part of their declarations (but it 
   can still be overridden with an explicit Lib "libname").

Example
   '' This procedure uses the default calling convention for the system, which is
   '' STDCALL on Win32 and CDECL on Linux/DOS/*BSD, and is seen externally as
   '' "MYTEST1@4" on Win32 and "MYTEST1" on Linux/DOS/*BSD (following FB's default
   '' ALL-UPPER-CASE name mangling).
   Sub MyTest1 ( ByVal i As Integer )
   End Sub

   Extern "C"
      '' This procedure uses the CDECL convention and is seen externally
      '' as "MyTest2".
      Sub MyTest2 ( ByVal i As Integer )
      End Sub
   End Extern

   Extern "C++"
      '' This procedure uses the CDECL convention and its name is mangled
      '' compatible to g++-4.x, specifically: "_Z7MyTest3i"
      Sub MyTest3 ( ByVal i As Integer )
      End Sub
   End Extern

   Extern "Windows"
      '' This procedure uses the STDCALL convention and is seen externally
      '' as "MyTest4@4" on Windows, and "MyTest4" on Linux, *BSD and DOS.
      Sub MyTest4 ( ByVal i As Integer )
      End Sub
   End Extern

   Extern "Windows-MS"
      '' This procedure uses the STDCALL convention and is seen externally
      '' as "MyTest5".
      Sub MyTest5 ( ByVal i As Integer )
      End Sub
   End Extern

   MyTest1( 0 )
   MyTest2( 0 )
   MyTest3( 0 )
   MyTest4( 0 )

Dialect Differences
   * Extern blocks are only available in the -lang fb dialect.

Differences from QB
   * New to FreeBASIC

Platform Differences
   * On Linux, *BSD and DOS platforms, Extern "Windows" blocks never 
     append a "@N" suffix to procedure names, and thus are equal to Extern 
     "Windows-MS".

See also
   * cdecl
   * stdcall
   * Extern




============================================================================
    F

------------------------------------------------------------ KeyPgFalse ----
False

Intrinsic constant set by the compiler

Syntax
   Const False As Boolean

Description
   Gives the False Boolean value where used.

Example
   Dim b As Boolean = False
   If b Then
      Print "b is True"
   Else
      Print "b is False"
   End If


   b Is False

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __False.

Differences from QB
   * New to FreeBASIC

See also
   * True
   * Boolean



------------------------------------------------------------ KeyPgField ----
Field

Specifies field alignment.

Syntax
   Type|Union typename Field = { 1 | 2 | 4 }
      ...
   End Type|Union

Description
   Field can be used to pack Types or Unions more tightly than 
   the default layout. The most commonly used value is Field = 1, which 
   causes the Type or Union to be packed as tightly as possible, without 
   any padding bytes being added between the fields or at the end of the 
   Type. Field can only be used to decrease field alignment, but it cannot 
   be used to increase it. In order to add padding bytes, a Union with 
   appropriate members could be used instead.

Example
   Type bitmap_header Field = 1
      bfType          As UShort
      bfsize          As ULong
      bfReserved1     As UShort
      bfReserved2     As UShort
      bfOffBits       As ULong
      biSize          As ULong
      biWidth         As ULong
      biHeight        As ULong
      biPlanes        As UShort
      biBitCount      As UShort
      biCompression   As ULong
      biSizeImage     As ULong
      biXPelsPerMeter As ULong
      biYPelsPerMeter As ULong
      biClrUsed       As ULong
      biClrImportant  As ULong
   End Type

   Dim bmp_header As bitmap_header

   'Open up bmp.bmp and get its header data:
   'Note: Will not work without a bmp.bmp to load . . .
   Open "bmp.bmp" For Binary As #1

      Get #1, , bmp_header
      
   Close #1

   Print bmp_header.biWidth, bmp_header.biHeight

   Sleep

Dialect Differences
   *In the -lang qb dialect, the compiler assumes Field = 1 by default, if 
     no other Field was specified, causing all structures to be tightly 
     packed, without added padding, as in QB.

Differences from QB
   * In QB Field was used to define fields in a file buffer at run time. 
     This feature is not implemented in FB, so the keyword has been 
     redefined. To define fields in a file buffer, Types must be used.

See also
   * Type
   * Union
   * Structure packing/field alignment



--------------------------------------------------------- KeyPgFileattr ----
FileAttr

Returns information about an open file number

Syntax
   Declare Function FileAttr ( ByVal filenum As Long, ByVal returntype As 
   Long = 1 ) As Integer

Usage
   #include "file.bi"
   result = FileAttr( filenum, [ returntype ] )

or

   #include "vbcompat.bi"
   result = FileAttr( filenum, [ returntype ] )

Parameters
   filenum
      The file number of a file or device opened with Open
   returntype
      An integer value indicating the type of information to return.

Return Value
   A value associated with the return type, otherwise 0 on error.

Description
   Information about the file number is returned based on the supplied 
   returntype
         +-----+-----------+------------------+
         |Value|Description|constant          |
         |1    |File Mode  |fbFileAttrMode    |
         |2    |File Handle|fbFileAttrHandle  |
         |3    |Encoding   |fbFileAttrEncoding|
         +-----+-----------+------------------+

   For File Mode, returntype = 1 (fbFileAttrMode) the return value is the 
   sum of one or more of the following values: 
         +-----+---------+----------------+
         |Value|File Mode|Constant        |
         |1    |Input    |fbFileModeInput |
         |2    |Output   |fbFileModeOutput|
         |4    |Random   |fbFileModeRandom|
         |8    |Append   |fbFileModeAppend|
         |32   |Binary   |fbFileModeBinary|
         +-----+---------+----------------+

   For File Handle, returntype = 2 (fbFileAttrHandle), the return value is 
   the file handle as supplied by the C Runtime for file-type devices.  

   On Windows only: For File Handle, returntype = 2 (fbFileAttrHandle), the 
   value returned for COM devices is the handle returned by CreateFile() 
   when the device was first opened.  The value returned for LPT devices is 
   the handle returned by OpenPrinter() when the device was first opened.  
   This handle value can be passed to other Windows API functions.

   On Linux only: For File Handle, returntype = 2 (fbFileAttrHandle), the 
   value returned for COM devices is the file descriptor returned by open() 
   when the device was first opened.

   For Encoding, returntype = 3 (fbFileAttrEncoding), the return value is 
   one of the following values:
         +-----+--------+----------------+
         |Value|Encoding|Constant        |
         |0    |Ascii   |fbFileEncodASCII|
         |1    |UTF-8   |fbFileEncodUTF8 |
         |2    |UTF-16  |fbFileEncodUTF16|
         |3    |UTF-32  |fbFileEncodUTF32|
         +-----+--------+----------------+

Example
   #include "vbcompat.bi"
   #include "crt.bi"

   Dim f As FILE Ptr, i As Integer

   '' Open a file and write some text to it

   Open "test.txt" For Output As #1
   f = Cast( FILE Ptr, FileAttr( 1, fbFileAttrHandle ))
   For i = 1 To 10
     fprintf( f, !"Line %i\n", i )
   Next i
   Close #1

   '' re-open the file and read the text back

   Open "test.txt" For Input As #1
   f = Cast( FILE Ptr, FileAttr( 1, fbFileAttrHandle ))
   While feof(f) = 0
     i = fgetc(f)
     Print Chr(i);
   Wend
   Close #1

Differences from QB
   * None for returntype = 1
   * QBasic and 16-bit Visual Basic returned DOS file handle for 
     returntype = 2
   * returntype = 3 is new to FreeBASIC

See also
   * Open



--------------------------------------------------------- KeyPgFilecopy ----
FileCopy

Copies a file

Syntax
   Declare Function FileCopy ( ByVal source As ZString Ptr, ByVal 
   destination As ZString Ptr ) As Long

Usage
   #include "file.bi"
   FileCopy source, destination

or

   #include "file.bi"
   result = FileCopy( source, destination )

Parameters
   source
      A String argument specifying the filename of the file to copy from.  
      This file must exist.
   destination
      A String argument specifying the filename of the file to copy to.  
      This file will be overwritten if it exists.  This file should not be 
      currently referenced by any open file handles.

Return Value
   Returns 0 on success, or 1 if an error occurred.

Description
   Copies the contents of the source file into the destination file, 
   overwriting the destination file if it already exists.
   It is necessary to #include either "file.bi" or "vbcompat.bi" in order 
   to gain access to this function.

   The error code returned by FileCopy can be checked using Err in the next 
   line. The function version of  FileCopy returns directly the error code 
   as a 32 bit Long.

Example
   #include "file.bi"
   FileCopy "source.txt", "destination.txt"

Platform Differences
   * Linux requires the filename case matches the real name of the file. 
     Windows and DOS are case insensitive. 
   * Path separators in Linux are forward slashes /. Windows uses backward 
     slashes \ but it allows forward slashes.  DOS uses backward  slashes \
     . 

Differences from QB
   * New to FreeBASIC.  Existed in Visual Basic.

See also



----------------------------------------------------- KeyPgFiledatetime ----
FileDateTime

Returns the last modified date and time of a file as Date Serial 

Syntax
   Declare Function FileDateTime ( ByVal filename As ZString Ptr ) As Double

Usage
   #include "file.bi"
   result = FileDateTime( filename )

or

   #include "vbcompat.bi"
   result = FileDateTime( filename )

Parameters
   filename
      Filename to retrieve date and time for.

Return Value
   Returns a Date Serial.

Description
   Returns the file's last modified date and time as Date Serial.

Example
   #include "vbcompat.bi"

   Dim filename As String, d As Double

   Print "Enter a filename: "
   Line Input filename

   If FileExists( filename ) Then

     Print "File last modified: ";

     d = FileDateTime( filename )

     Print Format( d, "yyyy-mm-dd hh:mm AM/PM" )

   Else

     Print "File not found"

   End If

Platform Differences
   * Linux requires the filename case matches the real name of the file. 
     Windows and DOS are case insensitive. 
   * Path separators in Linux are forward slashes / . Windows uses 
     backward slashes \ but it allows forward slashes.  DOS uses backward 
     slashes \.

Differences from QB
   * New to FreeBASIC

See also
   * Date Serials



------------------------------------------------------- KeyPgFileexists ----
FileExists

Tests the existence of a file

Syntax
   Declare Function FileExists ( ByVal filename As ZString Ptr ) As Long

Usage
   #include "file.bi"
   result = FileExists( filename )

or

   #include "vbcompat.bi"
   result = FileExists( filename )

Parameters
   filename
      Filename to test for existence.

Return Value
   Returns non-zero (-1) if the file exists, otherwise returns zero (0).

Description
   FileExists tests for the existence of a file.
   Internally, it may issue an Open() and a Close() function, which may 
   have consequences - eg, any existing Lock(s) on the file may be 
   released.
   Depending on the exact requirements, alternative methods of checking for 
   file existence may be to use the Dir() function (being careful of 
   attributes and ensuring the path doesn't contain wildcards), or to try 
   Opening the file and checking the return value for success.

Example
   #include "vbcompat.bi"

   Dim filename As String

   Print "Enter a filename: "
   Line Input filename

   If FileExists( filename ) Then
     Print "File found: " & filename
   Else
     Print "File not found: " & filename
   End If

Platform Differences
   * Linux requires the filename case matches the real name of the file. 
     Windows and DOS are case insensitive. 
   * Path separators in Linux are forward slashes /. Windows uses backward 
     slashes \ but it allows for forward slashes.  DOS uses backward \ 
     slashes. 

Differences from QB
   * New to FreeBASIC

See also
   * Dir



---------------------------------------------------------- KeyPgFilelen ----
FileLen

Finds the length of a file given its filename

Syntax
   Declare Function FileLen ( filename As String ) As LongInt

Usage
   #include "file.bi"
   result = FileLen(filename)

or

   #include "vbcompat.bi"
   result = FileLen(filename)

Parameters
   filename
      A String argument specifying the filename of the file whose length to 
      return.

Description
   Returns the size in bytes of the file specified by filename.

Example
   #include "file.bi"
   Dim length As Integer
   length = FileLen("file.txt")

Platform Differences
   * Linux requires the filename case matches the real name of the file. 
     Windows and DOS are case insensitive. 
   * Path separators in Linux are forward slashes / . Windows uses 
     backward slashes \ but it allows for forward slashes .  DOS uses 
     backward  \ slashes. 

Differences from QB
   * New to FreeBASIC.  Existed in Visual Basic.

See also
   * LOF



-------------------------------------------------------------- KeyPgFix ----
Fix

Returns the integer part of a number, rounding towards zero

Syntax
   Declare Function Fix ( ByVal number As Single ) As Single
   Declare Function Fix ( ByVal number As Double ) As Double
   Declare Function Fix ( ByVal number As Integer ) As Integer
   Declare Function Fix ( ByVal number As UInteger ) As UInteger

Usage
   result = Fix( number )

Parameters
   number
      the floating-point number to truncate

Return Value
   Returns the integer part of number, rounding towards zero.

Description
   Equivalent to: Sgn(number) * Int(Abs(number)).  For example, Fix(1.3) 
   will return 1.0, and Fix(-4.9) will return -4.0.  For integer types, the 
   number is returned unchanged.

   Note: this function is also equivalent to number - Frac(number).

   The Fix unary Operator can be overloaded with user defined types.

Example
   Print Fix(1.9)  '' will print  1
   Print Fix(-1.9) '' will print -1 

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * None

See also
   * Int
   * Frac
   * CInt
   * Operator



------------------------------------------------------------- KeyPgFlip ----
Flip

Changes the current video display page

Syntax
   Declare Function Flip ( ByVal frompage As Long = -1, ByVal topage As Long
   = -1 ) As Long

Usage
   Flip [ frompage ] [, topage ]

Parameters
   frompage
      previous page
   topage
      new page to display

Return Value
   Returns zero (0) if successful, or a non-zero error code to indicate a 
   failure.

Description
   In normal graphics mode, Flip is an alias for PCopy and ScreenCopy. See 
   ScreenCopy for details.

   In OpenGL mode, Flip does a hardware page flip and displays the contents 
   of the backbuffer. It is recommended that you call Flip regularly while 
   in OpenGL mode, otherwise your app may also become unresponsive.

   The error code returned by Flip can be checked using Err in the next 
   line. The function version of  Flip returns directly the error code as a 
   32 bit Long.

Example
   ScreenRes 320, 240, 32, 2    'Sets up the screen to be 320x240 in 32-bit color with 2 video pages.
   ScreenSet 1,0                'Sets the working page to 1 and the displayed page to 0

   For n As Integer = 50 To 270

      Cls
      Circle (n, 50),50 ,RGB(255,255,0) 'Draws a circle with a 50 pixel radius in yellow on page 1
      Flip 1,0    'Copies our circle from page 1 to page 0

      Sleep 25
   Next

   Print "Now wasn't that neat!"
   Print "Push any key."
   Flip 1,0    'Copies our text from page 1 to page 0
   Sleep

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Flip.

Differences from QB
   * New to FreeBASIC



-------------------------------------------------------------- KeyPgFor ----
For

Control flow statement, open statement clause, or operator depending on 
context.

Syntax
   For iterator = startvalue To endvalue [ Step increment ]
or
   Open [ device ] "filename" For filemode As #handle
or
   declare operator For ( byref stp as datatype )

See also
   * For...Next
   * Open
   * Operator

   


---------------------------------------------------------- KeyPgFornext ----
For...Next

Control flow statement for looping

Syntax
   For iterator [ As datatype ] = startvalue To endvalue [ Step stepvalue ]
      [ statement block ]
   Next [ iterator ]

Parameters
   iterator
      a variable identifier that is used to iterate from an initial value 
      to an end value
   datatype
      If specified, the variable iterator will automatically be declared 
      with the type datatype
   startvalue
      an expression that denotes the starting value of the iterator
   endvalue
      an expression used to compare with the value of the iterator
   stepvalue
      an expression that is added to the iterator after every iteration

Description
   A For...Next loop initializes iterator to startvalue, then executes the 
   statement block, incrementing iterator by stepvalue until it exceeds 
   endvalue. If stepvalue is not explicitly given it will set to 1.

   The values of stepvalue and endvalue are stored internally immediately 
   following execution of the For statement and thus neither can be changed 
   inside the For loop.  Comparison operators such as < and > will not be 
   effective as stepvalue or endvalue because the expressions will not be 
   re-evaluated while the loop is running. (The results of the expressions 
   used to define them may be changed, but these changes will not affect 
   the execution of the For loop.) See examples.

   Note: In some dialects, the temporary variables holding stepvalue and 
   endvalue go out of scope at the end of the loop, and their values are 
   not guaranteed to remain unchanged once any code following the loop has 
   been executed.  For this reason, it is recommended never to branch out 
   of a For...Next loop (using Goto or similar), and then jump back into 
   the middle of it later when in the -lang fb or -lang deprecated dialect.

   The iterator must be an intrinsic scalar: only Static/Shared variables 
   and local variables can be used; no other kind can be used, including 
   array elements, UDT members, ByRef parameters or any kind of 
   dereferenced address.

   The iterator may be defined having the same scope as the For statement 
   by using the As datatype syntax.  With this syntax, iterator is created 
   and destroyed within the For...Next scope. See dialect differences 
   below.

   If endvalue is less than startvalue then a negative stepvalue must be 
   specified or the statement block will not execute at all, since 
   startvalue compares greater than endvalue.

   The For statement causes the execution of the statements in the 
   statement block until iterator compares greater than endvalue (or less 
   than endvalue if stepvalue < 0). iterator will be incremented the amount 
   of stepvalue following each execution of the statement block. If an 
   increment is not given, iterator will be implicitly incremented by 1.

   If an Exit For statement is encountered inside the statement block, the 
   loop is terminated, and execution resumes immediately following the 
   enclosing Next statement. If a Continue For statement is encountered, 
   the rest of the statement block is skipped until the block's 
   corresponding Next statement.  The counter's value is incremented and 
   the loop restarted if it is still within the bounds given by endvalue.

   Note: for integer data types, it is not possible to loop up to the 
   highest possible value (or down to the lowest possible value) that can 
   be stored in the variable type, because the loop only breaks when the 
   incremented variable exceeds endvalue, which can never happen.  For 
   example, if you try to iterate an variable from 0 to 255, the loop will 
   only break once the variable reaches 256 or more.  Using a UByte 
   variable for the counter wouldn't work, because although it can hold the 
   numbers 0 to 255, it cannot hold 256.  See Standard Data Type Limits to 
   find the upper and lower limits for the standard data types.

   Like all control flow statements, the For statement can be nested, that 
   is, it can be used in a statement block of another For statement.

   For, Next, and Step are operators that can be overloaded inside user 
   defined types. See Operator For, Operator Next, Operator Step

Example
   Print "counting from 3 to 0, with a step of -0.5"
   For i As Single = 3 To 0 Step -0.5
      Print "i is " & i
   Next i

   Dim As Integer i, j, k, toTemp, stepTemp
   j = 9: k = 1

   For i = 0 To j Step k
      
      j = 0: k = 0 '' Changing j and k has no effect on the current loop.
      Print i;
      
   Next i
   Print

   ' Internally, this is what the above example does:
   j = 9: k = 1

   i = 0: toTemp = j: stepTemp = k
   Do While IIf(stepTemp >= 0, i <= toTemp, i >= toTemp)
      
      j = 0: k = 0 '' Changing j and k has no effect on the current loop.
      Print i;
      
      i += stepTemp
   Loop
   Print

Example of infinite For...Next loop in case of loop up to the highest value 
of an Ubyte iterator (255):
   For ub As UByte = 240 To 255 '' Infinite loop because the end criterion value (255+1=256) can never be reached by the UByte iterator
      Print ub
      If Inkey <> "" Then Exit For
      Sleep 10
   Next ub
The same applies to lowest value of an UByte iterator (0) in case of loop 
down (negative stepvalue).

Dialect Differences
   * In the -lang fb and -lang deprecated dialects, variables declared 
     inside a For..Next block are visible only inside the block, and cannot 
     be accessed outside it.
   * In the -lang qb and -lang fblite dialects, variables declared inside 
     a For..Next block (including the counter if declared, and any 
     temporary variables used to hold endvalue or stepvalue), have a 
     procedure-wide scope  as in QB

Differences from QB
   * ByRef arguments cannot be used as counters.

See also
   * Continue
   * Do...Loop
   * Exit



----------------------------------------------------------- KeyPgFormat ----
Format

Formats a number in a specified format

Syntax
   Declare Function Format ( ByVal numerical_expression As Double, ByRef 
   formatting_expression As Const String = "" ) As String

Usage
   #include "string.bi"
   result = Format[$]( numerical_expression, formatting_expression )

Parameters
   numerical_expression
      number to format
   formatting_expression
      formatting pattern

Return Value
   Format returns a string with the result of the numerical expression 
   formatted as indicated in the formatting expression.
   The formatting expression is a string that can yield numeric or 
   date-time values.

Description
   To recover meaningful date-time values the numerical expression must be 
   a date serial obtained from the appropriate functions.
   This function is part of FreeBASIC, however it is not recognized by the 
   compiler unless vbcompat.bi is included.

   "Numeric Formats"
         +--------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
         |Symbol                    | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
         | Null string              | General format (no formatting)                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
         |0                         | Digit placeholder: If the number has fewer digits than there are           zeros (on either side of the decimal) in the format expression, leading or trailing zeros are displayed. If there are more digits to the right of the decimal than zeros in the format, the number is rounded. If there are more digits to the left of the decimal than zeros in the format the digits are all displayed                                                                                      |
         | #                        | Digit placeholder: Follows the same rules as for the 0 digit except the leading or trailing zeros are not displayed                                                                                                                                                                                                                                                                                                                                                                      |
         |.                         | Placeholder for decimal point.If the format contains only #'s to the left of . then numbers smaller than 1  are begun with a decimal point.                                                                                                                                                                                                                                                                                                                                              |
         | %                        | Percentage :The expression is multiplied by 100 and the % character is inserted.                                                                                                                                                                                                                                                                                                                                                                                                         |
         |,                         | Thousands separator. Two adjacent commas, or a comma immediately to the left of the decimal point location (whether there is a decimal specified or not) means 'Omit the three digits that fall between these  commas, or between the comma and the decimal point, rounding as needed.'                                                                                                                                                                                                  |
         | E- E+ e- e+              |Scientific format: If a format contains one digit placeholder (0 or #) to the right of an E-, E+, e-, or e+, the number is displayed in scientific  format and an E or e is inserted between the number and its exponent.The number of 0's or #'s to the right determines the number of digits in the exponent. Use E- or e- to place a minus sign next to negative exponents. Use a E+ or e+ to place a minus sign next to negative exponents and a plus sign next to positive exponents.|
         | : ? + $ () space         |   Display literal character  To display a character other than one of these, precede the character with a backslash (\) or enclose the character(s) in double quotation marks                                                                                                                                                                                                                                                                                                            |
         |\                         | Display next character in format string as it is                                                                                                                                                                                                                                                                                                                                                                                                                                         |
         |text between double quotes|  Displays the text inside the double quotes.                                                                                                                                                                                                                                                                                                                                                                                                                                             |
         | :                        | Time separator is used to separate hours, minutes, and seconds when time values are formatted.                                                                                                                                                                                                                                                                                                                                                                                           |
         | /                        | The date separator is used to separate day,month, and year when date values are formatted.                                                                                                                                                                                                                                                                                                                                                                                               |
         +--------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

   "Date-Time formats:"
         +----------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
         |Symbol                | Description                                                                                                                                          |
         |d, dd                 | Display the day as a one-digit/two-digit number (1-31/01-31)                                                                                         |
         |ddd                   | Display the day as an abbreviation (Sun-Sat)                                                                                                         |
         |dddd                  | Display the day as a full name (Sunday-Saturday)                                                                                                     |
         |ddddd                 |  Display a serial date number as a complete date (including day, month and year)                                                                     |
         |m, mm                 | Display the month as a one-digit/two-digit number (1-12/01-12).  If immediately following h or hh, the minute rather than the month is displayed     |
         |M, MM                 | Display the month as a one-digit/two-digit number (1-12/01-12), even if immediately following h or hh                                                |
         |mmm                   | Display the month as an abbreviation (Jan-Dec)                                                                                                       |
         |mmmm                  | Display the month as a full name (January-December)                                                                                                  |
         |y, yy                 | Display the year as a two-digit number (00-99)                                                                                                       |
         |yyyy                  | Display the year as a four-digit number (1900-2040)                                                                                                  |
         |h, hh                 | Display the hour as a one-digit/two-digit number (0-23/00-23)                                                                                        |
         |m, mm                 | Display the minute as a one-digit/two-digit number (0-59/00-59).  If not immediately following h or hh, the month rather than the minute is displayed|
         |n, nn                 | Display the minute as a one-digit/two-digit number (0-59/00-59), even if not immediately following h or hh                                           |
         |s, ss                 | Display the second as a one-digit/two-digit number (0-59/00-59)                                                                                      |
         |ttttt                 | Display a time serial number as a complete time, including hour, minute and second                                                                   |
         |AM/PM (Default), am/pm| Use the 12-hour clock displaying AM or am with any hour before noon, PM or pm with any hour between noon and 11:59                                   |
         |A/P, a/p              |  Use the 12-hour clock displaying A or a with any hour before noon, P or p with any hour between noon and 11:59                                      |
         +----------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+

Example

   Sample numeric formats
   Format (fmt)                  5             -5            .5
   		
   		Null String                   5             -5            0.5
   		0                             5             -5            1
   		0.00                          5.00          -5.00         0.50
   		#,##0                         5             -5            1
   		#,##0.00                      5.00          -5.00         0.50
   		0%                            500%          -500%         50%
   		0.00%                         500.00%       -500.00%      50.00%
   		0.00E+00                      5.00E+00      -5.00E+00     5.00E-01
   		0.00E-00                      5.00E00       -5.00E00      5.00E-01
    Sample Date And Time Formats
   The following are examples of Date And Time formats:
   		 Format  Expression     Display
   		 m/d/yy                 12/7/58
   		 d-mmmm-yy              7-December-58
   		 d-mmmm                 7-December
   		 mmmm-yy                December-58
   		 h:mm AM/PM             8:50 PM
   		 h:mm:ss AM/PM          8:50:35 PM
   		 h:mm                   20:50
   		 h:mm:ss                20:50:35
   		 m/d/yy h:mm            12/7/58 20:50 

Dialect Differences
   None

Differences from QB
   * Does not exist in QB 4.5. This function appeared first in PDS 7.1

See also
   * Print Using
   * ? Using
   * Str



------------------------------------------------------------- KeyPgFrac ----
Frac

Returns the decimal part of a number

Syntax
   Declare Function Frac ( ByVal number As Double ) As Double
   Declare Function Frac ( ByVal number As Integer ) As Integer
   Declare Function Frac ( ByVal number As UInteger ) As UInteger

Usage
   result = Frac( number )

Parameters
   number
      the number or expression to get the fraction part of.

Return Value
   Returns the fractional part of a number or expression.

Description
   Equivalent to: (number - Fix(number)).
   For example, Frac(4.25) will return 0.25, and Frac(-1.75) will return 
   -0.75.  For integer types, the value 0 is always returned.

   The Frac unary Operator can be overloaded with user defined types.

Example
   Print Frac(10.625)  '' will print  0.625
   Print Frac(-10.625) '' will print -0.625 

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * New to FreeBASIC

See also
   * Fix
   * Operator



-------------------------------------------------------------- KeyPgFre ----
Fre

Returns the amount of free memory available

Syntax
   Declare Function Fre ( ByVal value As Long = 0 ) As UInteger

Usage
   result = Fre( [ value ] )

Parameters
   value
      Unused dummy parameter kept for backward compatibility; can be 
      ignored.

Return Value
   Returns the amount of free memory, in bytes.

Description
   Returns the free memory (ram) available, in bytes.

Example
   Dim mem As Integer = Fre

   Print "Free memory:"
   Print
   Print mem; " bytes"
   Print mem  \ 1024; " kilobytes"
   Print mem  \ (1024 * 1024); " megabytes"

Differences from QB
   * The "value" argument is not checked, Fre will always return the free 
     physical memory available

See also
   * Dim
   * ReDim
   * Allocate



--------------------------------------------------------- KeyPgFreefile ----
FreeFile

Returns a free file number

Syntax
   Declare Function FreeFile ( ) As Long

Usage
   result = FreeFile

Return Value
   The next available file number, if any, otherwise zero (0).

Description
   Returns the number of the next free file number with valid values 1 to 
   255, or 0 if there are already 255 files opened. This value is a 
   required argument to Open a file. FreeFile is useful when opening files 
   in complex programs where the programmer can't keep track of the used 
   file numbers.

   Make sure to always close files when no longer needed, otherwise you 
   will get a file number leak, and won't be able to open any files anymore 
   after 255 filenumbers are exhausted while your program is running.

   FreeFile will always return the smallest free file number.  The file 
   number returned by FreeFile will not change until that file number is 
   Opened, or until a smaller file number is Closed.  For this reason, it 
   is wise to use FreeFile immediately before its corresponding Open, to 
   ensure that the file number is not returned and opened elsewhere first.

Example
   ' Create a string and fill it.
   Dim buffer As String, f As Long
   buffer = "Hello World within a file."

   ' Find the first free file number.
   f = FreeFile

   ' Open the file "file.ext" for binary usage, using the file number "f".
   Open "file.ext" For Binary As #f

   ' Place our string inside the file, using file number "f".
   Put #f, , buffer

   ' Close the file.
   Close #f

   ' End the program. (Check the file "file.ext" upon running to see the output.)
   End

   When using multiple FreeFile statements, FreeFile should be used 
   immediately before the Open statement:
   Dim As Long fr, fs
   ' The CORRECT way:
   fr = FreeFile
   Open "File1" For Input As #fr

   fs = FreeFile
   Open "File2" For Input As #fs

   As opposed to:
   Dim As Long fr, fs
   ' The WRONG way:
   fr = FreeFile
   fs = FreeFile '' fs has taken the same file number as fr

   Open "file1" For Input As #fr
   Open "file2" For Input As #fs '' error: file number already opened

Platform Differences
   * On Windows, a file number used in a dynamic link library is not the 
     same as an identical file number used in the main program.  File 
     numbers can not be passed or returned and then used between a DLL and 
     an executable.
   * Besides FreeBASIC's limit of 255 files per program opened at same 
     time, there is an OS limit of total amount of opened files, but 
     usually you won't touch it except in DOS, where the limit may be as 
     low as 15 files total.

Differences from QB
   * None

See also
   * Open
   * Put (File I/O)
   * Get (File I/O)
   * FileAttr



--------------------------------------------------------- KeyPgFunction ----
Function

Defines a procedure returning a value

Syntax
   [Public|Private] Function identifier [cdecl|pascal|stdcall] [Overload] [
   Alias external_identifier] [([parameter_list])] [ ByRef ] [As 
   return_type] [Static] [Export]
      statements
      ...
      { {Return [return_value]}|{Function = return_value}|{identifier = 
      return_value} }
      ...
   End Function

Parameters
   identifier: the name of the function
   external_identifier: externally visible (to the linker) name enclosed in 
   quotes
   parameter_list: parameter[, parameter[, ...]]
   parameter: [ByRef|ByVal] identifier [As type] [= default_value]
      identifier: the name of the variable referenced in the function.  If 
      the argument is an array then the identifier must be followed by an 
      empty parenthesis. 
      type: the type of variable
      default_value: the value of the argument if none is specified in the 
      call
   return_type: the type of variable returned by the function
   statements: one or more statements that make up the function body
   return_value: the value returned from the function

Description
   A function defines a block of code which can be executed with a single 
   statement (a function call), and provide a value back to the caller when 
   finished (a return value). 	There are several reasons to use functions:
   * Reduces redundancy in your program
   * Enables reuse of code in many programs
   * Improves readability of the program
   * Improves maintainability of the program
   * Makes it easy to extend your program

   Access Rights : The Public and Private keywords specify public or 
   private intra module-level access rights, respectively. If neither is 
   given, the function defaults to public access (Public).

   Calling Convention : Calling convention, or the order in which arguments 
   are pushed and popped from the stack during function calls, is specified 
   with the cdecl, pascal and stdcall keywords. If none is given, the 
   function uses the standard convention by default (stdcall).

   Passing Arguments : Functions may receive one or more variables, or 
   arguments, when called. These arguments are listed as parameters in the 
   parameter_list. The ByRef and ByVal keywords specify whether the 
   argument will be passed by reference or by value, respectively. The 
   argument's type is given by "As type" following the parameter. If a 
   parameter in the declaration is given a default value, the parameter is 
   optional.  Array parameters are specified by following an identifier 
   with an empty parenthesis.  Note that array parameters are always ByRef 
   and the ByRef keyword is neither required nor allowed for array 
   parameters.  When calling a function with an array argument the 
   parenthesis must be supplied there too; see the examples.

   Overloaded Functions : An overloaded function may share the same name (
   identifier) as another with a different signature. The Overload keyword 
   specifies that a function may be overloaded. A function must be defined 
   - or declared - using the Overload keyword prior to any functions that 
   overload them.

   Returning values : return_type specifies the data type returned by a 
   function upon exit. If no data type is specified, then the function will 
   return the default data type, which will be Integer unless set to 
   another data type using DefSng, DefDbl, DefStr, etc. Functions can 
   return values using three methods: the Return keyword followed by a 
   value exits the function immediately, and returns that value to the 
   caller. Functions can also return values by assigning the Function 
   keyword or the function's identifier to the desired return value. The 
   latter two methods do not cause the function to exit, however. Return 
   keyword mixed with Function= keyword or function's identifier= or 
   Exit Function keyword in a same function is unsupported when returning 
   objects with constructors. Since functions return values, function calls 
   evaluate to expressions. Thus, function calls can be made wherever an 
   expression is expected, like in Assignments or If statements. Functions 
   can also return references by specifying Byref As return_type.
   Warning: Whatever the output branch used, the return value must be 
   always defined, otherwise an unexpected behavior may occur.

   Local Variable Preservation : The Static keyword specifies that a 
   function's locally declared variables are preserved between function 
   calls. Upon entering a function defined with Static, local variables 
   have the same value as when the function was last called.

   When calling a function, parentheses surrounding the argument list (if 
   any) are required only for function calls in expressions. If there is no 
   argument to pass, the parentheses become optional, but it is a common 
   convention to place empty parentheses '()' after the function name, to 
   signify a function call.

Example

   '' This program demonstrates the declaration of a function 
   '' and returning a value using Return command

   Declare Function ReturnTen () As Integer

   Print ReturnTen () '' ReturnTen returns an integer by default.

   Function ReturnTen() As Integer
      Return 10
   End Function

   '' This program demonstrates the declaration of a function 
   '' and returning a value using assignment to function name

   Declare Function ReturnTen () As Integer

   Print ReturnTen () '' ReturnTen returns an integer by default.

   Function ReturnTen() As Integer
      ReturnTen = 10
   End Function

   '' This program demonstrates function overloading.

   '' The overloaded functions must be FIRST.
   Declare Function ReturnTen Overload (a As Single) As Integer
   Declare Function ReturnTen Overload (a As String) As Integer
   Declare Function ReturnTen (a As Integer) As Integer

   Print ReturnTen (10.000!) '' ReturnTen will take a single and return an integer
   Print ReturnTen (10)      '' ReturnTen will take an integer and return an integer
   Print ReturnTen ("10")    '' ReturnTen will take a string and return an integer

   Function ReturnTen Overload (a As Single) As Integer
      Return Int(a)
   End Function

   Function ReturnTen Overload (a As String) As Integer
      Return Val(a)
   End Function

   Function ReturnTen (a As Integer) As Integer
      Return a
   End Function

   '' The following example demonstrates optional parameters.

   Function TestFunc(P As String = "Default") As String
      Return P
   End Function

   Print TestFunc("Testing:")
   Print TestFunc

   '' This example shows how to declare and call 
   '' functions taking array arguments.

   Function x(b() As Double) As Integer
     x = UBound(b)-LBound(b)+1
   End Function

   Dim a(1 To 10) As Double
   Print x(a())
   Dim c(10 To 20) As Double 
   Print x(c())

Dialect Differences
   * In the -lang fb dialect, ByVal is the default parameter passing 
     convention for all built-in types except String; String and 
     user-defined Types are passed ByRef by default.
   * In the -lang qb and -lang fblite dialects, ByRef is the default 
     parameter passing convention.
   * In the -lang qb dialect, the name of the function must be used in an 
     assignment to specify the return value.  Using Function = ..." to 
     specify the return value may not be used.
   * In the -lang qb and -lang fblite dialects, Return may only be used to 
     return a value when Option Gosub is off.  In -lang qb, this must be 
     done explicitly using the Option Nogosub statement.

Differences from QB
   * Parameters can be optional in FreeBASIC.
   * In QBASIC, the return type could only specified with a suffix, not 
     with AS TYPE, and only allowed functions to return a built-in type.
   * Return value can now be specified by a Return statement.
   * Function Overloading is supported in FreeBASIC.
   * The return value of functions can be ignored in the calling code.

See also
   * Sub
   * Exit
   * Return
   * Declare
   * Public
   * Private



--------------------------------------------------- KeyPgMemberFunction ----
Function (Member)

Declares or defines a member procedure returning a value.

Syntax
   { Type | Class | Union } typename
      Declare [ Static | Const ] Function fieldname [calling convention 
      specifier] [ Alias external_name ] ( [ parameters ] ) [ ByRef ] As 
      datatype [ Static ]
   End { Type | Class | Union }

   Function typename.fieldname ( [ parameters ] ) [ ByRef ] As datatype [ 
   Export ]
      statements
   End Function

Parameters
   typename 
      name of the Type, Class, or Union
   fieldname 
      name of the procedure
   external_name
      name of field as seen when externally linked
   parameters 
      the parameters to be passed to the procedure
   calling convention specifier	
      can be one of: cdecl, stdcall or pascal

Description
   Function members are accessed with Operator . (Member Access) or 
   Operator -> (Pointer To Member Access) to call a member procedure that 
   returns a value (a reference can also be returned by specifying Byref As 
   return_type).  The procedure may optionally accept parameters either 
   ByVal or ByRef.  typename be overloaded  without explicit use of the 
   Overload keyword.

   typename is the name of the type for which the Function method is 
   declared and defined.  Name resolution for typename follows the same 
   rules as procedures when used in a Namespace.

   A hidden This parameter having the same type as typename is passed to 
   non-static member procedures.  This is used to access the fields of the 
   Type, Class, or Union.
   To access duplicated symbols defined outside the Type, add one (or two) 
   dot(s) as prefix: .SomeSymbol (or ..SomeSymbol if inside a With..End With
   block).

   A Static (Member) may be declared using the Static specifier.  A 
   Const (Member) may be declared using the Const specifier.

   As for a normal Function, the return value of a Function member can be 
   ignored in the calling code.

Example
   #include "vbcompat.bi"

   Type Date

     value As Double

     Declare Static Function Today() As Date

     Declare Function Year() As Integer
     Declare Function Month() As Integer
     Declare Function Day() As Integer

   End Type

   Function Date.Today() As Date
     Return Type(Now())
   End Function

   Function Date.Year() As Integer
     Return ..Year(value)
   End Function

   Function Date.Month() As Integer
     Return ..Month(value)
   End Function

   Function Date.Day() As Integer
     Return ..Day(value)
   End Function

   Dim d As Date = Date.Today

   Print "Year  = "; d.Year
   Print "Month = "; d.Month
   Print "Day   = "; d.Day

Dialect Differences
   * Only available in the -lang fb dialect.

See also
   * Class
   * Function
   * Sub (Member)
   * Type



------------------------------------------------------ KeyPgFunctionPtr ----
Function Pointer

Data type that stores a pointer to a Function procedure returning a value

Syntax
   Dim variable As Function [cdecl|pascal|stdcall] [( [parameter_list] )] [ 
   ByRef ] [As return_type] [= initializer]

Parameters
   parameter_list: parameter[, parameter[, ...]]
   parameter: [ByRef|ByVal] identifier [As type] [= default_value]
      identifier: the name of the variable referenced in the subroutine
      type: the type of variable
      default_value: the value of the argument if none is specified in the 
      call
   return_value: the value returned from the function
   intializer: address of a subroutine to set as the intial value

Description
   A Function pointer is a procedure pointer that stores the memory 
   location of compiled code that returns a value.  If no intializer is 
   given the default initial value is zero (0).

   The memory address for the Function procedure can be assigned to the 
   variable by taking the address of a subroutine with ProcPtr or 
   Operator @ (Address Of).

   The procedure must match the same Function declaration as the declared 
   Function pointer.

   To call the subroutine assigned, use the variable name as if it were a 
   normal declared Function.

   One of the primary uses for procedure pointers is to create callback 
   procedures. A callback procedure is a procedure created in the user 
   program that is called by another procedure either from the user own 
   code space or from an external library.

Example
   Function ConcatSelf( x As String ) As String
      Return x & x
   End Function

   Dim x As Function( x As String ) As String = ProcPtr( ConcatSelf )

   Print x( "Hello" )

   Function x2 (ByVal i As Integer) As Integer
     Return i * 2
   End Function

   Function x3 (ByVal i As Integer) As Integer
     Return i * 3
   End Function

   Function operation (ByVal i As Integer, ByVal op As Function (ByVal As Integer) As Integer) As Integer
     Return op(i)
   End Function

   Print operation(4, @x2)
   Print operation(4, @x3)

   ' Example of basic callback Function mechanism to implement a key pressed event:
   ' (the user callback Function address cannot be modified while the event thread is running)
   '   - An asynchronous thread tests the keyboard in a loop, and calls a user callback Function each time a key is pressed.
   '   - The callback Function address is passed to the thread.
   '   - The callback Function prints the character of the key pressed,
   '       but if the key pressed is <escape> it orders the thread to finish by using the function return value.
   '   - As the user callback address is passed to the thread as argument, it cannot be modified while the thread is running.

   '' thread Sub definition
     Sub threadInkey (ByVal p As Any Ptr)
      If p > 0 Then                                                '' test condition callback Function defined
        Dim As Function (ByRef As String) As Integer callback = p  '' convert the any ptr to a callback Function pointer
        Do
         Dim As String s = Inkey
         If s <> "" Then                                          '' test condition key pressed
           If callback(s) Then                                    '' test condition to finish thread
            Exit Do
           End If
         End If
         Sleep 50
        Loop
      End If
     End Sub

   '' user callback Function definition
     Function printInkey (ByRef s As String) As Integer
      If Asc(s) = 27 Then                                        '' test condition key pressed = <escape>
        Print
        Return -1                                                '' order thread to finish
      Else
        Print s;
        Return 0                                                 '' order thread to continue
      End If
     End Function

   '' user main code
     Dim As Any Ptr p = ThreadCreate(@threadInkey, @printInkey)   '' launch the thread, passing the callback Function address
     ThreadWait(p)                                                '' wait for the thread finish

Differences from QB
   * New to FreeBASIC

See also
   * Sub
   * ProcPtr
   * Operator @ (Address Of)




============================================================================
    G

------------------------------------------------------ KeyPgGetgraphics ----
Get (Graphics)

Gets a copy of a portion of the current work page or an image buffer

Syntax
   Get [source,] [STEP](x1, y1) - [STEP](x2, y2), dest

Parameters
   source
      the address of an image buffer. If it's omitted, the current work 
      page is copied.
   STEP
      indicates that the following co-ordinates are not absolute 
      co-ordinates.
   [STEP](x1, y1)
      co-ordinates of the upper-left corner of the sub-image to copy.  STEP 
      indicates that (x1, y1) offsets are relative to the current graphics 
      cursor position.
   [STEP](x2, y2)
      co-ordinates of the lower-right corner of the sub-image to copy.  
      STEP indicates that x2 and y2 are relative to x1 and y1, 
      respectively.
   dest
      the address of a previously allocated buffer to store the image data.

Description
   Get copies a rectangular portion of the current work page specified by 
   the co-ordinates (x1,  y1) and (x2,  y2), which represent the upper-left 
   and lower-right corners of the rectangle, respectively. STEP specifies 
   that the upper-left co-ordinates are relative to the current graphics 
   pen location, and/or that the lower-right co-ordinates are relative to 
   the upper-left co-ordinates. The new image buffer is formatted to match 
   the current screen mode pixel format.

   dest can be an address, an array (name not followed by empty 
   parentheses), or a reference to the first element in an array that will 
   receive the new image buffer. This memory must be sufficiently allocated 
   to hold the image buffer (the number of bytes required varies with the 
   -lang dialect used to compile the program). Valid image buffers can be 
   created simply by using preferably the ImageCreate statement.

   source can be an address, an array (name not followed by empty 
   parentheses), or a reference to the first element in an array that holds 
   an image buffer to retrieve a portion of. x1,  y1, x2,  y2, Step and 
   dest have the same meaning in this case.

   The co-ordinates of the rectangle are affected by the most recent Window 
   and View (Graphics) statements, and must both be within the current 
   clipping region set by View (Graphics) (or within the default viewport), 
   otherwise an illegal function call runtime error will be triggered, and 
   the function will have no effect.

Runtime errors:
   Get throws one of the following runtime errors:

   (1) Illegal function call
      * dest is an array, but is not big enough to hold the image buffer.
      * The upper-left or lower-right co-ordinates of the rectangle are 
        outside the current clipping region (set or default). See 
        View (Graphics).

Dialect Differences
   There are 2 types of buffers (details see GfxInternalFormats) depending 
   from FB dialect used:

   * In the -lang fb dialect, dest receives a new-style image buffer, 
     which consists of a 32-byte image header followed by pixel data which 
     is row-padded to the next paragraph boundary (16 bytes). Use the 
     following formula to calculate the total size, in bytes, required to 
     store the image buffer, where w and h are the respective width and 
     height of the rectangular portion of the current work page or source 
     image buffer, and bpp is the number of bytes per pixel of the current 
     screen mode:
      size = 32 + (((w * bpp + &hF) and not &hF) * h)

   * In the -lang qb and -lang fblite dialects, dest receives a QB-style 
     image buffer, which consists of a 4-byte image header followed by 
     pixel data which is not row-padded. Use the following formula to 
     calculate the total size, in bytes, required to store the image 
     buffer, where w and h are the respective width and height of the 
     rectangular portion of the current work page or source image buffer, 
     and bpp is the number of bytes per pixel of the current screen mode:
      size = 4 + (w * h * bpp)

Example
   #include Once "fbgfx.bi"

   '' Setup a 400x300 32bit screen
   ScreenRes 400, 300, 32

   '' First draw funny stuff...
   Line (10,10)-(140,30), RGB(255,255,0), bf
   Draw String (30, 20), "Hello there!", RGB(255,0,0)

   '' Now capture a 150x50 block from the top-left of the screen into an image
   '' buffer with GET...
   Dim As fb.Image Ptr image = ImageCreate(150, 50)
   Get (0,0)-(150-1,50-1), image

   '' And duplicate it all over the place!
   Put (0,50), image
   Put (0,100), image
   Put (0,150), image
   Put (0,200), image
   Put (0,250), image
   Put (150,0), image
   Put (150,50), image
   Put (150,100), image
   Put (150,150), image
   Put (150,200), image
   Put (150,250), image

   ImageDestroy(image)

   '' And a frame around a whole screen..
   Line (0,0)-(400-1,300-1), RGB(255,255,0), b

   '' Now get the whole screen...
   Dim As fb.Image Ptr big = ImageCreate(400, 300)
   Get (0,0)-(400-1,300-1), big

   '' And display that "screenshot" as if it was scrolling by...
   Dim As Integer x = -350
   While ((Inkey() = "") And (x < 350))
      ScreenLock
         Cls
         Put (x,0), big
      ScreenUnlock

      Sleep 100, 1

      x += 10
   Wend

   ImageDestroy(big)

See also
   * Put (Graphics)
   * ImageCreate
   * Get (File I/O)
   * Screen (Graphics)
   * Window
   * View (Graphics)
   * Internal graphics formats



-------------------------------------------------------- KeyPgGetfileio ----
Get (File I/O)

Reads data from a file to a buffer

Syntax
   Get #filenum As Long, [position As LongInt], ByRef data As Any [, [
   amount As UInteger] [, ByRef bytesread As UInteger] ]
   Get #filenum As Long, [position As LongInt], data As String [, , ByRef 
   bytesread As UInteger ]
   Get #filenum As Long, [position As LongInt], data() As Any [, , ByRef 
   bytesread As UInteger ]

Usage
   Get #filenum, position, data [, [amount] [, bytesread ] ]
   varres = Get (#filenum, position, data [, [amount] [, bytesread ] ] )

Parameters
   filenum
      The value passed to Open when the file was opened.
   position
      The position where the read must start. If the file was opened 
      For Random, the position is in records; otherwise, it is in bytes. If 
      omitted, reading starts at the present file pointer position.  The 
      position is 1-based: i.e. first record or byte of a file is at 
      position 1.
      If position is omitted or zero (0), file reading will start from the 
      current file position.
   data
      The buffer where data is written. It can be a numeric variable, a 
      string, an array, a user defined type or a dereferenced pointer. The 
      read operation will try to fill completely the variable, unless the 
      EOF is reached.
      When getting arrays, data should be followed by an empty pair of 
      brackets: "()".  Get will read data for all of the values in the 
      array.  amount is not allowed.
      When getting Strings, the number of bytes read is the same as the 
      number of bytes in the string data. amount is not allowed.
      Note: If you want to read values into a buffer, you should NOT pass a 
      pointer to the buffer; instead you should pass the first variable in 
      the buffer. (This can be done by dereferencing the pointer with 
      Operator * (Value Of).) If you pass a pointer directly, then Get will 
      overwrite the pointer variable, not the memory it points to.
   amount
      Makes Get read amount consecutive variables from file to memory, i.e. 
      it reads (amount * SizeOf(data) ) bytes of data from file into the 
      memory starting at data's memory location.  If amount is omitted it 
      defaults to 1, meaning that Get just reads a single variable.
   bytesread
      An unsigned integer variable to accept the result of the number of 
      bytes read successfully from the file.

Return Value
   Get() returns a 32 bit Long: a zero (0) on success; non-zero on error.
   Note: if EOF (end of file) is reached while reading, Get will return 
   success.  The amount of bytes actually read can be checked by passing a 
   bytesread variable.

Description
   Reads binary data from a file to a buffer variable

   Get can be used as a function, and will return 0 on success or an error 
   code on failure.	

   For files opened in Random mode, the size in bytes of the data to read 
   must match the specified record size.

   Note: If a dereferenced [w/z]string pointer is passed to Get, the amount 
   parameter is not taken into account as it is by passing a dereferenced 
   numeric pointer. But instead, the pointed buffer must begin with at 
   least as many non-zero elements as the number of elements to read.

Example
   Dim Shared f As Integer

   Sub get_long()

      Dim buffer As Long ' Long variable

      ' Read a Long (4 bytes) from the file into buffer, using file number "f".
      Get #f, , buffer

      ' print out result
      Print buffer
      Print

   End Sub

   Sub get_array()

      Dim an_array(0 To 10-1) As Long ' array of Longs

      ' Read 10 Longs (10 * 4 = 40 bytes) from the file into an_array, using file number "f".
      Get #f, , an_array()

      ' print out result
      For i As Integer = 0 To 10-1
         Print an_array(i)
      Next
      Print

   End Sub

   Sub get_mem

      Dim pmem As Long Ptr

      ' allocate memory for 5 Longs
      pmem = Allocate(5 * SizeOf(Long))

      ' Read 5 Longs (5 * 4 = 20 bytes) from the file into allocated memory
      Get #f, , *pmem, 5 ' Note pmem must be dereferenced (*pmem, or pmem[0])

      ' print out result using [] Pointer Indexing
      For i As Integer = 0 To 5-1
         Print pmem[i]
      Next
      Print

      ' free pointer memory to prevent memory leak
      Deallocate pmem

   End Sub

   ' Find the first free file file number.
   f = FreeFile

   ' Open the file "file.ext" for binary usage, using the file number "f".
   Open "file.ext" For Binary As #f

     get_long()

     get_array()

     get_mem()

   ' Close the file.  
   Close #f

   ' Load a small text file to a string

   Function LoadFile(ByRef filename As String) As String
      
      Dim h As Integer
      Dim txt As String
      
      h = FreeFile
      
      If Open( filename For Binary Access Read As #h ) <> 0 Then Return ""
      
      If LOF(h) > 0 Then
         
         txt = String(LOF(h), 0)
         If Get( #h, ,txt ) <> 0 Then txt = ""
         
      End If
      
      Close #h
      
      Return txt
      
   End Function

   Dim ExampleStr As String
   ExampleStr = LoadFile("smallfile.txt")
   Print ExampleStr

Differences from QB
   * Get in FB can read full arrays as in VB or, alternatively, read a 
     multiple of the data size into the memory.
   * Get can be used as a function in FB, to find the success/error code 
     returned without having to use error handling procedures.
   * FB allows the bytesread parameter, to check how many bytes have been 
     successfully read in.

See also
   * Get (Graphics) different usage of same keyword 
   * Put (File I/O)
   * Open
   * Close
   * Binary
   * Random
   * FreeFile
   * File I/O methods comparison



------------------------------------------------------ KeyPgGetjoystick ----
GetJoystick

Reads buttons and axis information from attached gaming devices

Syntax
   Declare Function GetJoystick ( ByVal id As Long, ByRef buttons As Integer
   = 0, ByRef a1 As Single = 0, ByRef a2 As Single = 0, ByRef a3 As Single 
   = 0, ByRef a4 As Single = 0, ByRef a5 As Single = 0, ByRef a6 As Single 
   = 0, ByRef a7 As Single = 0, ByRef a8 As Single = 0 ) As Integer

Usage
   result = GetJoystick( id[, buttons[, a1[, a2[, a3[, a4[, a5[, a6[, a7[, 
   a8]]]]]]]]] )

Parameters
   id
      the device id number (0 - 15)
   buttons
      the button status
   a1
      first axis value
   a2
      second axis value
   a3
      third axis value
   a4
      fourth axis value
   a5
      fifth axis value
   a6
      sixth axis value
   a7
      seventh axis value
   a8
      eighth axis value

Return Value
   0 on success or 1 on failure.  All of the axis positions are returned in 
   floating point format.

Description
   GetJoystick will retrieves the button state, and the axis positions for 
   up to 8 axes, for the joystick determined by id, a number between 0 and 
   15. Buttons are stored in a similar manner to GetMouse, with each bit in 
   buttons representing a button.

   A single precision value between -1.0 and 1.0 is returned for each valid 
   axis.  If the axis does not exist for the controller, a value of 
   -1000.00 is returned.

   GetJoystick will return 0 upon successful completion; It will return 1 
   upon failure. Failure can be caused by specifying an illegal joystick 
   number, specifying a joystick which doesn't exist, or a failure in the 
   joystick API.

   The error code returned by GetJoystick can be checked using Err in the 
   next line. The function version of  Getjoystick returns directly the 
   error code as a 32 bit Long.

Example
   Screen 12

   Dim x As Single
   Dim y As Single
   Dim buttons As Integer
   Dim result As Integer
   Dim a As Integer

   Const JoystickID = 0

   'This line checks to see if the joystick is ok.

   If GetJoystick(JoystickID,buttons,x,y) Then 
      Print "Joystick doesn't exist or joystick error."
      Print
      Print "Press any key to continue."
      Sleep
      End
   End If

   Do
      result = GetJoystick(JoystickID,buttons,x,y)

      Locate 1,1
      Print ;"result:";result;" x:" ;x;" y:";y;" Buttons:";buttons,"","",""
      
      'This tests to see which buttons from 1 to 27 are pressed. 
      For a = 0 To 26 
         If (buttons And (1 Shl a)) Then 
            Print "Button ";a;" pressed.    "
         Else 
            Print "Button ";a;" not pressed."
         End If
      Next a
   Loop

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Getjoystick.

Differences from QB
   * New to FreeBASIC

See also
   * Screen (Graphics)
   * SetMouse
   * GetMouse
   * MultiKey



----------------------------------------------------------- KeyPgGetkey ----
GetKey

Returns the ascii code of the first key in the keyboard buffer

Syntax
   Declare Function GetKey ( ) As Long

Usage
   result = GetKey

Return Value
   The value of the ascii code returned.

Description
   It returns the ascii code of the first key in the keyboard buffer. The 
   key is removed from the buffer. If no key is present, GetKey waits for 
   it.
   For extended keys (returning two characters), the extended code is 
   returned in the first byte, and the regular code is returned in the 
   second byte (the third and fourth bytes always being null at least in 
   console mode).
   WARNING: In graphics mode and depending on the key pressed,   Getkey   
   may not always return the exact same value as in console mode (for a 
   non-extended key, the most significant bit of the ascii code byte may be 
   propagated to the higher 3 bytes of the return value, such as a sign 
   bit).
   For a compatible code of the 2 screen modes, see the example below.

   The key read is not echoed to the screen.

   For a keyword not stopping the program if no key is at the buffer see 
   Inkey or MultiKey.

Example
   Dim As Long foo
   Do
      foo = GetKey
      Print "total return: " & foo
      
      If( foo > 255 ) Then
         Print "extended code: " & (foo And &hff)
         Print "regular code: " & (foo Shr 8)
      Else
         Print "regular code: " & (foo And &hff)
      End If
      Print 
   Loop Until foo = 27

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Getkey.

Differences from QB
   * New to FreeBASIC

See also
   * GetMouse
   * Inkey
   * Input()
   * MultiKey



--------------------------------------------------------- KeyPgGetmouse ----
GetMouse

Retrieves the status of the mouse pointing device

Syntax
   Declare Function GetMouse ( ByRef x As Integer, ByRef y As Integer, ByRef
   wheel As Integer = 0, ByRef buttons As Integer = 0, ByRef clip As Integer
   = 0 ) As Long

Usage
   result = GetMouse (x, y [, [ wheel ] [, [ buttons ] [, [ clip ]]]])

Parameters
   x
      x coordinate value
   y
      y coordinate value
   wheel
      scroll wheel value
   buttons
      button status
   clip
      clip status

Return Value
   0 on success, or 1 on error (for example because the mouse is outside 
   the graphic window) or on failure. (sets a runtime error)

Description
   GetMouse retrieves the mouse position and buttons status; information is 
   returned in the variables passed to this function by reference. If a 
   mouse is not available, all variables will contain the -1 value. 

   If in console mode, the x and y coordinates are the character cell 
   coordinates the mouse is currently on; the upper left corner of the 
   screen is at coordinates 0, 0. If the mouse moves out of the console 
   window, GetMouse returns the last coordinate on the window that the 
   mouse was on. If in console mode and fullscreen, the scroll wheel value 
   is not returned. 

   If in graphics mode, x and y will always be returned in pixel 
   coordinates still relative to the upper left corner of the screen, which 
   is at 0,0 in this case; custom coordinates system set via View or Window 
   do not affect the coordinates returned by GetMouse.
   If the mouse runs off the graphic window, all values are set to -1 and 
   the return value of the function is set to 1. This may result in 
   misinterpretation for the buttons and wheel if the return value of the 
   function is not also tested.

   Wheel is the mouse wheel counter; rotating the wheel away from you makes 
   the count to increase, rotating the wheel toward you makes it to 
   decrease. At program startup or when a new graphics mode is set via 
   Screen, wheel position is reset to 0. FreeBASIC may not always support 
   mouse wheels for a given platform, in which case 0 is always returned.

   Buttons stores the buttons status as a bitmask: bit 0 is set if left 
   mouse button is down; bit 1 is set if right mouse button is down; bit 2 
   is set if middle mouse button / wheel is down.

   Clip stores the mouse clipping status; if 1, the mouse is currently 
   clipped to the graphics window; if 0, the mouse is not clipped.

   The error code returned by GetMouse can be checked using Err in the next 
   line. The function version of  GetMouse returns directly the error code 
   as a 32 bit Long.

   Warning: When the flag GFX_SHAPED_WINDOW is set (see ScreenRes), 
   GetMouse is only active in any colored area, ie there where color <> 
   RGBA(255, 0, 255, alpha).

Example
   Dim As Integer x, y, buttons, res 
   ' Set video mode and enter loop
   ScreenRes 640, 480, 8
   Do
      ' Get mouse x, y and buttons. Discard wheel position.
      res = GetMouse (x, y, , buttons)
      Locate 1, 1
      If res <> 0 Then '' Failure

   #ifdef __FB_DOS__
         Print "Mouse or mouse driver not available"
   #else
         Print "Mouse not available or not on window"
   #endif

      Else
         Print Using "Mouse position: ###:###  Buttons: "; x; y;
         If buttons And 1 Then Print "L";
         If buttons And 2 Then Print "R";
         If buttons And 4 Then Print "M";
         Print "   "
      End If
   Loop While Inkey = ""
   End

   'Example 2: type-union-type structure
   Type mouse
      As Integer res
      As Integer x, y, wheel, clip
      Union
         buttons As Integer
         Type
            Left:1 As Integer
            Right:1 As Integer
            middle:1 As Integer
         End Type
      End Union
   End Type
    
   Screen 11
   Dim As mouse m

   Do
      m.res = GetMouse( m.x, m.y, m.wheel, m.buttons, m.clip )
      ScreenLock
      Cls
      Print Using "res = #"; m.res
      Print Using "x = ###; y = ###; wheel = +###; clip = ##"; m.x; m.y; m.wheel; m.clip
      Print Using "buttons = ##; left = #; middle = #; right = #"; m.buttons; m.left; m.middle; m.right
      ScreenUnlock
      Sleep 10, 1
   Loop While Inkey = ""

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Getmouse.  The variables passed must also be of type Long 
     instead of Integer.

Platform Differences
   * On Win32, scroll wheel changes are not guaranteed to be detected in 
     full-screen console mode. 
   * In DOS, the "clip" value has no relevance.  Additionally the wheel 
     and middle button will not work unless supported and enabled by the 
     mouse driver. See also FaqDOS.

Differences from QB
   * New to FreeBASIC

See also
   * ScreenRes setting graph mode by resolution
   * Screen (Graphics) setting mode the QB-like way
   * SetMouse
   * MultiKey
   * GetJoystick



------------------------------------------------------------ KeyPgGosub ----
GoSub

Control flow statement to use a section of code and return.

Syntax
   GoSub label

Description
   Execution jumps to a subroutine marked by a line label. Always use Return
   to exit a GoSub,  execution will continue  on next statement after GoSub
   . 

   The line label where GoSub jumps must be in the same main/function/sub 
   block as GoSub. All the variables in the subroutine are shared with the 
   block, no arguments can be used. For this reason Gosub is considered bad 
   programming practice as it can generate unreadable and untraceable code. 
   It is better to use Sub or Function instead.

Example
   '' Compile with -lang qb

   '$lang: "qb"

   GoSub message
   End

   message:
   Print "Welcome!"
   Return

Dialect Differences
   * Only available in the -lang qb and -lang fblite dialects.
   * GoSub support is disabled by default in the -lang fblite unless the 
     Option Gosub statement is used.

Differences from QB
   * None when using the -lang qb dialect.

See also
   * Goto
   * Return
   * Sub
   * Function
   * Option Gosub
   * Labels



------------------------------------------------------------- KeyPgGoto ----
Goto

Control flow statement to jump to another part of the program

Syntax
   Goto label

Description
   Jumps code execution to a line label.

   When using Goto label to exit a scope, any local variables defined in 
   that scope are destroyed (destructors are called).

   Usage of Goto label may be disallowed when it skips a variable 
   definition but not the end of the variable's scope. If the variable 
   requires construction, a compiler error is shown. For other variables, a 
   compiler warning is shown. This is intended to prevent potential 
   accesses to uninitialized variables, and ensures that automatic 
   destruction never happens to an uninitialized variable.

   For better source code readability, overuse of Goto should be avoided in 
   favor of more modern structures such as Do...Loop, For...Next, Sub, and 
   Function.

Example
      Goto there

   backagain:
      End

   there:
      Print "Welcome!"
      Goto backagain

   '' Compile with -lang qb or fblite

   '$lang: "qb"

   1 Goto 3
   2 End
   3 Print "Welcome!"
   4 Goto 2

Dialect Differences
   * Line numbers are allowed only in the -lang qb and -lang deprecated 
     dialects.
   * In the -lang qb and -lang fblite dialects, Goto label is allowed to 
     skip any variable definitions, because nested scopes are not supported 
     and all variable definitions are moved to the top of their procedure.

Differences from QB
   * None

See also
   * GoSub
   * Sub
   * Function
   * Labels




============================================================================
    H

-------------------------------------------------------------- KeyPgHex ----
Hex

Returns the hexadecimal of the given number

Syntax
   Declare Function Hex ( ByVal number As UByte ) As String
   Declare Function Hex ( ByVal number As UShort ) As String
   Declare Function Hex ( ByVal number As ULong ) As String
   Declare Function Hex ( ByVal number As ULongInt ) As String
   Declare Function Hex ( ByVal number As Const Any Ptr ) As String

   Declare Function Hex ( ByVal number As UByte, ByVal digits As Long ) As 
   String
   Declare Function Hex ( ByVal number As UShort, ByVal digits As Long ) As 
   String
   Declare Function Hex ( ByVal number As ULong, ByVal digits As Long ) As 
   String
   Declare Function Hex ( ByVal number As ULongInt, ByVal digits As Long ) 
   As String
   Declare Function Hex ( ByVal number As Const Any Ptr, ByVal digits As 
   Long ) As String

Usage
   result = Hex[$]( number [, digits ] )

Parameters
   number
      A number or expression evaluating to a number.  A floating-point 
      number will be converted to a LongInt.
   digits
      Optional number of digits to return.

Return Value
   A String containing the unsigned hexadecimal representation of number.

Description
   Returns the unsigned hexadecimal string representation of the integer 
   number. Hexadecimal digits range from 0-9, or A-F.

   If you specify digits > 0, the result string will be exactly that 
   length.  It will be truncated or padded with zeros on the left, if 
   necessary.

   The length of the string will not go longer than the maximum number of 
   digits required for the type of number (8 for a Long, 16 for a LongInt).

   If you want to do the opposite, i.e. convert a hexadecimal string back 
   into a number, the easiest way to do it is to prepend the string with 
   "&H", and convert it to an integer type, using a function like CInt, 
   similarly to a normal numeric string.  E.g. CInt("&HFF")

Example
   '54321 is D431 in hex
   Print Hex(54321)
   Print Hex(54321, 2)
   Print Hex(54321, 5)

   will produce the output:

   D431
   31
   0D431

Dialect Differences
   * The string type suffix "$" is obligatory in the -lang qb dialect.
   * The string type suffix "$" is optional in the -lang fblite dialect.
   * The string type suffix "$" is forbidden in the -lang fb dialect.

Differences from QB
   * In QBASIC, there was no way to specify the number of digits returned.
   * The size of the string returned was limited to 32 bits, or 8 
     hexadecimal digits.

See also
   * Bin
   * Oct
   * ValInt
   * ValLng



----------------------------------------------------------- KeyPgHibyte ----
HiByte

Gets the second byte of the operand.

Syntax
   #define HiByte( expr ) ((Cast(UInteger, expr) And &h0000FF00) Shr 8)

Usage
   result = HiByte( expr )

Parameters
   expr
      A numeric expression, converted to an UInteger value.

Return Value
   Returns the value of the high byte of the low 16bit word of expr.

Description
   This macro converts the numeric expression expr to an UInteger value, 
   then expands to an UInteger representing the value of its second byte - 
   that is the most-significant (high) byte of the least-significant (low) 
   16bit word of expr.

Example
   Dim N As UInteger

   'Note there are 16 bits
   N = &b1010101110000001
   Print "N is                                       "; N
   Print "The binary representation of N is          "; Bin(N)
   Print "The most significant byte (MSB) of N is    "; HiByte(N)
   Print "The least significant byte (LSB) of N is   "; LoByte(N)
   Print "The binary representation of the MSB is    "; Bin(HiByte(N))
   Print "The binary representation of the LSB is    "; Bin(LoByte(N))
   Sleep

The output would look like:

   N Is                                       43905
   The Binary representation of N Is          1010101110000001
   The most significant Byte (MSB) of N Is    171
   The least significant Byte (LSB) of N Is   129
   The Binary representation of the MSB Is    10101011
   The Binary representation of the LSB Is    10000001

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __HIBYTE.

Differences from QB
   * New to FreeBASIC

See also
   * LoByte
   * LoWord
   * HiWord



----------------------------------------------------------- KeyPgHiword ----
HiWord

Gets the second 16bit word of the operand.

Syntax
   #define HiWord( expr ) ((Cast(UInteger, expr) and &hFFFF0000) Shr 16)

Usage
   result = HiWord( expr )

Parameters
   expr
      A numeric expression, converted to an UInteger value.

Return Value
   Returns the value of the high 16bit word of the low 32bit dword of expr.

Description
   This macro converts the numeric expression expr to an UInteger value, 
   then expands to an UInteger representing the value of its second 16bit 
   word - that is the most-significant (high) 16bit word of the 
   least-significant (low) 32bit dword of expr.

Example
   Dim N As UInteger

   'Note there are 32 bits
   N = &b10000000000000011111111111111111

   Print "N is                                       "; N
   Print "The binary representation of N is          "; Bin(N)
   Print "The most significant word (MSW) of N is    "; HiWord(N)
   Print "The least significant word (LSW) of N is   "; LoWord(N)
   Print "The binary representation of the MSW is    "; Bin(HiWord(N))
   Print "The binary representation of the LSW is    "; Bin(LoWord(N))

   Sleep

The output would look like:

   N Is                                       2147614719
   The Binary representation of N Is          10000000000000011111111111111111
   The most significant word (MSW) of N Is    32769
   The least significant word (LSW) of N Is   65535
   The Binary representation of the MSW Is    1000000000000001
   The Binary representation of the LSW Is    1111111111111111

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __HIWORD.

Differences from QB
   * New to FreeBASIC

See also
   * LoByte
   * HiByte
   * LoWord



------------------------------------------------------------- KeyPgHour ----
Hour

Gets the hour of day from a Date Serial 

Syntax
   Declare Function Hour ( ByVal date_serial As Double ) As Long

Usage
   #include "vbcompat.bi"
   result = Hour( dateserial )

Parameters
   date_serial
      the date serial

Return Value
   Returns the hour from a variable containing a date in Date Serial 
   format.

Description
   The compiler will not recognize this function unless vbcompat.bi is 
   included.

Example
   #include "vbcompat.bi"

   Dim ds As Double = DateSerial(2005, 11, 28) + TimeSerial(7, 30, 50)

   Print Format(ds, "yyyy/mm/dd hh:mm:ss "); Hour(ds)

Differences from QB
   * Did not exist in QB. This function appeared in PDS and VBDOS

See also
   * Date Serials




============================================================================
    I

----------------------------------------------------------- KeyPgIfthen ----
If...Then

Control flow statement for conditional branching

Syntax
   If expression Then [statement(s)] [Else [statement(s)]] [End If]
or
   If expression Then : [statement(s)] [Else [statement(s)]] : End If
or
   If expression Then
      [statement(s)]
   [ ElseIf expression Then ]
      [statement(s)]
   [ Else ]
      [statement(s)]
   End If

   Remark: EndIf (without blank) is also supported like in QB for backward 
   compatibility.

Description
   If...Then is a way to make decisions.
   It is a mechanism to execute code only if a condition is true, and can 
   provide alternative code to execute based on more conditions:
      * Execute code (just behind Then) if a condition is true.
      * Execute certain code (just behind Then) if a condition is true and 
        execute other (just behind Else) if it's false.
      * Test other conditions (with ElseIf) if the first condition is 
        false.

   expression can be one of several forms:
      * a conditional expression, for example:
         x = 5
      * multiple conditions separated by logical bit-wise operators, for 
        example:
         x >= 5 And x <= 10
      * multiple conditions separated by logical short-circuit operators, 
        for example:
         y <> 0 AndAlso x \ y = 1
         (in this case, "x \ y = 1" will only be evaluated if "y <> 0" is 
         True)
      * any numerical expression, in which case a value of zero (0) 
        represents False, and a non-zero value represents True

   Both multi-line and single-line Ifs can be nested.  In the latter case, 
   the optional End Ifs can be useful to control where nested Ifs begin and 
   end.

   The multi-line syntax allows several Elseifs (but none after a Else) and 
   tests can be nested (there must be in this case as many End Ifs as Ifs).
   If the condition of the If is not true, those of Elseifs blocks are 
   tested in succession:
      * If either of these is true, the corresponding code is executed, 
        then the program skips the following blocks to continue after the 
        End If.
      * If none are true, the code following the Else (if exists) is 
        executed alone.

   In the -lang fb and -lang fblite dialects, colons (:) can be used 
   instead of newlines to construct multi-line If blocks on a single line.

   Note: The single-line syntax If...Goto, as shortcut for If...Then Goto, 
   is deprecated and it only exists for compatibility with QB.

Example
   '' Here is a simple "guess the number" game using if...then for a decision.

   Dim As Integer num, guess

   Randomize
   num = Int(Rnd * 10) + 1 'Create a random number between 1 and 10...
               
   Print "guess the number between 1 and 10 (or CTRL-C to abort)"

   Do 'Start a loop

      Input "Guess"; guess 'Input a number from the user

      If guess > 10 OrElse guess < 1 Then  'The user's guess is out of range
         Print "The number can't be greater then 10 or less than 1!"
      ElseIf guess > num Then  'The user's guess is too high
         Print "Too high"
      ElseIf guess < num Then  'The user's guess is too low
         Print "Too low"
      Else                     'The user guessed the right number!
         Print "Correct!"
         Exit Do   'Exit the loop
      End If

   Loop 'Go back to the start of the loop

   Sleep

Dialect Differences
   * In the -lang qb and -lang fblite dialects, variables declared inside 
     an If..Then block have a procedure-wide scope  as in QB 
   * In the -lang fb and -lang deprecated dialects, variables declared 
     inside an If..Then block are visible only inside the block, and cannot 
     be accessed outside it.
   * In the -lang qb dialect, if there is a new line or a single-line 
     comment (') directly after THEN, then the IF will be multi-line.  A 
     colon, a Rem or any other statement will result in a single-line IF.
   * In the -lang fb and -lang fblite dialects, if there is a new line, a 
     single-line comment ('), a colon (:), or a Rem statement directly 
     after THEN, then the IF will be multi-line.  Any other statement will 
     result in a single-line IF.

Differences from QB
   * END IF was not supported in single-line IFs in QBASIC.

See also
   * ElseIf
   * Do...Loop
   * #if
   * Select Case



-------------------------------------------------------------- KeyPgIif ----
IIf

Conditional function that returns one of two values.

Syntax
   IIf ( condition, expr_if_true, expr_if_false )

Parameters
   condition
      The condition to test.
      A non-zero value evaluates as true, while a value of zero evaluates 
      as false.
   expr_if_true
      An expression to evaluate and return if condition is true.
      It must return:
         * a numeric value, which can be an integer, floating point number 
           or a pointer, including Boolean,
         * or a string value,
         * or an UDT value.
   expr_if_false
      An expression to evaluate and return if condition is false.
      It must be same type as expr_if_true (either numeric, either string 
      or UDT).

Return Value
   if condition is non-zero, expr_if_true, otherwise expr_if_false

Description
   IIf returns a different numeric or string or UDT value (not a reference) 
   depending of the result of a conditional expression evaluated at 
   run-time. Its typical use is in the middle of an expression; it avoids 
   splitting it to put a conditional in the middle.

   IIf only evaluates the expression that it needs to return.  This saves 
   time, and can also be useful to prevent evaluating expressions that 
   might be invalid depending on the condition.

   When IIf treats expressions of mixed numeric types (conditional 
   expression evaluated at run-time):
      * if at least one expression is of floating-point type, the result 
        type is the floating-point type (the bigger in case of two 
        floating-point types),
      * if the two expressions are of integer types, the result type is 
        the bigger type of both (see Coercion and Conversion for the 
        precise ranking of integer types).

Example
   Dim As Integer a, b, x, y, z
   a = (x + y + IIf(b > 0, 4, 7)) \ z

is equivalent to:
   Dim As Integer a, b, x, y, z, temp
   If b > 0 Then temp = 4 Else temp = 7
   a = (x + y + temp) \ z

   Dim As Integer I
   I = -10
   Print I, IIf(I>0, "positive", IIf(I=0, "null", "negative"))
   I = 0
   Print I, IIf(I>0, "positive", IIf(I=0, "null", "negative"))
   I = 10
   Print I, IIf(I>0, "positive", IIf(I=0, "null", "negative"))
   Sleep

   Type UDT1
     Dim As Integer I1
   End Type

   Type UDT2 Extends UDT1
     Dim As Integer I2
   End Type

   Dim As UDT1 u1, u10 = (1)
   Dim As UDT2 u2, u20 = (2, 3)

   u1 = IIf(0, u10, u20)
   Print u1.I1
   u1 = IIf(1, u10, u20)
   Print u1.I1

   u2 = IIf(0 , u10, u20)
   Print u2.I1; u2.I2
   'u2 = Iif(1, u10, u20) ''Invalid assignment/conversion
   Sleep

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Iif.

Differences from QB
   * New to FreeBASIC

See also
   * If...Then



-------------------------------------------------- KeyPgImageConvertRow ----
ImageConvertRow

Converts a row of image data into another color depth

Syntax
   Declare Sub ImageConvertRow ( ByVal src As Any  Ptr, ByVal src_bpp As 
   Long, ByVal dst As Any  Ptr, ByVal dst_bpp As Long, ByVal width As Long, 
   ByVal isrgb As Long = 1 )

Usage
   ImageConvertRow( src, src_bpp, dst, dst_bpp, width [, isrgb ] )

Parameters
   src
      The address of the start of the source row.  The source can either be 
      a full-color image with a bit depth of 24 or 32 bits per pixel, or a 
      paletted image with a bit depth of 1-8 bits per pixel.  Converting a 
      paletted image will only work properly if you are in a screen mode 
      that is using the correct palette for the image when you do the 
      conversion.
   src_bpp
      The number of bits per pixel in the source row.  1-8, 24 and 32.
   dst
      The address of the start of the destination row.  The image can be a 
      full-color image of 16 or 32 bits per pixel.  If the source is a 
      paletted image, the destination can also be a paletted image of 1 to 
      8 bits per pixel.
   dst_bpp
      The number of bits per pixel in the destination row.  Valid values 
      for this are 1-8, 16 and 32.
   width
      The length of the row in pixels.
   isrgb
      A value of zero indicates that the Red and Blue channels are the 
      other way round in the source image.  Use this switch if you want the 
      Red and Blue channels to be swapped in the conversion.

Description
   Copies the row of an image from one memory location to another, 
   converting the color information in each pixel to match the destination 
   image.

Example
   #include "fbgfx.bi"
   #if __FB_LANG__ = "fb"
   Using FB
   #endif

   Const As Integer w = 64, h = 64
   Dim As IMAGE Ptr img8, img32
   Dim As Integer x, y

   '' create a 32-bit image, size w*h:
   ScreenRes 1, 1, 32, , GFX_NULL
   img32 = ImageCreate(w, h)

   If img32 = 0 Then Print "Imagecreate failed on img32!": Sleep: End

   '' create an 8-bit image, size w*h:
   ScreenRes 1, 1, 8, , GFX_NULL
   img8 = ImageCreate(w, h)

   If img8 = 0 Then Print "Imagecreate failed on img8!": Sleep: End

   '' fill 8-bit image with a pattern
   For y = 0 To h - 1
      For x = 0 To w - 1
         PSet img8, (x, y), 56 + (x + y) Mod 24
      Next x
   Next y

   '' open a graphics window in 8-bit mode, and PUT the image into it:
   ScreenRes 320, 200, 8
   WindowTitle "8-bit color mode"
   Put (10, 10), img8

   Sleep

   '' copy the image data into a 32-bit image
   Dim As Byte Ptr p8, p32
   Dim As Integer pitch8, pitch32

   #ifndef ImageInfo '' older versions of FB don't have the ImageInfo feature
   #define GETPITCH(img_) IIf(img_->Type=PUT_HEADER_NEW,img_->pitch,img_->old.width*img_->old.bpp)
   #define GETP(img_) CPtr(Byte Ptr,img_)+IIf(img_->Type=PUT_HEADER_NEW,SizeOf(PUT_HEADER),SizeOf(_OLD_HEADER))
   pitch8 = GETPITCH(img8): p8 = GETP(img8)
   pitch32 = GETPITCH(img32): p32 = GETP(img32)
   #else
   ImageInfo( img8,  , , , pitch8,  p8  )
   ImageInfo( img32, , , , pitch32, p32 )
   #endif

   For y = 0 To h - 1
      ImageConvertRow(@p8 [ y * pitch8 ],  8, _
                  @p32[ y * pitch32], 32, _
                  w)
   Next y

   '' open a graphics window in 32-bit mode and PUT the image into it:
   ScreenRes 320, 200, 32
   WindowTitle "32-bit color mode"
   Put (10, 10), img32

   Sleep

   '' free the images from memory:
   ImageDestroy img8
   ImageDestroy img32

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __ImageConvertRow.

Differences from QB
   * New to FreeBASIC

See also
   * ScreenRes
   * Get (Graphics)
   * Put (Graphics)
   * ImageCreate
   * ImageDestroy
   * ImageInfo



------------------------------------------------------ KeyPgImagecreate ----
ImageCreate

Allocates and initializes storage for an image

Syntax
   Declare Function ImageCreate ( ByVal width As Long, ByVal height As Long
   , ByVal color As ULong = transparent_color ) As Any Ptr
   Declare Function ImageCreate ( ByVal width As Long, ByVal height As Long
   , ByVal color As ULong = transparent_color, ByVal depth As Long ) As Any 
   Ptr

Usage
   result = ImageCreate( width, height [, [ color ][, depth ]] )

Parameters
   width
      The desired width, in number of pixels.
   height
      The desired height, in number of pixels.
   color
      The pixel value to fill the area of the image.
   depth
      The desired color depth, in bits per pixel.

Return Value
   If the image could not be created, NULL (0) is returned, otherwise, the 
   address of the image is returned. ImageCreate must be called after 
   graphic mode initialization, else it returns 0.

   Consequently, in case of Shared variable declaration, ImageCreate cannot 
   be used as integrated initializer, even inside an Udt (in member field 
   or constructor), because the initialization value (of shared variable) 
   is set at the start of the program before any user code is run. The 
   image allocation call must be in a separated executable instruction, and 
   after the graphic mode initialization.

Description
   Both procedures attempt to allocate memory for an image of the specified 
   width and height. If not successful, NULL (0) is returned. Otherwise, an 
   image of that size is created and initialized by filling the entire area 
   of pixels with the value color. If not specified, color assumes the 
   value of the transparent color for the current graphics screen, which 
   can be found by calling ScreenControl. In any case, the address of the 
   image is returned, which is then controlled by the user, and must be 
   destroyed using ImageDestroy.

   The first procedure creates an image with a color depth matching that of 
   the current graphics screen, which can be found by calling ScreenControl
   . The second procedure creates an image with a color depth of depth, in 
   bits per pixel. For both procedures, the resulting image can be used in 
   drawing procedures while in any screen mode -- and across mode changes 
   -- as long as the color depth of the image matches that of the graphics 
   screen.

   ImageCreate is the recommended way to allocate memory for new images. 
   The memory layout -- size, structure, etc. -- while documented, may 
   change from version to version, making manual calculation of the sizes 
   involved error-prone. However, ImageInfo can be used to retrieve, among 
   other things, the size, in bytes, of an existing image, allowing memory 
   to be manually allocated for a copy of an image, or to be read from or 
   written to a file or device.

   Get (Graphics) can be used to initialize an image using pre-allocated 
   memory.

Example
   '' Create a graphics screen.
   ScreenRes 320, 200, 32

   '' Create a 64x64 pixel image with a darkish green background.
   Dim image As Any Ptr = ImageCreate( 64, 64, RGB(0, 128, 0) )

   If image = 0 Then
      Print "Failed to create image."
      Sleep
      End -1
   End If

   '' Draw a semi-transparent, red circle in the center of the image.
   Circle image, (32, 32), 28, RGBA(255, 0, 0, 128),,, 1.0, f

   '' Draw the image onto the screen using various blitting methods.
   Put (120, 60), image, PSet
   Put (140, 80), image, Alpha

   '' Destroy the image.
   ImageDestroy image

   Sleep

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Imagecreate.

Differences from QB
   * New to FreeBASIC

See also
   * ImageDestroy
   * ImageInfo
   * Get (Graphics)
   * Internal pixel formats



----------------------------------------------------- KeyPgImageDestroy ----
ImageDestroy

Destroys and deallocates storage for an image

Syntax
   Declare Sub ImageDestroy ( ByVal image As Any Ptr )

Usage
   ImageDestroy( image )

Parameters
   image
      The address of the image to destroy.

Description
   Destroys the image pointed to by image, which must be an address 
   returned from a call to ImageCreate.

   Calling ImageDestroy on a null pointer induces no action.

Example
   See ImageCreate for an example on using ImageDestroy.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Imagedestroy.

Differences from QB
   * New to FreeBASIC

See also
   * ImageCreate



-------------------------------------------------------- KeyPgImageInfo ----
ImageInfo

Retrieves information about an image

Syntax
   Declare Function ImageInfo ( ByVal image As Any Ptr, ByRef width As 
   Integer = 0, ByRef height As Integer = 0, ByRef bypp As Integer = 0, 
   ByRef pitch As Integer = 0, ByRef pixdata As Any Ptr = 0, ByRef size As 
   Integer = 0 ) As Long

Usage
   result = ImageInfo( image [, [width] [, [height] [, [bypp] [, [pitch] [, 
   [pixdata] [, size]]]]]] )

Parameters
   image
      The address of the image.
   width
      Stores the width of the image, in pixels.
   height
      Stores the height of the image, in pixels.
   bypp
      Stores the bytes per pixel of the image - i.e. the size of a single 
      pixel, in bytes.
   pitch
      Stores the pitch of the image - i.e. the size of each scanline (row), 
      in bytes.  Note that this may be more than just width * bypp, because 
      the scanlines may be padded to allow them to be aligned better in 
      memory.
   pixdata
      Stores the address of the start of the first scanline of the image.
   size
      Stores the size of the image in memory, in bytes.

Return Value
   If image doesn't point to a valid image, one (1) is returned. Otherwise, 
   width, height, bypp, pitch, pixdata and size are assigned appropriate 
   values, and zero (0) is returned.

Description
   ImageInfo provides various information about an image, such as its 
   dimensions and color depth, but also provides you with the information 
   you need to directly access all the pixel data in the pixel buffer.

   It can also provide the size of the image in memory, which is useful for 
   allocating memory to copy the existing image, or to write the image to a 
   file.

   The error code returned by ImageInfo can be checked using Err in the 
   next line. The function version of  ImageInfo returns directly the error 
   code as a 32 bit Long.

Example
   '' pixelptr(): use imageinfo() to find the pointer to a pixel in the image
   '' returns null on error or x,y out of bounds
   Function pixelptr(ByVal img As Any Ptr, ByVal x As Integer, ByVal y As Integer) As Any Ptr

      Dim As Integer w, h, bypp, pitch
      Dim As Any Ptr pixdata
      Dim As Integer success
      
      success = (ImageInfo(img, w, h, bypp, pitch, pixdata) = 0)
      
      If success Then
         If x < 0 Or x >= w Then Return 0
         If y < 0 Or y >= h Then Return 0
         Return pixdata + y * pitch + x * bypp
      Else
         Return 0
      End If
      
   End Function

   '' usage example:

   '' 320*200 graphics screen, 8 bits per pixel
   ScreenRes 320, 200, 8

   Dim As Any Ptr ip '' image pointer

   Dim As Byte Ptr pp '' pixel pointer (use byte for 8 bits per pixel)

   ip = ImageCreate(32, 32) '' create an image (32*32, 8 bits per pixel)

   If ip <> 0 Then

      '' draw a pattern on the image
      For y As Integer = 0 To 31

         For x As Integer = y - 5 To y + 5 Step 5

            '' find the pointer to pixel at x,y position
            '' note: this is inefficient to do for every pixel!
            pp = pixelptr(ip, x, y)

            '' if success, plot a value at the pixel
            If (pp <> 0) Then *pp = 15

         Next x

      Next y

      '' put the image and draw a border around it
      Put (10, 10), ip, PSet
      Line (9, 9)-Step(33, 33), 4, b

      '' destroy the image to reclaim memory
      ImageDestroy ip

   Else
      Print "Error creating image!"
   End If

   Sleep

   '' Create 32-bit graphics screen and image.
   ScreenRes 320, 200, 32
   Dim image As Any Ptr = ImageCreate( 64, 64 )

   Dim pitch As Integer
   Dim pixels As Any Ptr

   '' Get enough information to iterate through the pixel data.
   If 0 <> ImageInfo( image, ,,, pitch, pixels ) Then
      Print "unable to retrieve image information."
      Sleep
      End
   End If

   '' Draw a pattern on the image by directly manipulating pixel memory.
   For y As Integer = 0 To 63
      Dim row As ULong Ptr = pixels + y * pitch
      
      For x As Integer = 0 To 63
         row[x] = RGB(x * 4, y * 4, (x Xor y) * 4)
      Next x
   Next y

   '' Draw the image onto the screen.
   Put (10, 10), image

   ImageDestroy( image )

   Sleep

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Imageinfo.

Differences from QB
   * New to FreeBASIC

See also
   * ImageCreate
   * ImageDestroy
   * ImageConvertRow
   * Get (Graphics)
   * Put (Graphics)
   * Internal pixel formats



------------------------------------------------------------ KeyPgOpImp ----
Operator Imp (Implication)

Returns the bitwise-and (implication) of two numeric values

Syntax
   Declare Operator Imp ( ByRef lhs As T1, ByRef rhs As T2 ) As Ret

Usage
   result = lhs Imp rhs

Parameters
   lhs
      The left-hand side expression.
   T1
      Any numeric or boolean type.
   rhs
      The right-hand side expression.
   T2
      Any numeric or boolean type.
   Ret
      A numeric or boolean type (varies with T1 and T2).

Return Value
   Returns the bitwise-implication of the two operands.

Description
   This operator returns the bitwise-implication of its operands, a logical 
   operation that results in a value with bits set depending on the bits of 
   the operands (for conversion of a boolean to an integer, false or true 
   boolean value becomes 0 or -1 integer value).

   The truth table below demonstrates all combinations of a 
   boolean-implication operation:

      +-------+-------+------+
      |Lhs Bit|Rhs Bit|Result|
      |0      |0      |1     |
      |1      |0      |0     |
      |0      |1      |1     |
      |1      |1      |1     |
      +-------+-------+------+

   No short-circuiting is performed - both expressions are always 
   evaluated.

   The return type depends on the types of values passed. Byte, UByte and 
   floating-point type values are first converted to Integer. If the left 
   and right-hand side types differ only in signedness, then the return 
   type is the same as the left-hand side type (T1), otherwise, the larger 
   of the two types is returned. Only if the left and right-hand side types 
   are both Boolean, the return type is also Boolean.

   This operator can be overloaded for user-defined types.

Example
   Dim As UByte a, b, c
   a = &b00001111
   b = &b01010101
   c = a Imp b '' c = &b11110101

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * None

See also
   * Operator Truth Tables



------------------------------------------------------- KeyPgImplements ----
Implements

Specifies an interface to be implemented by a user-defined type
   Note: Stub page. Even though this keyword is reserved already, 
   interfaces are not implemented yet.

Syntax
   Type typename Implements interface
      ...
   End Type

Description

Example

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Implements.

Differences from QB
   * New to FreeBASIC

See also
   * Type
   * Extends
   * Extends Zstring
   * Extends Wstring



----------------------------------------------------------- KeyPgImport ----
Import

External linkage attribute for public data located in DLL's

Syntax
   Extern Import symbolname[( subscripts)] [ Alias "aliasname"] [ As 
   DataType] [, ...]

Description
   Is used only on Win32 platforms with the Extern keyword and is needed to 
   access global variables in DLLs.  This is due to the level of 
   indirection on any such access: an implicit pointer dereference.

Example

   /* mydll.c :
   	compile With
   	  gcc -Shared -Wl,--strip-all -o mydll.dll mydll.c
   */
   __declspec( dllexport ) Int MyDll_Data = 0x1234;

   /'  import.bas :
   	Compile with
   	  fbc import.bas
   '/
   #inclib "mydll"

   Extern Import MyDll_Data Alias "MyDll_Data" As Integer

   Print "&h" + Hex( MyDll_Data )

   ' Output:
   ' &h1234

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Import.

Differences from QB
   * New to FreeBASIC

See also
   * Extern



------------------------------------------------------------ KeyPgInkey ----
Inkey

Returns a string representing the first key waiting in the keyboard buffer

Syntax
   Declare Function Inkey ( ) As String

Usage
   result = Inkey[$]

Return Value
   The first character found in the keyboard buffer, or an empty string (""
   ) if none found.

Description
   Peeks into the keyboard buffer and returns a String representation of 
   the first character, if any, found. The key is then removed from the 
   buffer, and is not echoed to the screen. If the keyboard buffer is 
   empty, an empty string ("") is immediately returned without waiting for 
   keys.

   If the key is in the ASCII character set, a one-character String 
   consisting of that character is returned. If the key is an "extended" 
   one (numeric pad, cursors, functions) a two-character String is 
   returned, the first of which is the extended character  (See dialect 
   differences below)

   The Shift, Ctrl, Alt, and AltGr keys can't be read independently by this 
   function as they never enter the keyboard buffer (although, perhaps 
   obviously, Shift-A will be reported by Inkey differently than Control-A 
   et cetera; Alt-A is an extended key a la the above).

   See also Input() or GetKey, or Sleep to wait for a key press if the 
   keyboard buffer is empty.

Example
   Print "press q to quit"
   Do
      Sleep 1, 1
   Loop Until Inkey = "q"

   '' Compile with -lang fblite or qb

   #lang "fblite"

   #if __FB_LANG__ = "qb"
   #define EXTCHAR Chr$(0)
   #else
   #define EXTCHAR Chr(255)
   #endif

   Dim k As String

   Print "Press a key, or Escape to end"
   Do

      k = Inkey$

      Select Case k

         Case "A" To "Z", "a" To "z": Print "Letter: " & k
         Case "1" To "9":             Print "Number: " & k

         Case Chr$(32): Print "Space"

         Case Chr$(27): Print "Escape"

         Case Chr$(9): Print "Tab"

         Case Chr$(8): Print "Backspace"

         Case Chr$(32) To Chr$(127)
            Print "Printable character: " & k

         Case EXTCHAR & "G": Print "Up Left / Home"
         Case EXTCHAR & "H": Print "Up"
         Case EXTCHAR & "I": Print "Up Right / PgUp"

         Case EXTCHAR & "K": Print "Left"
         Case EXTCHAR & "L": Print "Center"
         Case EXTCHAR & "M": Print "Right"

         Case EXTCHAR & "O": Print "Down Left / End"
         Case EXTCHAR & "P": Print "Down"
         Case EXTCHAR & "Q": Print "Down Right / PgDn"

         Case EXTCHAR & "R": Print "Insert"
         Case EXTCHAR & "S": Print "Delete"

         Case EXTCHAR & "k": Print "Close window / Alt-F4"

         Case EXTCHAR & Chr$(59) To EXTCHAR & Chr$(68)
            Print "Function key: F" & Asc(k, 2) - 58

         Case EXTCHAR & Chr$(133) To EXTCHAR & Chr$(134)
            Print "Function key: F" & Asc(k, 2) - 122

         Case Else
            If Len(k) = 2 Then
               Print Using "Extended character: chr$(###, ###)"; Asc(k, 1); Asc(k, 2)
            ElseIf Len(k) = 1 Then
               Print Using "Character chr$(###)"; Asc(k)
            End If

      End Select

      If k = Chr$(27) Then Exit Do

      Sleep 1, 1

   Loop

Dialect Differences
   * The extended character is Chr(255) in the -lang fb and -lang fblite 
     dialects.
      * In the -lang qb dialect, the extended character depends on how the 
        keyword is written. If the QB form Inkey$ is used, the extended 
        character is Chr(0).  If it is referenced as __Inkey, the extended 
        char is Chr(255).
      * In all other dialects, the extended char is always Chr(255).
   * The string type suffix "$" is obligatory in the -lang qb dialect.
   * The string type suffix "$" is optional in the -lang fblite dialect.
   * The string type suffix "$" is forbidden in the -lang fb dialect.

Differences from QB
   * None in the -lang qb dialect.
   * QBasic returned a Chr(0) as the first character for an extended key, 
     but FreeBASIC returns Chr(255) as the first character in the -lang fb 
     and -lang fblite dialects.

See also
   * Sleep
   * GetKey
   * Input()
   * MultiKey



-------------------------------------------------------------- KeyPgInp ----
Inp

Returns a value at a hardware port.

Syntax
   Declare Function Inp ( ByVal port As UShort ) As Integer

Usage
   value = Inp(port)

Parameters
   port
      Port number to read.

Return Value
   The value at the specified port.

Description
   This function retrieves the value at 'port' and returns immediately.

Example
   '' Turn off PC speaker
   Out &h61,Inp(&h61) And &hfc

	

Platform Differences
   * In the Windows and Linux versions three port numbers (&H3C7, &H3C8, 
     &H3C9) are hooked by the graphics library when a graphics mode is in 
     use to emulate QB's VGA palette handling. This use is deprecated; use 
     Palette to retrieve and set palette colors.

   * Using true port access in the Windows version requires the program to 
     install a device driver for the present session. For that reason, 
     Windows executables using hardware port access should be run with 
     administrator permits each time the computer is restarted. Further 
     runs don't require admin rights as they just use the already installed 
     driver. The driver is only 3K in size and is embedded in the 
     executable.

See also
   * Out
   * Wait
   * Palette

   


------------------------------------------------------------ KeyPgInput ----
Input

Reads a list of values from the keyboard

Syntax
   Input [;] ["prompt" ,|; ] variable_list

Parameters
   prompt
      an optional string literal that is written to the screen as a prompt. 
      If it is followed by a semicolon (;), a question mark ("? ") will be 
      appended to the prompt.  If it is followed by a comma, nothing will 
      be appended.
   variable_list
      a list of comma-separated variables used to hold the values read from 
      the user.

Description
   Reads a list values from the keyboard up until the first carriage 
   return. Numerical values are converted from their string representation 
   into the corresponding types in the variable list. Characters are echoed 
   to the screen as they are typed.

   If there is more than one value in the input list, then the input line 
   will be split up by scanning for delimiters - commas (,) after strings, 
   or commas and whitespace after numbers.  Surrounding whitespace will be 
   trimmed from string values. If an input string has a comma in it, it 
   must be wrapped in quotes ("...") to prevent it being split up.
   For inputting to a single string without delimiting, Line Input should 
   be used instead.

   The prompt - if any - is written to the screen at the current cursor 
   location, and characters read are echoed to the screen immediately 
   following the prompt. If no prompt is specified, characters are echoed 
   at the current cursor location.

   The optional leading semicolon (;) after Input is similar to the 
   optional trailing semicolon in a Print statement: the cursor will remain 
   on the same line after all of the characters have been echoed, 
   otherwise, the cursor will move to the beginning of the next line.

   If more values are read than are listed in the variable list, extra 
   values will be ignored; if fewer values are read (i.e. the user presses 
   enter before inputting all values), the remaining variables will be 
   initialized (numeric variables to zero (0), and string variables to the 
   empty string ("")).

   Numeric values are converted using methods similar to the procedures Val 
   and ValLng, using the most appropriate function for the number format, 
   converting as many numeric characters as possible.

   Input has a limited edit capacity: it allows to erase characters using 
   the backspace key.  If a better user interface is needed, a custom input 
   routine should be used.

Example

   Example #1
   Dim user_name As String, user_age As Integer

   Input "Enter your name and age, separated by a comma: ", user_name, user_age

   Print "Your name is " & user_name & ", and you are " & user_age & " years old."

   Example #2
   Dim As Double a, b
   Dim As String yn

   Do
      
      Input   "Please enter a number: ", a
      Input ; "And another: ", b
      Print , "Thank you"
      Sleep 500
      Print
      Print "The total is "; a + b
      Print
      
      Do
         Input "Would you like to enter some more numbers"; yn
         yn = LCase(yn)
      Loop Until yn = "y" Or yn = "n"
      
   Loop While LCase(yn) = "y"

Differences from QB
   * If the user inputs the wrong number of values, or if it expects a 
     number for a value and gets a string that is not a valid number, then 
     QBASIC issues the message "Redo from start", and does not continue 
     further until it receives a valid input.
   * QB does not treat space as a delimiter when inputting a number from 
     the console.

See also
   * Input #
   * Input()
   * Line Input



---------------------------------------------------- KeyPgInputfilemode ----
Input (File Mode)

Specifies text file to be opened for input mode

Syntax
   Open filename for Input [Encoding encoding_type] [Lock lock_type] as [#]
   filenum 

Parameters
   filename
      file name to open for input
   encoding_type
      indicates encoding type for the file
   lock_type
      locking to be used while the file is open
   filenum
      unused file number to associate with the open file

Description
   A file mode used with Open to open a text file for reading.

   This mode allows to read sequentially lines of text with Line Input #, 
   or to read comma separated values with Input #. 

   Text files can't be simultaneously read and written in FreeBASIC, so if 
   both functions are required on the same file, it must be opened twice.

   filename must be a string expression resulting in a legal file name in 
   the target OS, without wildcards. The file will be sought for in the 
   present directory, unless the filename contains a path . If the file 
   does not exist, an error is issued. The pointer is set at the first 
   character of the file.

   Encoding_type indicates the Unicode Encoding of the file, so characters 
   are correctly read. If omitted, "ascii" encoding is defaulted. Only 
   little endian character encodings are supported at the moment. 
      *"utf8", 
      *"utf16" 
      *"utf32" 
      *"ascii" (the default)

   Lock_type indicates the way the file is locked  for other processes, it 
   is one of:
      * Read - the file can be opened simultaneously by other processes, 
        but not for reading
      * Write - the file can be opened simultaneously by other processes, 
        but not for writing
      * Read Write - the file cannot be opened simultaneously by other 
        processes (the default)

   filenum is a valid FreeBASIC file number (in the range 1..255) not being 
   used for any other file presently open. The file number identifies the 
   file for the rest of file operations. A free file number can be found 
   using the FreeFile function.

Example
   Dim ff As UByte
   Dim randomvar As Integer
   Dim name_str As String
   Dim age As Integer

   '' collect the test data and output to file with Write #
   Input "What is your name? ", name_str
   Input "What is your age? ", age
   Randomize
   Print

   ff = FreeFile
   Open "testfile" For Output As #ff
   Write #ff, Int(Rnd*42), name_str, age
   Close #ff

   '' clear variables
   randomvar = 0
   name_str = ""
   age = 0

   '' input the variables, using Input #
   ff = FreeFile
   Open "testfile" For Input As #ff
   Input #ff, randomvar, name_str, age
   Close #ff

   Print "Random Number was: " & randomvar
   Print "Your name is: " & name_str
   Print "Your age is: " & age

   'File outputted by this sample will look something like this
   '(not including the leading comment marker):
   '23,"Your Name",19

Differences from QB

See also
   * Input (Console I/O)
   * Input #
   * Input()
   * Append
   * Open
   * Output



---------------------------------------------------------- KeyPgInputPp ----
Input #

Reads a list of values from a text file

Syntax
   Input # filenum, variable_list

Parameters
   filenum
      a file number of a file or device opened for Input
   variable_list
      a list of variables used to hold the values read

Description
   Reads from a text file through a bound file number a delimiter-separated 
   set of values and writes them in reading order into the variables in 
   variable_list. If a variable is numeric the read value is converted from 
   its string representation into the corresponding type.

   Numeric values are converted in a similar way to the procedures Val and 
   ValLng, using the most appropriate function for the number format.

   Delimiters may be commas or line breaks. Whitespace is also treated as a 
   separator after numbers. A string including a comma or a whitespace must 
   be surrounded by double quotes. 

   To read an entire line into a string, use Line Input instead.

   Write # can be used to create a file readable with Input #.

Example
   Dim a As Integer
   Dim b As String
   Dim c As Single

   Open "myfile.txt" For Output As #1
   Write #1, 1, "Hello, World", 34.5
   Close #1

   Open "myfile.txt" For Input As #1
   Input #1, a, b, c
   Close #1
   Print a, b, c

Differences from QB
   * QB has a bug in INPUT # that causes it to read past the end of the 
     line if it does not find a matching end-quote when reading a string. 
     If you are porting QB code that relies upon this bug, you may need to 
     edit your data files to remove newlines from inside quoted strings, or 
     to use a custom function to piece back together the multiline string.

See also
   * Input
   * Input()
   * Line Input #
   * Write #
   * Open
   * Input (File Mode)



--------------------------------------------------------- KeyPgInputnum ----
Input()

Reads a number of characters from console or file

Syntax
   Declare Function Input ( n As Integer ) As String
   Declare Function Input ( n As Integer, filenum As Integer ) As String

Usage
   result = Input[$]( n [, [#]filenum ] )

Parameters
   n
      Number of bytes to read.
   filenum
      File number of a bound file or device.

Return Value
   Returns a String of the characters read.

Description
   Reads a number of characters from the console, or a bound file/device 
   specified by filenum.

   The first version waits for and reads n characters from the keyboard 
   buffer. Extended keys are not read. The characters are not echoed to the 
   screen.

   The second version waits for and reads n characters from a file or 
   device. The file position is updated.

Example
   Print "Select a color by number" 
   Print "1. blue"
   Print "2. red"
   Print "3. green"
   Dim choice As String
   Do
      choice = Input(1)
   Loop Until choice >= "1" And choice <= "3"

Dialect Differences
   * The string type suffix "$" is forbidden in the -lang fb dialect.

Differences from QB
   * None in the -lang qb dialect.

See also
   * Winput()
   * GetKey
   * Inkey



------------------------------------------------------------ KeyPgInstr ----
InStr

Locates the first occurrence of a substring or character within a string

Syntax
   Declare Function InStr ( ByRef str As Const String,  [ Any ] ByRef 
   substring As Const String ) As Integer
   Declare Function InStr ( ByRef str As Const WString, [ Any ] ByRef 
   substring As Const WString ) As Integer
   Declare Function InStr ( ByVal start As Integer, ByRef str As Const 
   String, [ Any ] ByRef substring As Const String ) As Integer
   Declare Function InStr ( ByVal start As Integer, ByRef str As Const 
   WString, [ Any ] ByRef substring As Const WString ) As Integer

Usage
   first = InStr( [ start, ] str, [ Any ] substring )

Parameters
   str
      The string to be searched.
   substring
      The substring to find.
   start
      The position in str at which the search will begin. The first 
      character starts at position 1.

Return Value
   The position of the first occurrence of substring in str.

Description
   Locates the position of the first occurrence of a substring or character 
   within a string. In the first form of InStr (without start parameter), 
   the search begins at the first character.

   Zero (0) is returned if: either substring is not found, either str or 
   substring are empty strings, or start < 1.

   If the Any keyword is specified, InStr returns the first occurrence of 
   any character in substring.

Example
   ' It will return 4
   Print InStr("abcdefg", "de")

   ' It will return 0
   Print InStr("abcdefg", "h")

   ' It will search for any of the characters "f", "b", "c", and return 2 as "b" is encountered first
   Print InStr("abcdefg", Any "fbc")

   Dim test As String
   Dim idx As Integer

   test = "abababab"
   idx = InStr(test, "b")

   Do While idx > 0 'if not found loop will be skipped
      Print """b"" at " & idx
      idx = InStr(idx + 1, Test, "b")
   Loop

'A Unicode example:
dim text as wstring*20
text = "&#1055;&#1088;&#1080;&#1074;&#1077;&#1090;, &#1084;&#1080;&#1088;!"
print instr(text,"&#1077;&#1090;") ' displays 5

Platform Differences
   * The wide-character string version of InStr is not supported for DOS 
     target.

Differences from QB
   * QB returns start if search is a zero length string.
   * QB does not support Unicode.

See also
   * InStrRev
   * Mid (Function)



--------------------------------------------------------- KeyPgInstrrev ----
InStrRev

Locates the last occurrence of a substring or character within a string

Syntax
   Declare Function InStrRev ( ByRef str As Const String, [ Any ] ByRef 
   substring As Const String, ByVal start As Integer = -1 ) As Integer
   Declare Function InStrRev ( ByRef str As Const WString, [ Any ] ByRef 
   substring As Const WString, ByVal start As Integer = -1 ) As Integer

Usage
   last = InStrRev( str, [ Any ] substring [, start ]  )

Parameters
   str
      The string to be searched.
   substring
      The substring to find.
   start
      The position in str at which the search will begin. The first 
      character starts at position 1.

Return Value
   The position of the last occurrence of substring in str.

Description
   Locates the position of the last occurrence of a substring or character 
   within a string.  If start parameter is not given or is less than zero, 
   the search begins at the last character.

   Zero (0) is returned if:
      * substring is not found, or
      * either str or substring is an empty strings, or 
      * start is zero, or 
      * start is greater than the length of str.

   If the Any keyword is specified, InStrRev returns the last occurrence of 
   any character in substring.

Example
   ' It will return 4
   Print InStrRev("abcdefg", "de")

   ' It will return 0
   Print InStrRev("abcdefg", "h")

   Dim test As String
   Dim idx As Integer

   test = "abababab"
   idx = InStrRev(test, "b")

   Do While idx > 0 'if not found loop will be skipped
      Print """b"" at " & idx
      idx = InStrRev(Test, "b", idx - 1)
   Loop

'A Unicode example:
dim text as wstring*20
text = "&#1055;&#1088;&#1080;&#1074;&#1077;&#1090;, &#1084;&#1080;&#1088;!"
print instrrev(text,"&#1077;&#1090;") ' displays 5

Platform Differences
   * The wide-character string version of InStrRev is not supported for 
     DOS target.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Instrrev.

Differences from QB
   * New to FreeBASIC

See also
   * InStr
   * Mid (Function)



-------------------------------------------------------------- KeyPgInt ----
Int

Returns the floor of a number

Syntax
   Declare Function Int ( ByVal number As Single ) As Single
   Declare Function Int ( ByVal number As Double ) As Double
   Declare Function Int ( ByVal number As Integer ) As Integer
   Declare Function Int ( ByVal number As UInteger ) As UInteger

Usage
   result = Int( number )

Parameters
   number
      the floating-point number to round

Return Value
   Returns the floor of number, i.e. the largest integer that is less than 
   or equal to it.

Description
    Int returns the floor of number.  For example, Int(4.9) will return 4.0
   , and Int(-1.3) will return -2.0.  For integer types, the number is 
   returned unchanged.

   The Int unary Operator can be overloaded with user defined types.

Example
   Print Int(1.9)  '' will print  1
   Print Int(-1.9) '' will print -2 

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * None

See also
   * Fix
   * CInt
   * Operator



---------------------------------------------------------- KeyPgInteger ----
Integer

Standard data type: 32-bit or 64-bit signed, same size as SizeOf(Any Ptr)

Syntax
   Dim variable As Integer
   Dim variable As Integer<bits>

Parameters
   bits
      A numeric constant expression indicating the size in bits of integer 
      desired.  The values allowed are 8, 16, 32 or 64.

Description
   Integer is the main data type FreeBASIC uses for integer math and 
   bitwise operations. It is the default type for number literals.

   In the first form Integer is a 32-bit or 64-bit signed whole-number data 
   type, depending on the target platform.

   If an explicit bit size is given (the second form), a data type is 
   provided that can hold values from -1LL Shl (bits-1) up to (1LL Shl (
   bits-1)) - 1. The selected data type is Byte for Integer<8>, Short for 
   Integer<16>, Long for Integer<32> and LongInt for Integer<64>.

Example
   #ifdef __FB_64BIT__
      Dim x As Integer = &H8000000000000000
      Dim y As Integer = &H7FFFFFFFFFFFFFFF
      Print "Integer Range = "; x; " to "; y
   #else
      Dim x As Integer = &H80000000
      Dim y As Integer = &H7FFFFFFF
      Print "Integer Range = "; x; " to "; y
   #endif

Dialect Differences
   * In the -lang fb and -lang fblite dialects, the Integer data type is 
     32-bit or 64-bit depending on target platform
   * In the -lang qb dialect, the Integer data type is 16-bit, regardless 
     of platform.

Differences from QB
   * The ability to select a bit size is new to FreeBASIC
   * The INTEGER type is always 16 bits wide in QB.

See also
   * Long
   * LongInt
   * UInteger
   * CInt



--------------------------------------------------------------- KeyPgIs ----
Is

Clause in the Select Case statement block.

Syntax
   Case Is expression

Description
   Is specifies that a particular case inside a Select Case block will be 
   evaluated based on an expression including the greater than (>) or less 
   than (<) operator and a value. 

See also
   * Select Case
   * Operator Is



------------------------------------------------------------- KeyPgOpIs ----
Operator Is (Run-Time Type Information)

Check if an object is compatible to a type derived from its compile-time 
type
(in the context of inheritance)

Syntax
   result = expression Is  typename

Parameters
   expression
      The expression to check, an object of a type that is directly or 
      indirectly derived from Object using Extends.
   typename
      The child type to check for. This type must be directly or indirectly 
      derived from the type of expression (the compile-time type of the 
      object).

Return Value
   Returns negative one (-1) if the expression is an object of real-type 
   typename or one of its base-types derived from the expression type, or 
   zero (0) if it's an object of an incompatible type.

Description
   The Is operator must be used in conjunction with inheritance in order to 
   check compatibility between objects and types from an inheritance 
   structure extending the built-in Object type.

   The Is operator is a binary operator that checks whether an object is 
   compatible to its derived types at run-time. Because Is relies on 
   Run-Time Type Information (RTTI), it can only be used with types that 
   are derived from the built-in Object type using Extends. The compiler 
   disallows using Is for checks that can be solved at compile-time.

   The Is operator is successful not only for the real-type (the "lowest"), 
   but also for its base-types, as long as they are still below the type of 
   expression (the compile-time type). In order to determine the real-type, 
   all possibilities from lowest to highest must be checked.

   Extending the built-in Object type allows to add an extra hidden vtable 
   pointer field at the top of the Type. The vtable is used to access 
   information for run-time type identification used by the Is operator.

   This operator cannot be overloaded.

Example
   Type Vehicle Extends Object
      As String Name
   End Type

   Type Car Extends Vehicle
   End Type

   Type Cabriolet Extends Car
   End Type

   Type Bike Extends Vehicle
   End Type

   Sub identify(ByVal p As Object Ptr)
      Print "Identifying:"

      '' Not a Vehicle object?
      If Not (*p Is Vehicle) Then
         Print , "unknown object"
         Return
      End If

      '' The cast is safe, because we know it's a Vehicle object
      Print , "name: " & CPtr(Vehicle Ptr, p)->Name

      If *p Is Car Then
         Print , "It's a car"
      End If

      If *p Is Cabriolet Then
         Print , "It's a cabriolet"
      End If

      If *p Is Bike Then
         Print , "It's a bike"
      End If
   End Sub

   Dim As Car ford
   ford.name = "Ford"
   identify(@ford)

   Dim As Cabriolet porsche
   porsche.name = "Porsche"
   identify(@porsche)

   Dim As Bike mountainbike
   mountainbike.name = "Mountain Bike"
   identify(@mountainbike)

   Dim As Vehicle v
   v.name = "some unknown vehicle"
   identify(@v)

   Dim As Object o
   identify(@o)

Differences from QB
   * New to FreeBASIC

See also
   * Extends
   * Extends Zstring
   * Extends Wstring
   * Object
   * Is (Select Case)
   * TypeOf
 


----------------------------------------------------------- KeyPgIsDate ----
IsDate

Tests if a string can be converted to a Date Serial

Syntax
   Declare Function IsDate ( ByRef stringdate As Const String ) As Long

Usage
   #include "vbcompat.bi"
   result = IsDate( stringdate )

Parameters
   stringdate
      the string to test

Return Value
   Returns non-zero (-1) if the date string can be converted to a 
   Date Serial, otherwise returns zero (0).

Description
   Date strings must be in the format set in the regional settings of the 
   OS to be considered valid dates.

   IsDate(Date) will return non-zero (-1) only if the regional settings 
   specify the same date format that QB used.

   The compiler will not recognize this function unless vbcompat.bi or 
   datetime.bi is included.

Example
   #include "vbcompat.bi"

   Dim s As String, d As Integer

   Do
     Print
     Print "Enter a date: "

     Line Input s

     If s = "" Then Exit Do

     If IsDate( s ) = 0 Then
      Print "'"; s; "' is not a valid date"
     Else
      d = DateValue( s )
      Print "year  = "; Year( d )
      Print "month = "; Month( d )
      Print "day   = "; Day( d )
     End If

   Loop

Differences from QB
   * New to FreeBASIC

See also
   * Date Serials
   * DateSerial
   * TimeValue
   * DateValue



----------------------------------------------------- KeyPgIsredirected ----
IsRedirected

Checks whether stdin or stdout is redirected to a file

Syntax
   Declare Function IsRedirected ( ByVal is_input As Long = 0 ) As Long

Usage
   #include "fbio.bi"
   result = IsRedirected( is_input )

Parameters
   is_input
      A Long indicating the type of information to return.

Return Value
   Returns non-zero (-1) if stdin or stdout is redirected, otherwise 
   returns zero (0).

Description
   IsRedirected checks whether stdin or stdout is redirected to a file, 
   instead of being connected to the console/terminal as usual.

   If is_input is equal to non-zero (-1), IsRedirected checks stdin.
   If is_input is equal to zero (0), IsRedirected checks stdout.

Example
   '' A Windows based example, just for the use principle
   '' Self-sufficient example, using his own .exe file as dummy input file for stdin redirection

   #include "fbio.bi"

   '' Quotation marks wrapping for compatibility with spaces in path name
   Dim As String pathExe = """" & ExePath & """"
   Dim As String fileExe = Mid(Command(0), InStrRev(Command(0), "\") + 1)
   Dim As String redirection = " < """ & Command(0)
   If LCase(Right(Command(0), 4)) = ".exe" Then
     redirection &= """"
   Else
     redirection &= ".exe"""
   End If

   If Command() = "" Then  '' First process without stdin redirection
     '' Check stdin redirection
     Print "First process without stdin redirection: IsRedirected(-1) = "; IsRedirected(-1)
     '' Creation of asynchronous second process with stdin redirected from file.exe
     Shell("start /d " & pathExe & " /b " & fileExe & redirection & " secondprocess")
     '' Waiting for termination of asynchronous second process
     Sleep
   ElseIf Command() = "secondprocess" Then  '' Second process with stdin redirection
     '' Check stdin redirection
     Print "Second process with stdin redirection  : IsRedirected(-1) = "; IsRedirected(-1)
   End If

Differences from QB
   * New to FreeBASIC.

See also
   * Reset(Streamno)




============================================================================
    K

------------------------------------------------------------- KeyPgKill ----
Kill

Deletes a file from disk / storage media.

Syntax
   Declare Function Kill ( ByRef filename As Const String ) As Long

Usage
   result = Kill( filename )

Parameters
   filename
      The filename is the name of the disk file to delete. If the file is 
      not in the current directory, the path must also be given as 
      path/file.

Return Value
   Returns zero (0) on success, or non-zero on error.

Description
   Kill deletes a file from disk / storage media.

   The error code returned by Kill can be checked using Err in the next 
   line. The function version of  Kill returns directly the error code as a 
   32 bit Long.
 
Example
   Dim filename As String = "file.ext"
   Dim result As Integer = Kill( filename )

   If result <> 0 Then Print "error trying to kill " ; filename ; " !"

Platform Differences
   On some platforms, Kill may be able to remove folders and read-only 
   files.  Whether it succeeds or fails here is not currently defined.  It 
   may be necessary to check the attributes of the file you are deleting, 
   and decide accordingly whether you want to try Killing it.

Differences from QB
   * KILL can optionally be used as function in FreeBASIC.

See also
   * Shell
   * RmDir




============================================================================
    L

----------------------------------------------------------- KeyPgLbound ----
LBound

Returns the lower bound of an array's dimension

Syntax
   Declare Function LBound ( array() As Any, ByVal dimension As Integer = 1 
   ) As Integer

Usage
   result = LBound( array [, dimension ] )

Parameters
   array
      an array of any type
   dimension
      the dimension to get lower bound of

Return Value
   Returns the lower bound of an array's dimension.
 
Description
   LBound returns the lowest value that can be used as an index into a 
   particular dimension of an array.

   Array dimensions are numbered from one (1) to n, where n is the total 
   number of dimensions. If dimension is not specified, LBound will return 
   the lower bound of the first dimension.

   If dimension is zero (0), LBound returns 1, corresponding to the lower 
   bound of the array dimensions 1..n. UBound returns n, the number of 
   dimensions, in this case. This can be used to detect the array's number 
   of dimensions.

   For any other (non-zero) dimension values outside of the valid range 1..
   n, LBound returns 0. UBound returns -1 in this case. This can be used to 
   detect whether a certain dimension exists in the array, and also works 
   when used on an empty array which does not have any valid dimensions.

   Thus, for empty dynamic arrays, we get:
      * Lbound(array) = 0 and Ubound(array) = -1 (dimension 1 does not 
        exist)
      * Lbound(array, 0) = 1 and Ubound(array, 0) = 0 (zero dimensions)
      * @array(Lbound(array)) = 0 (no data buffer allocated)

Example
   Dim array(-10 To 10, 5 To 15, 1 To 2) As Integer

   Print LBound(array) 'returns -10
   Print LBound(array, 2) 'returns 5
   Print LBound(array, 3) 'returns 1

See also
   * UBound
   * Static
   * Dim
   * ReDim



------------------------------------------------------------ KeyPgLcase ----
LCase

Returns a lower case copy of a string

Syntax
   Declare Function LCase ( ByRef str As Const String, ByVal mode As Long = 
   0 ) As String
   Declare Function LCase ( ByRef str As Const WString, ByVal mode As Long 
   = 0 ) As WString

Usage
   result = LCase[$]( str [ , mode ] )

Parameters
   str
      String to convert to lowercase.
   mode
      The conversion mode: 0 = current locale, 1 = ASCII only

Return Value
   Lowercase copy of str.

Description
   Returns a copy of str with all of the letters converted to lower case.

   If str is empty, the null string ("") is returned.

Example
   Print LCase("AbCdEfG")

Output:

   abcdefg

Platform Differences
   * The wide-character string version of LCase is not supported for DOS 
     target.

Dialect Differences
   * The string type suffix "$" is obligatory in the -lang qb dialect.
   * The string type suffix "$" is optional in the -lang fblite dialect.
   * The string type suffix "$" is forbidden in the -lang fb dialect.

Differences from QB
   * QB does not support Unicode.

See also
   * UCase



------------------------------------------------------------- KeyPgLeft ----
Left

Returns the leftmost substring of a string

Syntax
   Declare Function Left ( ByRef str As Const String, ByVal n As Integer ) 
   As String
   Declare Function Left ( ByRef str As Const WString, ByVal n As Integer ) 
   As WString

Usage
   result = Left[$]( str, n )

Parameters
   str
      The source string.
   n
      The number of characters to return from the source string.

Return Value
   Returns the leftmost substring from str.

Description
   Returns the leftmost n characters starting from the left (beginning) of 
   str. If str is empty, then the null string ("") is returned. If n <= 0 
   then the null string ("") is returned. If n > len(str) then the entire 
   source string is returned.

Example
   Dim text As String = "hello world"
   Print Left(text, 5)

   will produce the output:

   hello

An Unicode example:

dim text as wstring*20
text = "&#1055;&#1088;&#1080;&#1074;&#1077;&#1090;, &#1084;&#1080;&#1088;!"
print left(text, 6) 'displays "&#1055;&#1088;&#1080;&#1074;&#1077;&#1090;"

Platform Differences
   * DOS does not support the wide-character string version of Left.

Dialect Differences
   * The string type suffix "$" is obligatory in the -lang qb dialect.
   * The string type suffix "$" is optional in the -lang fblite dialect.
   * The string type suffix "$" is forbidden in the -lang fb dialect.

Differences from QB
   * QB does not support Unicode.

See also
   * Right
   * Mid (Function)



-------------------------------------------------------------- KeyPgLen ----
Len

Returns the length of an expression or data type

Syntax
   Declare Function Len ( ByRef expression As String ) As Integer
   Declare Function Len ( ByRef expression As ZString ) As Integer
   Declare Function Len ( ByRef expression As WString ) As Integer

   Declare Operator Len ( ByRef expression As datatype ) As datatype

   Declare Function Len ( datatype ) As Integer	

Usage
   result = Len( expression )
      or
   result = Len( DataType )

Parameters
   expression
      An expression of any type.
   datatype
      A DataType.

Return Value
   Returns the size of an expression or DataType in bytes.

Description
   Len returns the length of an expression or the size of a DataType, in 
   bytes.

   In the first form, if expression is of type String, WString or ZString, 
   the length of the string in characters will be returned. If the 
   expression is of a user defined type, an Operator Len compatible with 
   that data type is called.  Otherwise, the size of the expression's data 
   type in bytes is returned.

   In the second form, if expression is ZString or WString, the size in 
   bytes of an ASCII or Unicode character is returned, respectively. If 
   datatype is String, the size of the string descriptor type is returned.

   When a variable from a given namespace is accessed with the namespace's 
   name prefix, wrap the argument to Len with parentheses to force it to be 
   seen as an expression. For example Len((namespace_name.variable)).

   If there is both a user defined type and a variable visible with the 
   same name in the current scope, the user defined type takes precedence 
   over the variable.  To ensure that the Len takes the variable instead of 
   the user defined type, wrap the argument to Len with parentheses to 
   force it to be seen as an expression.  For example Len((variable)).

   The Len unary Operator can be overloaded with user defined types.

Example
   Print Len("hello world") 'returns "11"
   Print Len(Integer) ' returns 4

   Type xyz
      a As Integer
      b As Integer
   End Type

   Print Len(xyz) ' returns 8

Dialect Differences
   * Len only allows expressions in the -lang qb dialect. 
   * Can be used with built-in types and user-defined types in the -lang fb
     and -lang fblite dialects.

Differences from QB
   * Can be used with built-in types and user-defined types in the -lang fb
     and -lang fblite dialects.
   * None in the -lang qb dialect.

See also
   * SizeOf



-------------------------------------------------------------- KeyPgLet ----
Let

Indicates the assignment operator.

Syntax
   Let variable = value
or
   Let( variable1 [, variable2 [, ... ]] ) = udt
or
   Operator typename.Let ( [ ByRef | ByVal ] rhs As datatype )
      statements
   end operator

Description
   Command intended to help the programmer to distinguish an assignment 
   statement (e.g. Let a = 1) from an equality test (e.g. If a = 1 then ...
   ).  As the compiler does not require it, it is usually omitted.

   Let can be used as a left-hand side operator to assign the members of a 
   user defined type to multiple variables. See Operator Let() (Assignment)

   Let is used with operator overloading to refer the assignment operator. 
   See Operator Let (Assignment)

Example
   '' Compile with -lang fblite or qb

   #lang "fblite"

   ' these two lines have the same effect:
   Let x = 100
   x = 100

Dialect Differences
   * The use of Let to indicate an assignment statement (Let variable = 
     expr) is not allowed in the -lang fb dialect.
   * The UDT to multi-variable Let assignment is only available in the 
     -lang fb dialect.
   * Overloading of operators is not available in the -lang qb and 
     -lang fblite dialects.

Differences from QB
   * None in the -lang fb dialect.
   * The Let operator is new to FreeBASIC.
   * The UDT to multi-variable Let assignment is new to FreeBASIC.

See also
   * Operator =[>] (Assignment)
   * Operator Let (Assignment)
   * Operator Let() (Assignment)
   * Operator



-------------------------------------------------------------- KeyPgLib ----
Lib

Specifies the library where a sub or function can be found as part of a 
declaration

Syntax
   Declare { Sub | Function } proc_name Lib "libname" [ Alias "symbol_name" 
   ] ( arguments list ) As return_type

   Extern "mangling" lib "libname"
      declarative statements
   end Extern

   Type T
      As Integer dummy
      Declare Constructor Lib "libname" [ Alias "symbol_name" ] ( arguments 
      list )
   end Type

Description
   In Sub or Function declarations, and also in class method declarations 
   (including constructors and destructors), Lib indicates the library 
   containing the function. Libraries specified in this way are linked in 
   as if #Inclib "Libname" or -l libname had been used.

   Lib can also be used with Extern ... End Extern Blocks to specifiy a Lib 
   for all declarations inside.

Example
   '' mydll.bas
   '' compile with:
   ''   fbc -dll mydll.bas

   Public Function GetValue() As Integer Export
     Function = &h1234
   End Function

   Declare Function GetValue Lib "mydll" () As Integer

   Print "GetValue = &h"; Hex(GetValue())

   ' Expected Output :
   ' GetValue = &h1234

Differences from QB
   * New to FreeBASIC

See also
   * Declare
   * #inclib



----------------------------------------------------- KeyPgLinegraphics ----
Line (Graphics)

Draws a line

Syntax
   Line [target,] [[STEP]|(x1, y1)]-[STEP] (x2, y2) [, [color][, [B|BF][, 
   style]]]
   or
   Line - (x2, y2) [, [color][, [B|BF][, style]]]

Parameters
   target
      specifies buffer to draw on
   STEP
      indicates that the starting coordinates are relative
   (x1, y1)
      starting coordinates of the line
   STEP
      indicates that ending coordinates are relative
   (x2, y2)
      ending coordinates of the line
   color
      the color attribute.
   B|BF
      specifies box or box filled mode
   style
      line style

Description
   Graphics statement that draws a straight line or a box between two 
   points. The action will take place on the current work page set via 
   ScreenSet, or onto the buffer Get/Put buffer if specified.

   Line coordinates are affected by custom coordinates system set via Window
   and View (Graphics) statements, and respect clipping rectangle set by 
   View (Graphics). If a pair of coordinates is preceded by the STEP 
   keyword, the coordinates are assumed to be relative to the last graphics 
   cursor position. If the B flag is specified, a rectangle will be drawn 
   instead of a line, with (x1,y1)-(x2,y2) as the coordinates of the 
   opposite rectangle corners. If BF is specified, a filled rectangle will 
   be drawn.

   Color denotes the color attribute, which is mode specific (see Color and 
   Screen (Graphics) for details). If omitted, the current foreground color 
   as set by the Color statement is used.

   Style, if specified, allows styled line drawing; its value is 
   interpreted as a 16-bit bitmask, and Line will use it to skip pixel 
   drawing. Starting at (x1,y1), the most significant bit of the style mask 
   is checked: if 1, the pixel is drawn, if 0, it's skipped. This repeats 
   for all the line pixels with the other bits, with the mask being reused 
   when the 16 bits are all checked.

   When Line is used as Line - (x2, y2), a line is drawn from the current 
   cursor position to the (x2,y2) coordinates specified by Line.  
   Alternatively, Point can be used to get the current cursor position.

   Note: Either chained use or boxes drawn with Line can induce pixels 
   overdrawn at some locations. Thus, the resultant (blended) color of 
   these overdrawn pixels is affected if a transparent color (in 
   conjunction with the GFX_ALPHA_PRIMITIVES option flag) is used.

Example
   '' draws a diagonal red line with a white box, and waits for 3 seconds
   Screen 13
   Line (20, 20)-(300, 180), 4
   Line (140, 80)-(180, 120), 15, b
   Line - ( 200, 200 ), 15
   Sleep 3000

   ' Draws 2 lines with 2 different line styles in 2 different colors
   ScreenRes 320, 240

   Line (10, 100)-(309, 140),  4, B, &b1010101010101010 ' red box with dashed border

   Line (20, 115)-(299, 115),  9,  , &b1111000011111111 ' blue dashed line
   Line (20, 125)-(299, 125), 10,  , &b0000000011110000 ' green dashed line

   Sleep

Differences from QB
   * target is new to FreeBASIC

See also
   * Circle
   * Window
   * View (Graphics)



-------------------------------------------------------- KeyPgLineinput ----
Line Input

Reads one line of input from the keyboard

Syntax
   Line Input [;] [promptstring {;|,} ] stringvariable

Parameters
   promptstring
      prompt to display before waiting for input
   stringvariable
      variable to receive the line of text

Description
   Reads a line of text from the keyboard and stores it in a string 
   variable.

Example
   Dim x As String

   Line Input "Enter a line:", x

   Print "You entered '"; x; "'"

Differences from QB
   * QBASIC only allowed literal strings for the prompt text.  FreeBASIC 
     allows any variable or constant string expression.

See also
   * Line Input #
   * Input



------------------------------------------------------ KeyPgLineinputPp ----
Line Input #

Reads one line of text from a file

Syntax
   Line Input #file number, string_variable

Parameters
   file number
      file number of an file opened for Input
   string_variable
      variable to receive the line of text

Description
   Reads a line from an open text file (opened for Input through a bound 
   file number) and stores it in a string variable.  

   A line of text ends at, but does not include the end of line characters. 
   An end of line character may be the LF character (Chr(10)) or the CRLF 
   character pair (Chr(13,10)).

Example
   Dim s As String

   Open "myfile.txt" For Output As #1
   Print #1, "Hello, World"
   Close #1

   Open "myfile.txt" For Input As #1
   Line Input #1, s
   Close #1
   Print s

Differences from QB
   * None

See also
   * Line Input
   * Input #
   * Open
   * Input (File Mode)



----------------------------------------------------------- KeyPgLoByte ----
LoByte

Gets the lowest byte of the operand.

Syntax
   #define LoByte( expr ) (Cast(UInteger, expr) And &h000000FF)

Usage
   result = LoByte( expr )

Parameters
   expr
      A numeric expression, converted to an UInteger value.

Return Value
   Returns the value of the low byte of expr.

Description
   This macro converts the numeric expression expr to an UInteger value, 
   then expands to an UInteger representing the value of its 
   least-significant (low) byte.

Example
   Dim N As UInteger

   'Note there are 16 bits
   N = &b1010101110000001
   Print "N is                                       "; N
   Print "The binary representation of N is          "; Bin(N)
   Print "The most significant byte (MSB) of N is    "; HiByte(N)
   Print "The least significant byte (LSB) of N is   "; LoByte(N)
   Print "The binary representation of the MSB is    "; Bin(HiByte(N))
   Print "The binary representation of the LSB is    "; Bin(LoByte(N))
   Sleep

The output would look like:

   N Is                                       43905
   The Binary representation of N Is          1010101110000001
   The most significant Byte (MSB) of N Is    171
   The least significant Byte (LSB) of N Is   129
   The Binary representation of the MSB Is    10101011
   The Binary representation of the LSB Is    10000001

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __LOBYTE.

Differences from QB
   * New to FreeBASIC

See also
   * HiByte
   * LoWord
   * HiWord



-------------------------------------------------------------- KeyPgLoc ----
LOC

Returns the file position where the last file read/write was performed

Syntax
   Declare Function LOC ( ByVal filenum As Long ) As LongInt

Usage
   result = LOC( filenum )

Parameters
   filenum
      The file number of an open file.

Return Value
   The file position where the last read/write was performed.

Description
   Returns the position where the last file read/write was performed.

   The position is indicated in records:
      In files opened FOR RANDOM the record length specified when file was 
      opened is used
      In  text files (FOR INPUT|OUTPUT|APPEND, a record length of 128 bytes 
      is supposed.
      In files opened for BINARY a 1 byte record length is used.

   In FreeBASIC the file position is 1 based, the first record of a file is 
   record 1 (LOC=1 after reading or writing the first record, LOC=0 for the 
   start position in the file).

   When used with a serial device, LOC returns the number of bytes waiting 
   to be read from the serial device's input buffer.

Example
   Dim b As String

   If Open Com ("com1:9600,n,8,1,cs,rs,ds,bin" For Binary As #1) <> 0 Then
     Print "unable to open serial port"
     End
   End If

   Print "Sending command: AT"

   Print #1, "AT" + Chr(13, 10);

   Sleep 500,1

   Print "Response:"

   While( LOC(1) > 0 )
     b = Input(LOC(1), 1)
     Print b;
   Wend

   Close #1

Differences from QB
   * None

See also
   * LOF
   * EOF
   * Seek (Function)
   * Open



------------------------------------------------------------ KeyPgLocal ----
Local

Error handling statement to set the current error handler

Syntax
   On Local Error Goto label

Description
   The Local clause in an On Error construction allows to define an error 
   handler in the same Sub or Function the On Local Error is in.

    Remark: Presently, the Local clause (authorized only inside 
   Sub/Function) is ignored by the compiler, and the error handler can be 
   either in the scope of the same procedure the On [Local] Error is in, or 
   in the main part of the module (if defined before the procedure).
   Exception if -gen gcc is used: when the On [Local] Error is inside a 
   Sub/Function, the error handler also must always be inside that same 
   procedure.

Example
   '' compile with -lang fblite or qb

   #lang "fblite"

   Declare Sub foo

   foo
   Print "ok"
   Sleep

   Sub foo
     Dim errno As Integer
     On Local Error Goto fail
     Open "xzxwz.zwz" For Input As #1
     On Local Error Goto 0
     Exit Sub
   fail:                  ' here starts the error handler
     errno = Err
     Print "Error "; errno      ' just print the error number
     Sleep
   End Sub

Differences from QB
   * The LOCAL clause comes from PDS 7.1. QB 4.5 does not allow local 
     error handling.

See also
   * On Error
   * Labels



----------------------------------------------------------- KeyPgLocate ----
Locate

Sets the current cursor position

Syntax
   Declare Function Locate( row As Long = 0, column As Long = 0, state As 
   Long = -1, start As Long = 0, stop As Long = 0 ) As Long

Usage
   Locate [row], [column], [state]

   result = Locate( [row], [column], [state] )
   new_column = LoByte( result )
   new_row = HiByte( result )
   new_state = HiWord( result )

Parameters
   row
      the 1-based vertical character position in the console.
   column
      the 1-based horizontal character position in the console.
   state
      the state of the cursor in console-mode only: 0 is off, 1 is on; text 
      cursor is never visible in graphics mode.
   start
      Ignored. Allowed for -lang qb dialect compatibility only.
   stop
      Ignored. Allowed for -lang qb dialect compatibility only.

Return Value
   Returns a 32 bit Long containing the current cursor position and state. 
   The Low Byte Of The Low Word contains the column, the 
   High Byte Of The Low Word contains the row, and the High Word contains 
   the cursor state.

   If any of the row, column or state parameters were just set by the call 
   to Locate, then the return value will reflect these new values, not the 
   previous ones. If any of the parameters were omitted in the call to 
   Locate, then the return value will reflect the current values, which are 
   the same as before the call to Locate.

   Locate will attempt to position the cursor at the specified row and 
   column. If the position is beyond the screen extents, cursor will not 
   reposition. And next Print to the screen will continue at last valid 
   cursor position.  When printing to the last line of the screen, and the 
   Print statement has a new line character, the screen will scroll and 
   reposition the cursor automatically to the last line, column 1.

Description
   Sets the text cursor in both graphics and console modes.

Example
   Locate 10
   Print "Current line:"; CsrLin

   '' Text cursor + mouse tracking
   Dim As Integer x = 0, y = 0, dx, dy

   Cls
   Locate , , 1

   While Inkey <> Chr(27)
      GetMouse dx, dy
      If( dx <> x Or dy <> y ) Then
         Locate y+1, x+1: Print " ";
         x = dx
         y = dy
         Locate 1, 1: Print x, y, ""
         Locate y+1, x+1: Print "X";
      End If
   Wend

Differences from QB
   * The start and stop arguments have no effect in FreeBASIC.
   * QB will raise an error if row or column are beyond the screen 
     extents.

See also
   * CsrLin
   * Pos
   * Print
   * ?



------------------------------------------------------------- KeyPgLock ----
Lock

Restricts read/write access to a file or portion of a file

Syntax
   Lock #filenum, record
   Lock #filenum, start To end

Parameters
   filenum
      The file number used to Open the file.
   record
      The record (Random files) to lock.
   start
      The first byte position (Binary files) to lock from.
   end
      The last byte position (Binary files) to lock to.

Description
   Lock temporarily restricts access by other threads or programs to a 
   file, or portion of a file, usually to allow safe writing to it.

   After modifying the data, an Unlock with the same parameters as the Lock 
   should be issued.

   Note: This command does not always work, neither as documented nor as 
   expected. It appears to be broken at the moment.

Example
   '' e.g. locking a file, reading 100 bytes, and unlocking it. 
   '' To run, make sure there exists a file called 'file.ext' 
   '' in the current directory that is at least 100 bytes.

   Dim array(1 To 100) As Integer
   Dim f As Integer, i As Integer
   f = FreeFile
   Open "file.ext" For Binary As #f
   Lock #f, 1 To 100
   For i = 1 To 100
      Get #f, i, array(i)
   Next
   Unlock #f, 1 To 100
   Close #f

Differences from QB
   * Currently, FB cannot implicitly lock the entire file
   * In Random mode, FB cannot lock a range of records

See also
   * Open
   * Unlock
   * ScreenLock



-------------------------------------------------------------- KeyPgLof ----
LOF

Returns the length of an open disk file

Syntax
   Declare Function LOF ( ByVal filenum As Long ) As LongInt

Usage
   result = LOF( filenum )

Parameters
   filenum
      The file number of an open disk file.

Return Value
   The length in bytes of an open disk file.

Description
   Returns the length, in bytes, of a file opened previously with Open 
   using the given filenum.

   With Open Com it returns the length of the data pending to be read in 
   the receive buffer.

Example
   Dim f As Integer
   f = FreeFile
   Open "file.ext" For Binary As #f
   Print LOF(f)
   Close #f

Differences from QB
   * None

See also
   * LOC
   * EOF
   * Open



-------------------------------------------------------------- KeyPgLog ----
Log

Returns the natural logarithm of a given number

Syntax
   Declare Function Log cdecl ( ByVal number As Double ) As Double

Usage
   result = Log( number )

Parameters
   number
      The number to calculate the natural log.

Return Value
   Returns the logarithm with the base e (also know as the natural 
   logarithm) of number.

Description
   There can be some confusion with this notation given that in mathematics 
   the natural logarithm function is usually denoted LN, while the 
   logarithm of base 10 is often denoted as LOG. FreeBASIC, like most 
   computer programming languages, uses LOG to denote the natural 
   logarithm. The required number argument can be any valid numeric 
   expression greater than zero. If number is zero, FreeBASIC returns a 
   special value representing "-infinity", printing like "-Inf". If number 
   is less than zero, Log returns a special value representing "not 
   defined", printing like "NaN" or "IND", exact text is platform 
   dependent. If number is an uninitialized variable, -infinity is 
   returned.

   Log can be overloaded as operator to accept user-defined types.

Example
   'Find the logarithm of any base
   Function LogBaseX (ByVal Number As Double, ByVal BaseX As Double) As Double
      LogBaseX = Log( Number ) / Log( BaseX )
      'For reference:   1/log(10)=0.43429448
   End Function

   Print "The log base 10 of 20 is:"; LogBaseX ( 20 , 10 )
   Print "The log base 2 of 16 is:"; LogBaseX ( 16 , 2 )

   Sleep

The output would look like:

   The Log Base 10 of 20 Is: 1.301029995663981
   The Log Base 2 of 16 Is: 4

Differences from QB
   * None

See also
   * Exp



------------------------------------------------------------- KeyPgLong ----
Long

Standard data type: 32-bit signed integer

Syntax
   Dim variable As Long

Description
   32-bit signed whole-number data type. Can hold values from -2147483648 
   to 2147483647. Corresponds to a signed DWORD.

Example
     Dim x As Long = &H80000000
     Dim y As Long = &H7FFFFFFF
     Print "Long Range = "; x; " to "; y

   Output:
   Long Range = -2147483648 To  2147483647

See also
   * Integer
   * LongInt
   * ULong



---------------------------------------------------------- KeyPgLongint ----
LongInt

Standard data type: 64 bit signed

Syntax
   Dim variable As LongInt

Description
   A 64-bit signed whole-number data type. Can hold values from -9 223 372 
   036 854 775 808 to 9 223 372 036 854 775 807. Corresponds to a signed 
   QWORD.

Example
     Dim x As LongInt = &H8000000000000000
     Dim y As LongInt = &H7FFFFFFFFFFFFFFF
     Print "LongInt Range = "; x; " to "; y

   Output:
   LongInt Range = -9223372036854775808 To  9223372036854775807

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Longint.

Differences from QB
   * New to FreeBASIC

See also
   * ULongInt
   * CLngInt



------------------------------------------------------------- KeyPgLoop ----
Loop

Control flow statement for looping.

Syntax
   Do
      [ statement block ]
   Loop [ { Until | While } condition ]

See also
   * Do...Loop

   


----------------------------------------------------------- KeyPgLoWord ----
LoWord

Gets the lowest 16bit word of the operand.

Syntax
   #define LoWord( expr ) (Cast(UInteger, expr) And &h0000FFFF)

Usage
   result = LoWord( expr )

Parameters
   expr
      A numeric expression, converted to an UInteger value.

Return Value
   Returns the value of the low word of expr.

Description
   This macro converts the numeric expression expr to an UInteger value, 
   then expands to an UInteger representing the value of its 
   least-significant (low) 16bit word.

Example
   Dim N As UInteger

   'Note there are 32 bits
   N = &b10000000000000011111111111111111

   Print "N is                                       "; N
   Print "The binary representation of N is          "; Bin(N)
   Print "The most significant word (MSW) of N is    "; HiWord(N)
   Print "The least significant word (LSW) of N is   "; LoWord(N)
   Print "The binary representation of the MSW is    "; Bin(HiWord(N))
   Print "The binary representation of the LSW is    "; Bin(LoWord(N))

   Sleep

The output would look like:

   N Is                                       2147614719
   The Binary representation of N Is          10000000000000011111111111111111
   The most significant word (MSW) of N Is    32769
   The least significant word (LSW) of N Is   65535
   The Binary representation of the MSW Is    1000000000000001
   The Binary representation of the LSW Is    1111111111111111

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __LOWORD.

Differences from QB
   * New to FreeBASIC

See also
   * LoByte
   * HiByte
   * HiWord



------------------------------------------------------------- KeyPgLpos ----
LPos

Returns the number of characters sent to the printer port in the last LPrint
statement.

Syntax
   Declare Function LPos ( ByVal printer As Long ) As Long

Usage
   result = LPOS(printer)

Parameters
   printer
      Either 0, 1, 2 or 3.  Represents the printer port (LPT#)

Return Value
   Returns the number of characters sent.

Description
   Used to determine, from the last LPrint, how many characters were sent 
   to the printer port.

Example
   ' compile with -lang fblite or qb

   #lang "fblite"

   Dim test As String = "LPrint Example test"

   Print "Sending '" + test + "' to LPT1 (default)"
   LPrint test
   Print "LPT1 last recieved " + Str(LPos(1)) + " characters"
   Print "String sent was " + Str(Len(test)) + " characters long"

   Sleep

Differences from QB
   * None

See also
   * LPrint



----------------------------------------------------------- KeyPgLprint ----
LPrint

Writes text to the default printer.

Syntax
   LPrint  [ Using formatstring,] [expressionlist] [(, | ;)] ...

Parameters
   formatstring
      String specifying the output format.
   expressionlist
      List of variables to output according to the specified format.

Description
   Prints expressionlist to the printer attached to the parallel port LPT1, 
   or if it does not exist, to the default printer.  To print to a printer 
   different from the default one, use Open Lpt.

   The Using clause formats expressionlist according to formatstring.  
   Except an UDT, any data type can be passed to LPrint expressionlist, 
   expressions do not need to be first converted to strings.

   Using a comma (,) as separator or in the end of the expressionlist will 
   place the cursor in the next column (every 14 characters), using a 
   semi-colon (;) won't move the cursor. If neither of them are used in the 
   end of the expressionlist, then a new-line will be printed.

   Some printers will not print at all until a Chr(12) (End of Page) 
   character is printed.

   Internally, FreeBASIC uses the special file number -1 for printing using 
   LPrint.  This file number may be safely closed using Close -1.  The next 
   use of LPrint will automatically reopen it as needed.

Example
   '' Compile with -lang fblite or qb

   #lang "fblite"

   '' new-line
   LPrint "Hello World!"

   '' no new-line
   LPrint "Hello"; "World"; "!";

   LPrint

   '' column separator
   LPrint "Hello!", "World!"

   '' end of page
   LPrint Chr$(12)

Differences from QB
   * None

Dialect Differences
   * LPrint is not supported in the -lang fb dialect. In this dialect the 
     printer must be properly opened with Open Lpt and Print # must be used 
     to print.

See also
   * Open Lpt
   * Print
   * ?
   * Print #
   * ? #
   * Write



------------------------------------------------------------- KeyPgLset ----
LSet

Left-justifies a string

Syntax
   Declare Sub LSet ( ByRef dst As String, ByRef src As Const String )
   Declare Sub LSet ( ByVal dst As WString Ptr, ByVal src As Const WString 
   Ptr )

Usage
   LSet dst, src
   LSet dst_udt, src_udt

Parameters
   dst
      String String to receive the data.
   src
      Source String to get the data.
   dst_udt
      User defined Type to receive the data.	
   src_udt
      User defined Type to copy the data from.

Description
   LSet left justifies text into the string buffer dst, filling the left 
   part of the string with src and the right part with spaces. The string 
   buffer size is not modified.
   If text is too long for the string buffer size, LSet truncates 
   characters from the right.

   For compatibility with QBasic, LSet can also copy a user defined type 
   variable into another one. The copy is made byte for byte, without any 
   care for fields or alignment. It's up to the programmer to take care for 
   the  validity of the result.

Example
   Dim buffer As String
   buffer = Space(10)
   LSet buffer, "91.5"
   Print "-[" & buffer & "]-"

   Type mytype1
      x As Integer
      y As Integer
   End Type

   Type mytype2
      z As Integer
   End Type

   Dim a As mytype1 , b As mytype2
   b.z = 1234

   LSet a, b
   Print a.x

Differences from QB
   *In QB, the syntax was LSet dst = src. That syntax is also supported by 
     FB.

See also
   * RSet
   * Space
   * Put (File I/O)
   * MKD
   * MKI
   * MKL
   * MKS



------------------------------------------------------------ KeyPgLtrim ----
LTrim

Removes surrounding substrings or characters on the left side of a string

Syntax
   Declare Function LTrim ( ByRef str As Const String, [ Any ] ByRef 
   trimset As Const String = " " ) As String
   Declare Function LTrim ( ByRef str As Const WString, [ Any ] ByRef 
   trimset As Const WString = WStr(" ") ) As WString

Usage
   result = LTrim[$]( str [, [ Any ] trimset ] )

Parameters
   str
      The source string.
   trimset
      The substring to trim.

Return Value
   Returns the trimmed string.

Description
   This procedure trims surrounding characters from the left (beginning) of 
   a source string. Substrings matching trimset will be trimmed if 
   specified, otherwise spaces (ASCII code 32) are trimmed.

   If the Any keyword is used, any character matching a character in 
   trimset will be trimmed.

   All comparisons are case-sensitive.

Example
   Dim s1 As String = "  101 Things to do."
   Print "'" + LTrim(s1) + "'"
   Print "'" + LTrim(s1, " 01") + "'"
   Print "'" + LTrim(s1, Any " 01") + "'"

   Dim s2 As String = "BaaBaaBAA Test Pattern"
   Print "'" + LTrim(s2, "Baa") + "'"
   Print "'" + LTrim(s2, Any "BaA") + "'"

   will produce the output:

   '101 Things to do.'
   '  101 Things to do.'
   'Things to do.'
   'BAA Test Pattern'
   ' Test Pattern'

Platform Differences
   * DOS version/target of FreeBASIC does not support the wide-character 
     version of LTrim.

Dialect Differences
   * The string type suffix "$" is obligatory in the -lang qb dialect.
   * The string type suffix "$" is optional in the -lang fblite dialect.
   * The string type suffix "$" is forbidden in the -lang fb dialect.

Differences from QB
   * QB does not support specifying a trimset string or the ANY clause.

See also
   * RTrim
   * Trim




============================================================================
    M

----------------------------------------------------- KeyPgMidstatement ----
Mid (Statement)

Overwrites a substring of a string with another

Syntax
   Declare Sub Mid ( ByRef text As String, ByVal start As Integer, ByVal 
   length As Integer, ByRef expression As Const String )
   Declare Sub Mid ( ByVal text As WString Ptr, ByVal start As Integer, 
   ByVal length As Integer, ByVal expression As Const WString Ptr )

Usage
   Mid( text, start ) = expression
      Or
   Mid( text, start, length ) = expression

Parameters
   text
      The string to work with.
   start
      The start position in text of the substring to overwrite. The first 
      character starts at position 1.
   length
      The number of characters to overwrite.

Description
   Copies a maximum of length characters of expression into text, starting 
   at start.

   If length is not specified, all of expression is copied. The size of the 
   string text is unchanged; if expression is too big, as much of it is 
   copied up to the end of text.

   Mid can also be used as a function to return part of another string.  
   See Mid (Function).

Example
   Dim text As String

   text = "abc 123"
   Print text 'displays "abc 123"

   ' replace part of text with another string
   Mid(text, 5, 3) = "456" 
   Print text 'displays "abc 456"

Differences from QB
   * None

See also
   * Mid (Function)



------------------------------------------------------ KeyPgMidfunction ----
Mid (Function)

Returns a substring of a string

Syntax
   Declare Function Mid ( ByRef str as Const String, ByVal start as integer 
   ) as String
   Declare Function Mid ( ByVal str as Const WString Ptr, ByVal start as 
   integer ) as WString
   Declare Function Mid ( ByRef str as Const String, ByVal start as 
   integer, ByVal n as integer ) as String
   Declare Function Mid ( ByVal str as Const WString Ptr, ByVal start as 
   integer, ByVal n as integer ) as WString

Usage
   result = Mid[$]( str, start [, n ] )

Parameters
   str
      The source string.
   start
      The start position in str of the substring. The first character 
      starts at position 1.
   n
      The substring length, in characters.

Description
   Returns a substring starting from start in str. If str is empty then the 
   null string ("") is returned. If start <= 0 then the null string ("") is 
   returned.

   In the first form of Mid, all of the remaining characters are returned. 
   In the second form, if n < 0 or n >= len(str) then all of the remaining 
   characters are returned.

Example
   Print Mid("abcdefg", 3, 2)
   Print Mid("abcdefg", 3)
   Print Mid("abcdefg", 2, 1)

   will produce the output:
   cd
   cdefg
   b

A Unicode example:
   Wiki: code rendered this way to allow display of the Unicode characters.

dim text as wstring * 20
   text = "&#1055;&#1088;&#1080;&#1074;&#1077;&#1090;, 
   &#1084;&#1080;&#1088;!"
   print mid(text, 6, 4) ' displays "&#1090;, &#1084;"

Platform Differences
   * DOS does not support the wide-character string versions of Mid.

Dialect Differences
   * The string type suffix "$" is obligatory in the -lang qb dialect.
   * The string type suffix "$" is optional in the -lang fblite dialect.
   * The string type suffix "$" is forbidden in the -lang fb dialect.

Differences from QB
   * QB does not support Unicode.

See also
   * InStr
   * Mid (Statement)
   * Left
   * Right
   * Asc



----------------------------------------------------------- KeyPgMinute ----
Minute

Gets the minute of the hour from a Date Serial 

Syntax
   Declare Function Minute ( ByVal date_serial As Double ) As Long

Usage
   #include "vbcompat.bi"
   result = Minute( date_serial )

Parameters
   date_serial
      the date serial

Return Value
   Returns the minute from a  variable containing a date in  Date Serial  
   format.

Description
 
   The compiler will not recognize this function unless vbcompat.bi is 
   included.

Example
   #include "vbcompat.bi"

   Dim ds As Double = DateSerial(2005, 11, 28) + TimeSerial(7, 30, 50)

   Print Format(ds, "yyyy/mm/dd hh:mm:ss "); Minute(ds)

Differences from QB
   * Did not exist in QB. This function appeared in PDS and VBDOS

See also
   * Date Serials



-------------------------------------------------------------- KeyPgMkd ----
MKD

Does a binary copy from a Double variable to a String, setting its length 
to 8 bytes

Syntax
   Declare Function MKD ( ByVal number As Double ) As String

Usage
   result = MKD[$]( number )

Parameters
   number
      A Double variable to binary copy to a String.

Return Value
   Returns a String with a binary copy of the Double.

Description
   Does a binary copy from a Double variable to a String, setting its 
   length to 8 bytes. The resulting string can be read back to a Double by 
   CVD.

   This function is useful to write numeric values to buffers without using 
   a Type definition.

Example
   Dim n As Double, e As String
   n = 1.2345
   e = MKD(n)
   Print n, CVD(e)

Dialect Differences
   * The string type suffix "$" is obligatory in the -lang qb dialect.
   * The string type suffix "$" is optional in the -lang fblite dialect.
   * The string type suffix "$" is forbidden in the -lang fb dialect.

Differences from QB
   * None

See also
   * MKI
   * MKL
   * MKS
   * CVD
   * CVI
   * CVL
   * CVS



------------------------------------------------------------ KeyPgMkdir ----
MkDir

Makes a folder/directory on the local file system

Syntax
   Declare Function MkDir ( ByRef folder As Const String ) As Long

Usage
   result = MkDir( folder )

Parameters
   folder
      The folder/directory to be created.

Return Value
   Returns zero (0) on success, and negative one (-1) on failure.

Description
   Creates a folder on the local file system.

Example
   Dim pathname As String = "foo\bar\baz"
   Dim result As Integer = MkDir( pathname )

   If 0 <> result Then Print "error: unable to create folder " & pathname & " in the current path."

Platform Differences
   * Linux requires the filename case matches the real name of the file. 
     Windows and DOS  are case insensitive. 
   * Path separators in Linux are forward slashes / . Windows uses 
     backward slashes \ but it allows for forward slashes .  DOS uses 
     backward  \ slashes. 

Differences from QB
   * None

See also
   * Shell
   * CurDir
   * ChDir
   * RmDir



-------------------------------------------------------------- KeyPgMki ----
MKI

Does a binary copy from an integer variable to a String of the same length 
as the size of the input variable

Syntax
   Declare Function MKI ( ByVal number As Integer ) As String
   Declare Function MKI<bits> ( ByVal number As Integer<bits> ) As String

Usage
   result = MKI[$]( number )
   result = MKI[$]<bits>( number )

Parameters
   number
      A Integer or Integer<bits> variable to binary copy to a String.

Return Value
   Returns a String containing a binary copy of number.

Description
   Does a binary copy from an Integer or Integer<bits> variable to a String,
   setting its length to the number of bytes in the type. The resulting 
   string can be read back to an integer type using CVI or CVI<bits>.

   This function is useful to write numeric values to buffers without using 
   a Type definition.

   MKI supports an optional <bits> parameter before the argument.  If bits 
   is 16, MKShort will be called instead; if bits is 32, MKL will be 
   called; if bits is 64, MKLongInt will be called.  The length of the 
   return value and the required number argument type will depend on which 
   function is called.  See each function's page for more information.

Example
   Dim a As Integer, b As String
   a=4534
   b=MKI(a)
   Print a, CVI(b)

Dialect Differences
   * In the -lang qb dialect, MKI returns a 2-byte-string, since a QB 
     integer is only 16 bits.
   * The string type suffix "$" is obligatory in the -lang qb dialect.
   * The string type suffix "$" is optional in the -lang fblite dialect.
   * The string type suffix "$" is forbidden in the -lang fb dialect.
   * QB did not support a <bits> parameter.

See also
   * CVI
   * MKShort
   * MKL
   * MKLongInt
   * Integer



-------------------------------------------------------------- KeyPgMkl ----
MKL

Does a binary copy from a Long variable to a String, setting its length to 
4 bytes

Syntax
   Declare Function MKL ( ByVal number As Long ) As String

Usage
   result = MKL( number )

Parameters
   number
      A Long variable to binary copy to a String.

Return Value
   Returns a String with a binary copy of the Long.

Description
   Does a binary copy from a Long variable to a String, setting its length 
   to 4 bytes. The resulting string can be read back to a Long by CVL.

   This function is useful to write numeric values to buffers without using 
   a Type definition.

Example
   Dim a As Long, b As String
   a = 4534
   b = MKL(a)
   Print a, CVL(b)
   Sleep

Dialect Differences
   * The string type suffix "$" is obligatory in the -lang qb dialect.
   * The string type suffix "$" is optional in the -lang fblite dialect.
   * The string type suffix "$" is forbidden in the -lang fb dialect.

Differences from QB
   * None

See also
   * MKD
   * MKI
   * MKS
   * CVD
   * CVI
   * CVL
   * CVS



-------------------------------------------------------- KeyPgMklongint ----
MKLongInt

Does a binary copy from a LongInt variable to a String, setting its length 
to 8 bytes

Syntax
   Declare Function MKLongInt ( ByVal number As LongInt ) As String

Usage
   result = MKLongInt[$]( number )

Parameters
   number
      A LongInt variable to binary copy to a String.

Return Value
   Returns a String with a binary copy of the LongInt.

Description
   Does a binary copy  from a LongInt variable to a string, setting its 
   length to 8 bytes. The resulting string can be read back to a longint by 
   CVLongInt

   This function is useful to write numeric values to buffers without using 
   a Type definition.

Example
   Dim a As LongInt, b As String
   a = 4534
   b = MKLongInt(a)
   Print a, CVLongInt(b)
   Sleep

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Mklongint.

Differences from QB
   * New to FreeBASIC

See also
   * CVLongInt



-------------------------------------------------------------- KeyPgMks ----
MKS

Does a binary copy from a Single variable to a String, setting its length 
to 4 bytes

Syntax
   Declare Function MKS ( ByVal number As Single ) As String

Usage
   result = MKS[$]( number )

Parameters
   number
      A Single variable to binary copy to a String.

Return Value
   Returns a String with a binary copy of the Single.

Description
   Does a binary copy  from a Single variable to a String, setting its 
   length to 4 bytes. The resulting string can be read back to a Single by 
   CVS.

   This function is useful to write numeric values to buffers without using 
   a Type definition.

Example
   Dim n As Single, e As String
   n = 1.2345
   e = MKS(n)
   Print n, CVS(e)

Dialect Differences
   * The string type suffix "$" is obligatory in the -lang qb dialect.
   * The string type suffix "$" is optional in the -lang fblite dialect.
   * The string type suffix "$" is forbidden in the -lang fb dialect.

Differences from QB
   *None

See also
   * MKI
   * MKL
   * MKS
   * CVD
   * CVI
   * CVL
   * CVS



---------------------------------------------------------- KeyPgMkshort ----
MKShort

Does a binary copy from a Short variable to a String, setting its length to 
2 bytes

Syntax
   Declare Function MKShort ( ByVal number As Short ) As String

Usage
   result = MKShort[$](number)

Parameters
   number
      A Short variable to binary copy to a String.

Return Value
   Returns a String with a binary copy of the Short.

Description
   Does a binary copy  from a SHORT variable to a string, setting its 
   length to 2 bytes. The resulting string can be read back to a Short by 
   CVShort

   This function is useful to write numeric values to buffers without using 
   a Type definition.

Example
   Dim a As Short, b As String
   a = 4534
   b = MKShort(a)
   Print a, CVShort(b)
   Sleep

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Mkshort.

Differences from QB
   * In QBasic this function is called MKI.

See also
   * CVShort



-------------------------------------------------------- KeyPgOpModulus ----
Operator Mod (Modulus)

Finds the remainder from a division operation

Syntax
   Declare Operator Mod ( ByRef lhs As Integer, ByRef rhs As Integer ) As 
   Integer

Usage
   result = lhs Mod rhs

Parameters
   lhs
      The left-hand side dividend expression.
   rhs
      The right-hand side divisor expression.

Return Value
   Returns the remainder of a division operation.

Description
   Operator Mod (Modulus) divides two Integer expressions and returns the 
   remainder. Float numeric values are converted to Integer by rounding up 
   or down.

   Neither of the operands are modified in any way.

   This operator can be overloaded for user-defined types.

Example
   Print 47 Mod 7
   Print 5.6 Mod 2.1
   Print 5.1 Mod 2.8

Output:

   5
   0
   2

This is because: 
   * 47 divided by 7 gives a remainder of 5
   * 5.6 is rounded to 6 while 2.1 is rounded to 2. This makes the problem 
     6 MOD 2 which means 6 divided by 2 which gives a remainder of 0
   * 5.1 is rounded to 5 while 2.8 is rounded to 3. This makes the problem 
     5 MOD 3 which means 5 divided by 3 which gives a remainder of 2

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * None

See also
   * Mathematical Functions



------------------------------------------------------------ KeyPgMonth ----
Month

Gets the month of the year from a Date Serial

Syntax
   Declare Function Month ( ByVal date_serial As Double ) As Long

Usage
   #include "vbcompat.bi"
   result = Month( date_serial )

Parameters
   date_serial
      the date

Return Value
   Returns the month number from a variable containing a date in  
   Date Serial  format.

   The month values are in the range 1-12 being 1 for January and 12 for 
   December.

Description

   The compiler will not recognize this function unless vbcompat.bi is 
   included.

Example
   #include "vbcompat.bi"

   Dim a As Double = DateSerial(2005,11,28) + TimeSerial(7,30,50)

   Print Format(a, "yyyy/mm/dd hh:mm:ss "); Month(a)

Differences from QB
   * Did not exist in QB. This function appeared in PDS and VBDOS

See also
   * Date Serials



-------------------------------------------------------- KeyPgMonthname ----
MonthName

Gets the name of a month from its integral representation

Syntax
   Declare Function MonthName ( ByVal month As Long, ByVal abbreviate As 
   Long = 0 ) As String

Usage
   #include "vbcompat.bi"
   result = MonthName( month_number [, abreviate ] )

Parameters
   month
      the number of the month of the year - 1:January through 12:December
   abbreviate
      flag to indicate that name should be abbreviated

Return Value
   Returns the local operating system language month name from month value 
   1 to 12.

Description
   If abbreviate is true, the month name abbreviation  is returned. If 
   omitted or false, the whole name is returned.
    
   The compiler will not recognize this function unless vbcompat.bi or 
   datetime.bi is included.

Example
   #include "vbcompat.bi"

   Dim ds As Double = DateSerial(2005, 11, 28) + TimeSerial(7, 30, 50)

   Print Format(ds, "yyyy/mm/dd hh:mm:ss "); MonthName(Month(ds))

Differences from QB
   * Did not exist in QB. This function appeared in Visual Basic.

See also
   * Date Serials



--------------------------------------------------------- KeyPgMultikey ----
MultiKey

Detects the status of keys by keyboard scancode.

Syntax
   Declare Function MultiKey ( ByVal scancode As Long ) As Long

Usage
   result = MultiKey(scancode)

Parameters
   scancode
      The scan code of the key to check.

Return Value
   Returns -1 if the key for the specified scan code is pressed, otherwise 
   returns 0.

Description
   MultiKey is a function which will detect the status of any key, 
   determined by scancode, at any time. It will return -1 if the key is 
   pressed, otherwise it will return 0. The keyboard input buffer is not 
   disabled while you use MultiKey; that is, pressed keys will be stored 
   and subsequently returned by your next call to Inkey. This means you 
   have to empty Inkey manually when you finish using MultiKey, using 
   something like the following method:
   While Inkey <> "": Wend '' loop until the Inkey buffer is empty

   Keeping Inkey to work while you use MultiKey allows more flexibility and 
   can be useful to detect Chr(255)+"k" combo returned on window close 
   button click, if a windowed graphics mode has been set via the Screen 
   statement. For a list of accepted scancodes, see DOS keyboard scancodes; 
   these are guaranteed to be valid for all FreeBASIC supported platforms.
   MultiKey should always work in graphics mode, as long as the screen is 
   Unlocked. Support in the console depends on the platform the program is 
   run on though, and cannot be guaranteed.

Example
   #include "fbgfx.bi"
   #if __FB_LANG__ = "fb"
   Using FB '' Scan code constants are stored in the FB namespace in lang FB
   #endif

   Dim As Integer x, y

   ScreenRes 640, 480

   Color 2, 15

   x = 320: y = 240
   Do
      ' Check arrow keys and update the (x, y) position accordingly
      If MultiKey(SC_LEFT ) And x >   0 Then x = x - 1
      If MultiKey(SC_RIGHT) And x < 639 Then x = x + 1
      If MultiKey(SC_UP   ) And y >   0 Then y = y - 1
      If MultiKey(SC_DOWN ) And y < 479 Then y = y + 1
      
      ' Lock the page while we work on it
      ScreenLock
         ' Clear the screen and draw a circle at the position (x, y)
         Cls
         Circle(x, y), 30, , , , ,F
      ScreenUnlock
      
      Sleep 15, 1
      
      ' Run loop until user presses Escape
   Loop Until MultiKey(SC_ESCAPE)

   ' Clear Inkey buffer
   While Inkey <> "": Wend

   Print "Press CTRL and H to exit..."

   Do
      Sleep 25
      
      '' Stay in loop until user holds down CTRL and H at the same time
      If MultiKey(SC_CONTROL) And MultiKey(SC_H) Then Exit Do
   Loop

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Multikey.

Differences from QB
   * New to FreeBASIC

See also
   * Keyboard scancodes
   * GetMouse
   * GetJoystick
   * Screen (Graphics)
   * Inkey



------------------------------------------------------ KeyPgMutexCreate ----
MutexCreate

Creates a mutex used for synchronizing the execution of threads

Syntax
   Declare Function MutexCreate ( ) As Any Ptr

Usage
   result = MutexCreate

Return Value
   The Any Ptr handle of the mutex created, or the null pointer (0) on 
   failure.

Description
   Mutexes, short for "Mutually Exclusive", are a way of synchronizing 
   shared data within threads.  If there is a global variable used by 
   multiple threads (or a local static variable used by a single thread 
   called multiple times), it should be "locked" during its use with a 
   mutex.  This halts all threads using MutexLock with that mutex 
   (including the main thread executing main program), until it is unlocked 
   with MutexUnlock.

   Mutexcreate creates a mutex, returning a handle which is to be referred 
   to when locking, unlocking, or destroying the mutex.  Mutexes created 
   with Mutexcreate should be destroyed when no longer needed or before the 
   end of the program with MutexDestroy.

   A  mutex is a lock that guarantees three things:
   1. Atomicity - Locking a mutex is an atomic operation, meaning that the 
   operating system (or threads library) assures you that if you locked a 
   mutex, no other thread succeeded in locking this mutex at the same time.
   2. Singularity - If a thread managed to lock a mutex, it is assured that 
   no other thread will be able to lock the thread until the original 
   thread releases the lock.
   3. Non-Busy Wait - If a thread attempts to lock a thread that was locked 
   by a second thread, the first thread will be suspended (and will not 
   consume any CPU resources) until the lock is freed by the second thread. 
   At this time, the first thread will wake up and continue execution, 
   having the mutex locked by it. 

Example
   See also the ThreadCreate examples.

   'Visual example of mutual exclusion between 2 threads by using Mutex:
   'the "user-defined thread" computes the points coordinates on a circle,
   'and the "main thread" plots the points.
   '
   'Principle of mutual exclusion
   '          Thread#A                XOR                  Thread#B
   '.....                                         .....
   'MutexLock(mut)                                MutexLock(mut)
   '  Do_something#A_with_exclusion                 Do_something#B_with_exclusion
   'MutexUnlock(mut)                              MutexUnlock(mut)
   '.....                                         .....
   '
   'Behavior:
   '- The first point must be pre-calculated.
   '- Nothing prevents that a same calculated point could be plotted several times
   '(depends on execution times of the loops between main thread and user thread).
   '- Nothing prevents that a calculated point could be not plotted
   '(same remark on the loop times).
   '
   'If you comment out the lines containing "MutexLock" and "MutexUnlock"
   '(inside "user-defined thread" or/and "main thread"),
   'there will be no longer mutual exclusion between computation of coordinates and plotting of points,
   'and many points will not be plotted on circle (due to non coherent coordinates).

   '-----------------------------------------------------------------------------------------------------

   Type ThreadUDT                                   'Generic user thread UDT
      Dim handle As Any Ptr                        'Any Ptr handle to user thread
      Dim sync As Any Ptr                          'Any Ptr handle to mutex
      Dim quit As Byte                             'Boolean to end user thread
      Declare Static Sub Thread (ByVal As Any Ptr) 'Generic user thread procedure
      Dim procedure As Sub (ByVal As Any Ptr)      'Procedure(Any Ptr) to be executed by user thread
      Dim p As Any Ptr                             'Any Ptr to pass to procedure executed by user thread
      Const False As Byte = 0                      'Constante "false"
      Const True As Byte = Not False               'Constante "true"
   End Type

   Static Sub ThreadUDT.Thread (ByVal param As Any Ptr) 'Generic user thread procedure
      Dim tp As ThreadUDT Ptr = param                  'Casting to generic user thread UDT
      Do
         Static As Integer I
         MutexLock(tp->sync)                          'Mutex (Lock) for user thread
         tp->procedure(tp->p)                         'Procedure(Any Ptr) to be executed by user thread
         I += 1
         Locate 30, 38
         Print I;
         MutexUnlock(tp->sync)                        'Mutex (Unlock) for user thread
         Sleep 5
      Loop Until tp->quit = tp->True                   'Test for ending user thread
   End Sub

   '-----------------------------------------------------------------------------------------------------

   Type Point2D
      Dim x As Integer
      Dim y As Integer
   End Type

   Const x0 As Integer = 640 / 2
   Const y0 As Integer = 480 / 2
   Const r0 As Integer = 200
   Const pi As Single = 4 * Atn(1)

   Sub PointOnCircle (ByVal p As Any Ptr)
      Dim pp As Point2D Ptr = p
      Dim teta As Single = 2 * pi * Rnd
      pp->x = x0 + r0 * Cos(teta)
      Sleep 5                            'To increase possibility of uncorrelated data occurrence
      pp->y = y0 + r0 * Sin(teta)
   End Sub

   Screen 12
   Locate 30, 2
   Print "<any_key> : exit";
   Locate 30, 27
   Print "calculated:";
   Locate 30, 54
   Print "plotted:";

   Dim Pptr As Point2D Ptr = New Point2D
   PointOnCircle(Pptr)                   ' Computation for a first point valid on the circle

   Dim Tptr As ThreadUDT Ptr = New ThreadUDT
   Tptr->sync = MutexCreate
   Tptr->procedure = @PointOnCircle
   Tptr->p = Pptr
   Tptr->handle = ThreadCreate(@ThreadUDT.Thread, Tptr)

   Do
      Static As Integer I
      Sleep 5
      MutexLock(Tptr->sync)   'Mutex (Lock) for main thread
      PSet (Pptr->x, Pptr->y) 'Plotting one point
      I += 1
      Locate 30, 62
      Print I;
      MutexUnlock(Tptr->sync) 'Mutex (Unlock) for main thread
   Loop Until Inkey <> ""
    
   Tptr->quit = Tptr->True
   ThreadWait(Tptr->handle)
   MutexDestroy(Tptr->sync)
   Delete Tptr
   Delete Pptr

   Sleep

   See also the similar CondCreate example

Dialect Differences
   * Threading is not allowed in the -lang qb dialect.

Platform Differences
   * The DOS version of FreeBASIC does not allow for threads, as the OS 
     does not support them.
   * In Linux the threads are always started in the order they are 
     created, this can't be assumed in Win32. It's an OS, not a FreeBASIC 
     issue. 

Differences from QB
   * New to FreeBASIC

See also
   * MutexDestroy
   * MutexLock
   * MutexUnlock
   * ThreadCreate
   * ThreadWait



----------------------------------------------------- KeyPgMutexDestroy ----
MutexDestroy

Destroys a mutex

Syntax
   Declare Sub MutexDestroy ( ByVal id As Any Ptr )

Usage
   MutexDestroy( id )

Parameters
   id
      The Any Ptr handle of the mutex to be destroyed.

Description
   Mutexdestroy discards a mutex created by MutexCreate.  This call should 
   be executed after any threads using the mutex are no longer in use.

   See MutexCreate for more general information on mutexes.

Example
   See the examples in MutexCreate and also ThreadCreate.

Dialect Differences
   * Threading is not allowed in the -lang qb dialect.

Platform Differences
   * The DOS version of FreeBASIC does not allow for threads, as the OS 
     does not support them.
   * In Linux the threads are always started in the order they are 
     created, this can't be assumed in Win32. It's an OS, not a FreeBASIC 
     issue. 

Differences from QB
   * New to FreeBASIC

See also
   * MutexCreate
   * MutexLock
   * MutexUnlock
   * ThreadCreate
   * ThreadWait



-------------------------------------------------------- KeyPgMutexLock ----
MutexLock

Acquires a mutex

Syntax
   Declare Sub MutexLock ( ByVal id As Any Ptr )

Usage
   MutexLock( id )

Parameters
   id
      The Any Ptr handle of the mutex to be locked.

Description
   Mutexlock halts any other threads using a mutex "handle", generated by 
   MutexCreate, until the handle is unlocked with MutexUnlock.
   Such a halted thread has its execution suspended and does not consume 
   any CPU time until the mutex is unlocked.

   See MutexCreate for more general information on mutexes.

Example
   See also the examples in MutexCreate and also ThreadCreate.

   'Example of mutual exclusion for synchronization between 2 threads
   'by using 2 Mutexes only (by self lock and mutual unlock):
   'The Producer works one time, then the Consumer works one time.
   '
   'Principle of synchronisation by mutual exclusion
   '(initial condition: mut#A and mut#B locked)
   '
   '          Thread#A              XORs              Thread#B
   'Do_something#A_with_exclusion          MutexLock(mut#A)
   'MutexUnlock(mut#A)                       Do_something#B_with_exclusion
   '.....                                  MutexUnlock(mut#B)
   'MutexLock(mut#B)                       .....

   '----------------------------------------------------------------------

   Dim Shared produced As Any Ptr
   Dim Shared consumed As Any Ptr
   Dim consumer_id As Any Ptr
   Dim producer_id As Any Ptr

   Sub consumer ( ByVal param As Any Ptr )
      For i As Integer = 0 To 9
         MutexLock produced
         Print , ",consumer gets:" ; i
         MutexUnlock consumed
         Sleep 5
      Next i
   End Sub

   Sub producer ( ByVal param As Any Ptr )
      For i As Integer = 0 To 9
         Print "Producer puts:" ; i;
         MutexUnlock produced
         MutexLock consumed
      Sleep 5
   Next i
   End Sub

   produced = MutexCreate
   consumed = MutexCreate
   If ( produced = 0 ) Or ( consumed = 0 ) Then
      Print "Error creating mutexes! Exiting..."
      Sleep
      End
   End If

   MutexLock produced
   MutexLock consumed

   consumer_id = ThreadCreate ( @ consumer )
   producer_id = ThreadCreate ( @ producer )
   If ( producer_id = 0 ) Or ( consumer_id = 0 ) Then
      Print "Error creating threads! Exiting..."
      Sleep
      End
   End If

   ThreadWait consumer_id
   ThreadWait producer_id

   MutexDestroy consumed
   MutexDestroy produced

   Sleep

   ' 'Threadcreate' launches one time the user-defined Sub in a separate execution thread
   '    (which runs simultaneously with the rest of the main code).
   ' If you want obtain a periodically display from the thread,
   '    you must put (into the thread) a [Do...Loop] block with a 'Sleep x' to adjust the display period
   '    and a flag to exit the loop (and terminate the thread).
   '
   ' Warning:
   ' - Each thread has not its own memory of cursor position, so for that and other reasons, it is mandatory
   '      to apply an exclusion between displaying from the main code (main thread) and displaying from the user thread,
   '      by using a 'Mutex' ([Mutexlock...Mutexunlock] block).
   '   At beginning of each display block both into main thread and user thread,
   '      the initial cursor position must also be re-initialized.
   ' - The input keywords (like keyboard, mouse) cannot be safely run when the screen is locked,
   '      therefore a such keyword must be outside of any [Screenlock...Screenunlock] block (outside this block in its own thread,
   '      and protected of block of another thread by a 'Mutex').
   '
   ' See below a rustic program, but showing all these constraints:

   Dim Shared As Any Ptr sync   '' pointer to Mutex
   Dim Shared As Byte quit = 0  '' flag to end user thread
   Dim As Any Ptr handle        '' pointer to thread handle

   Sub ProcedureThread (ByVal param As Any Ptr)  '' param not used in thread body
      Do
         MutexLock(sync)       '' Mutex for exclusion of displaying
            ScreenLock        '' keyword after Mutexlock
               Locate 1, 70  '' re-initialize cursor position
               Print Date
               Locate , 71
               Print Time;
            ScreenUnlock      '' keyword before Mutexunlock
         MutexUnlock(sync)     '' end exclusion
         Sleep 100             '' ajust display period
      Loop Until quit <> 0      '' test for exit thread
   End Sub

   Screen 12
   Locate 1, 62
   Print "Date:"
   Locate , 62
   Print "Time:";
   Locate 15, 20
   Print "Mouse (position):"
   Locate , 20
   Print "Mouse (buttons) :";
   Locate 30, 2
   Print "<any_key> or <click on window close button>: exit";

   sync = MutexCreate                          '' create Mutex (before Threadcreate)
   handle = ThreadCreate(@ProcedureThread, 0)  '' launch thread

   Dim As String s
   Do
      MutexLock(sync)                     '' Mutex for exclusion of displaying
         Dim As Integer x, y, b
         GetMouse x, y , , b             '' keyword outside [Screenlock...Screenunlock] and protected by Mutex
         ScreenLock                      '' keyword after Mutexlock
            Locate 15, 37               '' re-initialize cursor position
            Print Using "######"; x; y
            Locate , 43
            Print Using "##"; b;
         ScreenUnlock                    '' Keyword before Mutexunlock
         s = Inkey                       '' keyword outside [Screenlock...Screenunlock] and protected by Mutex
      MutexUnlock(sync)                   '' end exclusion
      Sleep 10                            '' ajust display period
   Loop Until s <> ""
    
   quit = Not quit     '' order thread end
   ThreadWait(handle)  '' wait for thread end
   MutexDestroy(sync)  '' free Mutex

Dialect Differences
   * Threading is not allowed in the -lang qb dialect.

Platform Differences
   * The DOS version of FreeBASIC does not allow for threads, as the OS 
     does not support them.
   * In Linux the threads are always started in the order they are 
     created, this can't be assumed in Win32. It's an OS, not a FreeBASIC 
     issue. 

Differences from QB
   * New to FreeBASIC

See also
   * MutexCreate
   * MutexDestroy
   * MutexUnlock
   * ThreadCreate
   * ThreadWait



------------------------------------------------------ KeyPgMutexUnlock ----
MutexUnlock

Releases a mutex lock

Syntax
   Declare Sub MutexUnlock ( ByVal id As Any Ptr )

Usage
   MutexUnlock( id )

Parameters
   id
      The Any Ptr handle of the mutex to be unlocked.

Description
   Mutexunlock releases a mutex "handle" created by MutexCreate, and locked 
   with MutexLock.  This allows other threads sharing the mutex to continue 
   execution.

   See MutexCreate for more general information on mutexes.

Example
   See the examples in MutexCreate and also ThreadCreate.

Dialect Differences
   * Threading is not allowed in the -lang qb dialect.

Platform Differences
   * The DOS version of FreeBASIC does not allow for threads, as the OS 
     does not support them.
   * In Linux the threads are always started in the order they are 
     created, this can't be assumed in Win32. It's an OS, not a FreeBASIC 
     issue. 

Differences from QB
   * New to FreeBASIC

See also
   * MutexCreate
   * MutexDestroy
   * MutexLock
   * ThreadCreate
   * ThreadWait




============================================================================
    N

------------------------------------------------------------ KeyPgNaked ----
Naked

Write functions without prolog/epilog code

Syntax
   {Sub | Function} identifier Naked [calling_convention] ( param_list ) [[ 
   ByRef ] As data_type]
      asm_statements
   End {Sub | Function}

Parameters
   identifier - name of the procedure.
   calling_convention - calling convention of the procedure - can be cdecl, 
   pascal, or stdcall
   asm_statements - the code in the procedure body.  The code for handling 
   parameters and returning values must all be done manually.  Note that 
   the methods for doing these can change, depending on the 
   calling convention.
   param_list - parameters to be passed to the procedure.
   data_type - the data type of the function.

Description
   Naked allows the programmer to write procedures without the compiler 
   generating any prolog/epilog code.  This is useful when writing small, 
   fast functions in Asm without any unnecessary overhead.

Example
   '' Naked cdecl function
   Function subtract_c Naked cdecl _   '' parameters pushed onto call stack in reverse order of declaration
      ( _
         ByVal a As Long, _
         ByVal b As Long _        '' parameter pushed onto stack in first
      ) As Long
      
      Asm
         mov eax, dword Ptr [esp+4]  '' eax = a
         Sub eax, dword Ptr [esp+8]  '' eax -= b
         ret                         '' return result in eax
      End Asm
      
   End Function

   Print subtract_c( 5, 1 ) '' 5 - 1

   ''---------------------------------------------------------------------------------------------------------------------

   '' Naked stdcall function
   Function subtract_s Naked stdcall _ '' parameters pushed onto call stack in reverse order of declaration
                      _          '' called procedure responsible for removing parameters from stack
                      _          ''   (appending constant to RET instruction specifying number of bytes to release)
      ( _
         ByVal a As Long, _
         ByVal b As Long _        '' parameter pushed onto stack in first
      ) As Long
      
      Asm
         mov eax, dword Ptr [esp+4]  '' eax = a
         Sub eax, dword Ptr [esp+8]  '' eax -= b
         ret 8                       '' return result in eax and 8 bytes (2 integers) to release
      End Asm
      
   End Function

   Print subtract_s( 5, 1 ) '' 5 - 1 

   ''---------------------------------------------------------------------------------------------------------------------

   '' Naked pascal function
   Function subtract_p Naked pascal _  '' parameters pushed onto call stack in same order as declaration
                      _          '' called procedure responsible for removing parameters from stack
                      _          ''   (appending constant to RET instruction specifying number of bytes to release)
      ( _
         ByVal a As Long, _       '' parameter pushed onto stack in first
         ByVal b As Long _
      ) As Long
      
      Asm
         mov eax, dword Ptr [esp+8]  '' eax = a
         Sub eax, dword Ptr [esp+4]  '' eax -= b
         ret 8                       '' return result in eax and 8 bytes (2 longs) to release
      End Asm
      
   End Function

   Print subtract_p( 5, 1 ) '' 5 - 1

   '' Naked cdecl function
   '' plus ecx register preserved in asm block by creating user stack
   Function subtract_cp Naked cdecl _      '' parameters pushed onto call stack in reverse order of declaration
      ( _
         ByVal a As Long, _
         ByVal b As Long _            '' parameter pushed onto stack in first
      ) As Long
      
      Asm
         push ebp                        '' push ebp onto stack   => esp -= 4
         mov ebp, esp                    '' ebp = esp
                                 ''    => create user stack 4 bytes above call stack
         push ecx                        '' push ecx onto user stack   => esp -= 4
         mov eax, dword Ptr [(ebp+4)+4]  '' eax = a   (supplementary offset of +4 bytes only due to 'push ebp')
         mov ecx, dword Ptr [(ebp+8)+4]  '' ecx = b   (supplementary offset of +4 bytes only due to 'push ebp')
         Sub eax, ecx                    '' eax -= ecx
         pop ecx                         '' pop ecx from user stack   => esp += 4
         mov esp, ebp                    '' esp = ebp
         pop ebp                         '' pop ebp from stack   => esp += 4
                                 ''    => discard user stack
         ret                             '' return result in eax
      End Asm
      
   End Function

   Print subtract_cp( 5, 1 ) '' 5 - 1

Platform Differences
   * The default calling convention depends on the target platform, thus 
     it is best to specify the expected calling convention explicitly when 
     using Naked.

Differences from QB
   * New to FreeBASIC

See also
   * Asm
   * Calling Conventions
   * Function
   * Sub
   * cdecl
   * pascal
   * stdcall



------------------------------------------------------------- KeyPgName ----
Name

Renames a file on disk

Syntax
   Declare Function Name( ByRef oldname As Const String, ByRef newname As 
   Const String ) As Long

Usage
   result = Name( oldname, newname )

Parameters
   oldname
      Name of an existing file.
   newname
      New name of the file.

Return Value
   Returns zero (0) on success and non-zero on failure.

Description
   Renames a file or folder originally called oldname to newname.

   The function is not guaranteed to succeed if a file/folder exists with 
   the same name.  It may  succeed, overwriting the original, or it may 
   fail.  For greater control, FileExists could be used to test for an 
   existing file, and Kill could be used to delete an existing file 
   beforehand.

Example
   Dim OldName As String
   Dim NewName As String
   Dim result As Integer 

   OldName = "dsc001.jpg"
   NewName = "landscape.jpg"

   result = Name( OldName, NewName )
   If 0 <> result Then 
      Print "error renaming " & oldname & " to " & newname & "."
   End If

Differences from QB
   * In QB, NAME required AS rather than a comma between the old and new 
     names.  This is because NAME was a language keyword rather than a 
     function.

See also
   * Kill
   * FileExists



-------------------------------------------------------- KeyPgNamespace ----
Namespace

Declares a namespace block

Syntax
   Namespace identifier [ Alias "aliasname" ]
      statements
   End Namespace

Parameters
   identifier
      The name of the namespace (including nested names specifier).
   aliasname
      An alternate external name for the namespace.

Description
   Namespaces allow to group entities like objects (predefined data-types 
   and UDTs including Union and Enum) and procedures (including their 
   declarations) under a name. This way the global scope can be divided in 
   "sub-scopes", each one with its own name. 

   Whether or not explicitly declared a namespace in a source file, the 
   compiler adds a default namespace. This unnamed namespace, called the 
   global namespace, is present in every file.
   Any identifier in the global namespace is available for use in a named 
   namespace (even global symbols with the same name as keywords may be 
   declared inside a namespace). 

   Namespaces implicitly have public access and this is not modifiable.
   A variable declared inside a namespace is always implicitly static and 
   visible throughout the entire program even if the declaration modifier 
   Shared is not specified (static and shared are optional, but this may 
   improve code readability).
   To access from outside a defined symbol in a namespace, add the 
   namespace identifier followed by a dot as a prefix of the symbol, or 
   bring the namespace symbols into the current scope by means of the 
   Using (Namespaces) statement.

   Namespaces do not have any effect on the visibility of a define.
   It is possible to define a namespace in two or more declarations.

   Namespaces are commonly used in libraries where you don't want all the 
   symbols from that library to crowd the user's space (called the global 
   namespace). 
   For example, if you used the "Forms" library, it might define the Point 
   type for describing an X and Y coordinate, and you might also define it 
   for another purpose. This can be resolved by creating the namespace 
   Forms for the library, and then referring to its Point type as 
   Forms.Point, and yours as just Point. 

   To access duplicated symbols defined in the global namespace, add one 
   (or two) dot(s) as prefix: .SomeSymbol (or ..SomeSymbol if inside a 
   With..End With block).

Example
   Namespace Forms
      Type Point '' A 2D point
         As Integer x
         As Integer y
      End Type
      '' Since we are inside of the namespace, Point resolves to Forms.Point.
      Sub AdjustPoint( ByRef pt As Point, ByVal newx As Integer, ByVal newy As Integer )
         pt.x = newx
         pt.y = newy
      End Sub
   End Namespace

   Type Point '' A 3D point
      As Integer x
      As Integer y
      As Integer z
   End Type

   Sub AdjustPoint( ByRef pt As Point, ByVal newx As Integer, ByVal newy As Integer, ByVal newz As Integer )
      pt.x = newx
      pt.y = newy
      pt.z = newz
   End Sub

   Dim pt1 As Point
   AdjustPoint( pt1, 1, 1, 1 )
   Dim pt2 As Forms.Point
   Forms.AdjustPoint( pt2, 1, 1 )

   Namespaces are GCC C++ compatible, the following code aims to test that.
   (cpp)
   // mylib.cpp
   // To compile:
   //	g++ -c mylib.cpp -o mylib.o
   //	ar rcs libmylib.a mylib.o

   #include <string.h>
   #include <ctype.h>

   Namespace mylib
   {
   	Int test() 
   	{
   		Return 123;
   	}
   }

   '' test.bas

   Extern "c++" Lib "mylib"
      Namespace mylib Alias "mylib"
         Declare Function test() As Integer
      End Namespace
   End Extern

   Print mylib.test()

Dialect Differences
   * Namespaces are not supported in the -lang qb dialect.

Differences from QB
   * New to FreeBASIC

See also
   * Using (Namespaces)



------------------------------------------------------------ KeyPgOpNew ----
Operator New Expression

Operator to dynamically allocate memory and construct data of a specified 
type.

Usage
   result = New datatype
      or
   result = New datatype ( initializers, ... )
      or
   result = New datatype[ count ]

Parameters
   datatype
      Name of the data type to create.
   initializers
      Initial value(s) for the variable.
   count
      Exact number of elements to allocate.

Return Value
   A pointer of type datatype to the newly allocated data, or null pointer 
   if the memory allocation failed.

Description
   The New Expression operator dynamically allocates memory and constructs 
   a specified data type.

   For simple types, like integers, an initial value can be given. For 
   types without constructors, initial values can be specified for each 
   field (either with default initializer at data-field declaration, or 
   with initializer list as in New datatype (initializers, ..) if all type 
   data-fields are numeric primitives only and without any default 
   initializers). For types with at least one constructor, the initialize 
   list (if any) must match an existing constructor. If no initializers are 
   given, the default values for those types will be set.

   New[] Expression operator is the (one-dimensional) array-version of the 
   New Expression operator and allocates enough memory for the specified 
   number of objects. The default constructor for the type will be used to 
   set the initial values for each item.

   Objects created with New Expression operator must be freed with 
   Delete Statement operator. Object array created with New[] Expression 
   operator must be freed with Delete[] Statement operator, the 
   array-version of Delete Statement operator. You cannot mix and match the 
   different versions of the operators.

   Specifying an initial value of Any, as in New datatype (Any) will 
   allocate memory for the type, but not initialize the data.  This is only 
   valid on data types that do not have constructors (otherwise for data 
   types with constructors, syntax of simple memory allocation with pointer 
   conversion, like Cptr(datatype Ptr, Allocate(Sizeof(datatype))), can be 
   substituted to the invalid use of New...Any).

   Specifying an initial value of Any, as in New datatype[count] {Any} will 
   allocate memory for the array, but not initialize the data.  This is 
   only valid on data types that do not have constructors (otherwise for 
   data types with constructors, syntax of simple memory allocation with 
   pointer conversion, like Cptr(datatype Ptr, Allocate(count * 
   Sizeof(datatype))), can be substituted to the invalid use of New...Any).

   The total memory, in bytes, to be allocated with New datatype[count] 
   expression is calculated as sizeof(datatype) * count, plus 
   sizeof(uinteger) if there is an implicit or explicit Destructor.  The 
   total memory requested in bytes to be allocated must not overflow the 
   value that can be held by a UInteger.  The extra uinteger, if allocated, 
   stores the number of elements as part of the allocation, so that 
   Delete Statement can determine the count of destructors to call.

   If the memory allocation fails, a null pointer is returned and no 
   constructors are called.

   The dynamic memory allocation process part provided by the New 
   Expression operator can be overloaded for user-defined types as a member 
   operator New Overload. The following process part for data construction 
   can never be modified.

   Note: Using pointer = New datatype[count] may be unsafe if pointer was 
   declared with a type different from datatype (for sub-type polymorphism 
   purpose for example), because the pointer arithmetic fails to access the 
   elements if the pointer type size is different from the size of datatype 
   (when using Operator [] (Pointer Index) or adding an offset (element 
   number) to the pointer, or even when Delete[] Statement itself (the 
   array-version of Delete Statement) must destroy the elements).

Example
   Type Rational
      As Integer   numerator, denominator
   End Type

   Scope

      ' Create and initialize a "rational" and store its address.
      Dim p As Rational Ptr = New Rational(3, 4)
     
      ' test if null return pointer
      If (p = 0) Then
         Print "Error: unable to allocate memory, quitting."
         End -1
      End If

      Print p->numerator & "/" & p->denominator

      ' Destroy the rational and give its memory back to the system. 
      Delete p

   End Scope

   Scope

      ' Allocate memory for 100 integers and store the address of the first one.
      Dim p As Integer Ptr = New Integer[100]

      ' test if null return pointer
      If (p = 0) Then
         Print "Error: unable to allocate memory, quitting."
         End -1
      End If

      ' Assign some values to the integers in the array.
      For i As Integer = 0 To 99
         p[i] = i
      Next

      ' Free the entire integer array.
      Delete[] p

   End Scope

   Sleep

   '' Example of nested New [] to get a 2-dimentional object array (4*3)

   Type UDT
      Dim As Integer N
      Declare Constructor ()
      Declare Destructor ()
   End Type

   Constructor UDT ()
      Print "Constructor",
   End Constructor

   Destructor UDT ()
      Print "Destructor",
   End Destructor

   Dim As UDT Ptr Ptr p = New UDT Ptr [4]  '' New [] allocation for the first dimension:
                                 ''   no internal allocation of extra uinteger because
                                 ''   allocation of array of pointers (to UDT objects with destructor)
   For I As Integer = 0 To 3
      p[I] = New UDT [5]                  '' New [] allocations for the last dimension:
                                 ''   internal allocation of an extra uinteger for each New [],
                                 ''   because allocation of an array of UDT objects with destructor
      Print
   Next I

   For I As Integer = 0 To 3
      For J As Integer = 0 To 4
         p[I][J].N = I * 10 + J  '' assignment of each object array element
      Next J
   Next I

   Print
   For I As Integer = 0 To 3
      For J As Integer = 0 To 4
         Print p[I][J].N,        '' display of each object array element
      Next J
      Print
   Next I
   Print

   For I As Integer = 0 To 3
      Delete [] p[I]  '' Delete [] deallocations for the last dimension
      Print
   Next I
   Delete [] p         '' Delete [] deallocation for the first dimension)
   Print

   Sleep

      Output example:

   Constructor   Constructor   Constructor   Constructor   Constructor
   Constructor   Constructor   Constructor   Constructor   Constructor
   Constructor   Constructor   Constructor   Constructor   Constructor
   Constructor   Constructor   Constructor   Constructor   Constructor

    0             1             2             3             4
    10            11            12            13            14
    20            21            22            23            24
    30            31            32            33            34

   Destructor    Destructor    Destructor    Destructor    Destructor
   Destructor    Destructor    Destructor    Destructor    Destructor
   Destructor    Destructor    Destructor    Destructor    Destructor
   Destructor    Destructor    Destructor    Destructor    Destructor

Dialect Differences
   * Only available in the -lang fb dialect.

Differences from QB
   * New to FreeBASIC

See also
   * Delete Statement
   * Placement New
   * New Overload



--------------------------------------------------- KeyPgOpPlacementNew ----
Operator Placement New

Operator to construct an object at a specified memory address.

Syntax
   result = New(address) datatype
      or
   result = New(address) datatype ( initializers, ... )
      or
   result = New(address) datatype[ count ]

Parameters
   address 
      the location in memory to construct. the parenthesis are not 
      optional.
   initializers
      Initial value(s) for the variable.
   datatype
      name of the data type to construct.
   count
      Number of elements to construct.

Return Value
   A pointer of type datatype to the newly constructed data.

Description
   The Placement New operator constructs a specified data type at the 
   specified memory location. 

   For simple types, like integers, an initial value can be given. For 
   types without Constructors, initial values can be specified for each 
   field (either with default initializer at data-field declaration, or 
   with initializer list as in New datatype (initializers, ..) if all type 
   data-fields are numeric primitives only and without any default 
   initializers). For types with at least one constructor, the initialize 
   list (if any) must match an existing constructor. If no initializers are 
   given, the default values for those types will be set.

   Memory is not allocated when using the Placement New operator. Instead, 
   the memory at the specified address is used (the provided memory size 
   must be large enough to contain all the placement).
   It is incorrect to call Delete Statement on the address. The proper way 
   is to only call the destructor if one exists (implicitly or explicitly), 
   with syntax as for a member method by using member access operator.
   See examples below for proper Placement New operator usage.

   Placement New[] operator is the (one-dimensional) array-version of the 
   Placement New operator and constructs the specified number of objects 
   from the specified memory location. The default constructor for the type 
   will be used to set the initial values for each item.

   Specifying an initial value of Any, as in New(address)datatype (Any) or 
   New(address)datatype[count] {Any} will not initialize the data.  This is 
   only valid on data types that do not have constructors (otherwise for 
   data types with constructors, syntax of simple pointer conversion, like 
   Cptr(datatype Ptr, address), can be substituted to the invalid use of 
   New...Any).

   Because it does not provide any dynamic memory allocation process, the 
   Placement New operator (unlike the New Expression operator) does not 
   allow any overloading by a member operator for user-defined types.

   Note: Using pointer = New(address)datatype[count] may be unsafe if 
   pointer was declared with a type different from datatype (for sub-type 
   polymorphism purpose for example), because the pointer arithmetic fails 
   to access the elements if the pointer type size is different from the 
   size of datatype (when using Operator [] (Pointer Index) or adding an 
   offset (element number) to the pointer).

Example
   '' "placement new" example

   Type Rational
      As Integer    numerator, denominator
      Declare Constructor ( ByVal n As Integer, ByVal d As Integer )
      As String ratio = "/"
   End Type

   Constructor Rational ( ByVal n As Integer, ByVal d As Integer )
      This.numerator = n
      This.denominator = d
   End Constructor

   Scope
      
      '' allocate some memory to construct as a Rational
      Dim As Any Ptr ap = CAllocate(Len(Rational))
      
      '' make the placement new call
      Dim As Rational Ptr r = New (ap) Rational( 3, 4 )
      
      '' you can see, the addresses are the same, just having different types in the compiler
      Print ap, r
      
      '' confirm all is okay
      Print r->numerator & r->ratio & r->denominator
      
      '' delete must not be used with placement new
      '' destroying must be done explicitly if a destructor exists (implicitly or explicitly)
      ''   (in this example, the var-string member induces an implicit destructor)
      r->Destructor( )
      
      '' we explicitly allocated, so we explicitly deallocate
      Deallocate( ap )
      
   End Scope

Dialect Differences
   * Only available in the -lang fb dialect.

Differences from QB
   * New to FreeBASIC

See also
   * Destructor
   * New Expression



------------------------------------------------------------- KeyPgNext ----
Next

Control flow statement to mark the end of a For...Next loop.

Syntax
   Next [ identifier_list ]

Description
   Indicates the end of a statement block associated with a matching For 
   statement. 

   When Next is used on its own without an identifier_list, it closes the 
   most recent For statement block.

   identifier_list is optional and may be one or more variable names 
   separated by commas.  This form of the Next statement is retained for 
   compatibility with QB.  identifier_list, if given, must match the 
   identifiers used in the associated For statements in reverse order, from 
   inner to outer.

Example
   For i As Integer = 1 To 10
      For j As Integer = 1 To 2
         ' ...
      Next
   Next

   For i As Integer = 1 To 10
      For j As Integer = 1 To 2
         ' ...
      Next j
   Next i

   For i As Integer = 1 To 10
   For j As Integer = 1 To 2
      ' ...
   Next j,i

Differences from QB
   * ByRef arguments cannot be used as counters.

See also
   * For...Next



------------------------------------------------------- KeyPgResumenext ----
Resume Next

Error handling statement to resume execution after a jump to an error 
handler

Syntax
   Resume Next

Description
   Resume Next is used in the traditional QB error handling mechanism 
   within an error handler (called by On Error) to return execution to the 
   line after the one that caused the error.  Usually this is used to avoid 
   executing the same line and causing the error again.

   Resume Next resets the Err value to 0

Example
   '' Compile with -lang fblite or qb

   #lang "fblite"

   Dim As Single i, j

   On Error Goto ErrHandler

   i = 0
   j = 5
   j = 1 / i ' this line causes a divide-by-zero error; execution jumps to ErrHandler label

   Print "ending..."

   End ' end the program so that execution does not fall through to the error handler again

   ErrHandler:

   Resume Next ' execution jumps to 'Print "ending..."' line, but j is now in an undefined state

Dialect Differences
   *  RESUME NEXT is not supported in the -lang fb dialect. Statements can 
     be used in its function form to return an error code
   If Open( "text" For Input As #1 ) <> 0 Then
     Print "Unable to open file"
   End If

 

Differences from QB
   * Must compile with -ex or -exx option

See also
   * Err
   * Resume
   * Error Handling



------------------------------------------------------------ KeyPgOpNot ----
Operator Not (Complement)

Returns the bitwise-not (complement) of a numeric value

Syntax
   Declare Operator Not ( ByRef rhs As Byte ) As Integer
   Declare Operator Not ( ByRef rhs As UByte ) As Integer
   Declare Operator Not ( ByRef rhs As Single ) As Integer
   Declare Operator Not ( ByRef rhs As Double ) As Integer

   Declare Operator Not ( ByRef rhs As T ) As T

Usage
   result = Not rhs

Parameters
   rhs
      The right-hand side expression.
   T
      Any numeric or boolean type.

Return Value
   Returns the bitwise-complement of its operand.

Description
   This operator returns the bitwise-complement of its operand, a logical 
   operation that results in a value with bits set depending on the bits of 
   the operand.
   (for a boolean type, 'Not false' returns 'true' and 'Not true' returns 
   'false')

   The truth table below demonstrates all combinations of a 
   boolean-complement operation:

      +-------+------+
      |Rhs Bit|Result|
      |0      |1     |
      |1      |0     |
      +-------+------+

   This operator can be overloaded for user-defined types.

Example
   ' Using the NOT operator on a numeric value

   Dim numeric_value As Byte
   numeric_value = 15 '00001111

   'Result = -16 =     11110000
   Print Not numeric_value

   ' Using the NOT operator on conditional expressions
   Dim As UByte numeric_value1, numeric_value2
   numeric_value1 = 15
   numeric_value2 = 25

   If Not numeric_value1 = 10 Then Print "Numeric_Value1 is not equal to 10"
   If Not numeric_value2 = 25 Then Print "Numeric_Value2 is not equal to 25"

   ' This will output "Numeric_Value1 is not equal to 10" because
   ' the first IF statement is false.
   ' It will not output the result of the second IF statement because the
   ' condition is true. 

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * None

See also
   * Operator Truth Tables



-------------------------------------------------------------- KeyPgNow ----
Now

Gets the current system time as a Date Serial 

Syntax
   Declare Function Now ( ) As Double

Usage
   #include "vbcompat.bi"
   result = Now

Return Value
   Returns a date serial containing the system's date and time at execution 
   time.

Description
   As the time is the decimal part of a date serial, if the value of Now is 
   saved to an integer, the time in it will be reset to 00:00:00

   The compiler will not recognize this function unless vbcompat.bi is 
   included.

Example
   #include "vbcompat.bi"

   Dim a As Double = Now()

   Print Format(a, "yyyy/mm/dd hh:mm:ss") 

Differences from QB
   * Did not exist in QB. This function appeared in PDS and VBDOS

See also
   * Date Serials




============================================================================
    O

----------------------------------------------------------- KeyPgObject ----
Object

Built-in type providing run-time type information

Syntax
   Type Object
      As fb_BaseVT Ptr vtable_ptr
      Declare Constructor()
   End Type

Usage
   Type typename Extends Object
   End Type

   Dim variable As Object

Description
   Object is a built-in type which provides Run-Time Type Information 
   (RTTI) for all types derived from it using Extends, allowing them to be 
   used with Operator Is, and to support Virtual and Abstract methods.

   Extending the built-in Object type allows to add an extra hidden vtable 
   pointer field at the top of the Type. The vtable is used to dispatch 
   Virtual  and Abstract methods and to access information for run-time 
   type identification used by Operator Is.

Example
   See the Operator Is page, the Virtual and Abstract pages.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Object.

Differences from QB
   * New to FreeBASIC

See also
   * Extends
   * Extends Zstring
   * Extends Wstring
   * Operator Is
   * Virtual
   * Abstract



-------------------------------------------------------------- KeyPgOct ----
Oct

Converts a number to octal representation

Syntax
   Declare Function Oct ( ByVal number As UByte ) As String
   Declare Function Oct ( ByVal number As UShort ) As String
   Declare Function Oct ( ByVal number As ULong ) As String
   Declare Function Oct ( ByVal number As ULongInt ) As String
   Declare Function Oct ( ByVal number As Const Any Ptr ) As String

   Declare Function Oct ( ByVal number As UByte, ByVal digits As Long ) As 
   String
   Declare Function Oct ( ByVal number As UShort, ByVal digits As Long ) As 
   String
   Declare Function Oct ( ByVal number As ULong, ByVal digits As Long ) As 
   String
   Declare Function Oct ( ByVal number As ULongInt, ByVal digits As Long ) 
   As String
   Declare Function Oct ( ByVal number As Const Any Ptr, ByVal digits As 
   Long ) As String

Usage
   result = Oct[$]( number [, digits ] )

Parameters
   number
      A number or expression evaluating to a number.  A floating-point 
      number will be converted to a LongInt.
   digits
      Desired number of digits in the returned string.

Return Value
   A string containing the unsigned octal representation of number.

Description
   Returns the unsigned octal string representation of number. Octal digits 
   range from 0 to 7.

   If you specify digits > 0, the result string will be exactly that 
   length.  It will be truncated or padded with zeros on the left, if 
   necessary.

   The length of the returned string will not be longer than the maximum 
   number of digits required for the type of number (3 characters for Byte, 
   6 for Short, 11 for Long, and 22 for LongInt)

   If you want to do the opposite, i.e. convert an octal string back into a 
   number, the easiest way to do it is to prepend the string with "&O", and 
   convert it to an integer type, using a function like CInt, similarly to 
   a normal numeric string.  E.g. CInt("&O77")

Example
   Print Oct(54321)
   Print Oct(54321, 4)
   Print Oct(54321, 8)

   will produce the output:

   152061
   2061
   00152061

Dialect Differences
   * The string type suffix "$" is obligatory in the -lang qb dialect.
   * The string type suffix "$" is optional in the -lang fblite dialect.
   * The string type suffix "$" is forbidden in the -lang fb dialect.

Differences from QB
   * In QBASIC, there was no way to specify the number of digits returned.
   * The size of the string returned was limited to 32 bits, or 11 octal 
     digits.

See also
   * Bin
   * Hex
   * ValInt
   * ValLng



--------------------------------------------------------- KeyPgOffsetof ----
OffsetOf

Returns the offset of a field within a type.

Syntax
   #define OffsetOf(typename, fieldname) CInt( @Cast( typename Ptr, 0 )->
   fieldname )	

Usage
   result = OffsetOf( typename, fieldname )

Parameters
   typename
      Name of the type as defined using the Type...End Type statements.
   fieldname
      Name of the field as defined within the type (or within the base 
      types for a derived type).

Description
   For a non-derived type, OffsetOf will return the location fieldname as 
   offset in bytes from the beginning of typename.

   For a derived type, OffsetOf will return the location fieldname as 
   offset in bytes from the beginning of its highest base type.
   Note: if a member of the base type is overridden by a new member, the 
   offset of the old member cannot be accessed from the derived type.

Example
   Type MyType
     x As Single
     y As Single
     Union
      b As Byte
      i As Integer
     End Union
   End Type

   Print "OffsetOf x = "; OffsetOf(MyType, x)
   Print "OffsetOf y = "; OffsetOf(MyType, y)
   Print "OffsetOf b = "; OffsetOf(MyType, b)
   Print "OffsetOf i = "; OffsetOf(MyType, i)

Output
   OffsetOf x =  0
   OffsetOf y =  4
   OffsetOf b =  8
   OffsetOf i =  8

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Offsetof.

Differences from QB
   * New to FreeBASIC

See also
   * Type...End Type
   * SizeOf



---------------------------------------------------------- KeyPgOnerror ----
On Error

Error handling statement to set the current error handler

Syntax
   On [Local] Error Goto label

Parameters
   label
      Label to jump to when an error occurs

Description
   On Error triggers a jump to an error handler when an error occurs. Such 
   errors can be triggered by built-in statements such as Open, or when the 
   Error statement is used.

   Note: The error checking for built-in statements is only enabled if the 
   program is compiled with one of the -e, -ex or -exx options. On Error 
   remains working with Error even when none of these options are used.

   On Local Error can be used to specify a local error handler inside a 
   procedure. This allows for specialized per-procedure error handling and 
   will override the global error handler, if any. Without Local, the 
   handler must be in the main part of the module.
   Remark: Presently, the Local clause is ignored by the compiler.

   On Error Goto 0 deactivates the current error handler.

Example
   '' Compile with QB (-lang qb) dialect

   '$lang: "qb"

   On Error Goto errorhandler
   Error 24 '' simulate an error
   Print "this message will not be seen"

   errorhandler:
   Print "Error #"; Err; "!"
   End

   '' compile as: fbc onerror.bas -ex

   #lang "fblite"

   Function hFileExists( filename As String ) As Integer Static
      Dim f As Integer

      hFileExists = 0

      On Local Error Goto exitfunction

      f = FreeFile
      Open filename For Input As #f
      
      Close #f

      hFileExists = -1

   exitfunction:
      Exit Function
   End Function

      Print "File exists (0=false): "; hFileExists( Command )

      On Error Goto errhandler
      Error 1234
      Print "back from resume next"
      End 0

   errhandler:
      Print "error number: " + Str( Err ) + " at line: " + Str( Erl )
      Resume Next

Differences from QB
   * QB has no LOCAL clause and requires the label to be in the main part 
     of the module. 

See also
   * Error
   * Local
   * Err
   * Runtime Error Codes
   * Error Handling
   * Labels



---------------------------------------------------------- KeyPgOngosub ----
On...Gosub

Calls a label based on an expression

Syntax
   On expression GoSub label1[, ...]

Description
   Branches to different labels depending on the value of expression. An 
   expression value of 1 will branch to the first label, a value of 2 to 
   the second, etc.  If the value of expression is zero (0) or greater than 
   the number of items in the list, execution continues on the next 
   statement following the On...Gosub.

   This statement behaves exactly like GoSub and execution may return to 
   the statement following the On...Gosub using Return.

   It is recommended that the structured Select Case conditional statement 
   be used instead of On...Gosub.

Example
   '' Compile with -lang qb

   '$lang: "qb"

   choice = 3
   On choice GoSub labela, labelb, labelc
   Print "Good bye."
   End

   labela:
   Print "choice a"
   Return

   labelb:
   Print "choice b"
   Return

   labelc:
   Print "choice c"
   Return

Dialect Differences
   * Only available in the -lang qb and -lang fblite dialects.
   * On Gosub support is disabled by default in the -lang fblite unless 
     the Option Gosub statement is used.

Differences from QB
   * FreeBASIC does not generate a run-time error if expression is 
     negative or greater than 255.

See also
   * Select Case
   * On...Goto
   * GoSub
   * Return
   * Option Gosub
   * Labels



----------------------------------------------------------- KeyPgOngoto ----
On...Goto

Jumps to a label based on an expression.

Syntax
   On expression Goto label1[, ...]

Description
   Branches to different labels depending on the value of expression. An 
   expression value of 1 will branch to the first label, a value of 2 to 
   the second, etc.  If the value of expression is zero (0) or greater than 
   the number of items in the list, execution continues on the next 
   statement following the On...Goto.

   It is recommended that the structured Select Case conditional statement 
   be used instead of On...Goto.

Example
   Dim choice As Integer

   Input "Enter a number: ", choice

   On choice Goto labela, labelb, labelc

   labela:
   Print "choice a"
   End

   labelb:
   Print "choice b"
   End

   labelc:
   Print "choice c"
   End

Differences from QB
   * FreeBASIC does not generate a run-time error if expression is 
     negative or greater than 255.

See also
   * Select Case
   * On...Gosub
   * Goto
   * Labels



---------------------------------------------------------- KeyPgInclude ----
#include

Preprocessor statement to include contents of another source file

Syntax
   #include [once] "file"

Description
   #include inserts source code from another file at the point where the 
   #include directive appears.  This has the effect of compiling the source 
   code from the include file as though it were part of the source file 
   that includes it.  Once the compiler has reached the end of the include 
   file, the original source file continues to be compiled.

   This is useful to remove code from a file and separate it into more 
   files. It is useful to have a single file with declarations in a program 
   formed by several modules. You may include files within an include file, 
   although avoid including the original file into itself, this will not 
   produce valid results. Typically, include files will have an extension 
   of .bi and are mainly used for declaring subs/functions/variables of a 
   library, but any valid source code may be present in an include file.

   The Once specifier tells the compiler to include the file only once even 
   if it is included several times by the source code.

   $Include is an alternative form of include, existing only for 
   compatibility with QuickBASIC. It is recommended to use #include 
   instead.

   The compiler will automatically convert path separator characters ( '/' 
   and '\' ) as needed to properly load the file.  The filename name may be 
   an absolute or relative path.  

   For relative paths, or where no path is given at all, the include file 
   is search for in the following order:
   * Relative from the directory of the source file
   * Relative from the current working directory
   * Relative from addition directories specified with the -i command line 
     option
   * The include folder of the FreeBASIC installation (FreeBASIC\inc, 
     where FreeBASIC is the folder where the fbc executable is located)

Example
   ' header.bi file
   Type FooType
      Bar As Byte
      Barbeque As Byte 
   End Type

   ' main.bas file
   #include "header.bi"

   Dim Foo As FooType

   Foo.Bar = 1
   Foo.Barbeque = 2

Differences from QB
   * New to FreeBASIC

See also
   * #define
   * #inclib
   * Compiler Option: -i
   * Compiler Option: -include



------------------------------------------------------------- KeyPgOpen ----
Open

Opens a disk file for reading or writing using file operations

Syntax
   Open filename For Input [encoding_type] [lock_type] As [#]filenumber
   Open filename For Output [encoding_type] [lock_type] As [#]filenumber
   Open filename For Append [encoding_type] [lock_type] As [#]filenumber

   Open filename For Binary [access_type] [lock_type] As [#]filenumber
   Open filename For Random [access_type] [lock_type] As [#]filenumber [Len 
   = record_length]

Usage
   result = Open( filename[,] For {Input|Output|Append}[,] As filenumber )
      or
   result = Open( filename[,] For Binary[,] Access {Read|Write}[,] As 
   filenumber )
      or
   result = Open( filename[,] For Random[,] Access {Read|Write}[,] As 
   filenumber [[,] Len =  record_length] )
      or
   Open filename For {Input|Output|Append} As filenumber
      or
   Open filename For Binary Access {Read|Write} As filenumber
      or
   Open filename For Random Access {Read|Write} As filenumber [Len =  
   record_length]

Parameters
   filename
      A string value of the name of the disk file to open. Relative file 
      paths are relative to the current directory (see CurDir).
   encoding_type
      The encoding to be used when reading or writing text, can be one of:
         * Encoding "ascii" (ASCII encoding is used, default)
         * Encoding "utf8" (8-bit Unicode encoding is used)
         * Encoding "utf16" (16-bit Unicode encoding is used)
         * Encoding "utf32" (32-bit Unicode encoding  is used)
   access_type
      The type of access requested by the calling process.
         * Access [Read] [Write] (both read and write access can be used, 
           which is the default)
   lock_type
      Imposes restrictions on disk file access from other processes 
      (threads or programs), can be either:
         * Shared (the file can be freely accessed by other processes)
         * Lock [Read] [Write] (both read and write access can be denied 
           to other processes)
   filenumber
      An available file number to bind to the disk file, which can be found 
      with FreeFile.
   record_length
      The size, in bytes, of each record read from or written to the disk 
      file. The default is 128.

Return Value
   In the first usage, Open() returns a 32 bit Long value: zero (0) on 
   success and a non-zero error code otherwise.

Description
   Opens a disk file for reading and/or writing. The file number file_num 
   is bound to the file on disk, for use in subsequent file operations, 
   such as Input # and Lock. The next available file number can be 
   retrieved with FreeFile.

   The Input, Output and Append file modes open disk files for sequential 
   text I/O, useful for reading or writing plain text files:
      * When the Input mode is specified, only reading file operations can 
        be used, like Line Input # and Get #. If the disk file does not 
        exist a runtime error will be thrown.
      * The Append mode specifies that only writing operations can be 
        used, like Print # and Put #.  Writing operations will take place 
        at the end of the disk file if it exists, preserving the existing 
        data.
      * The Output mode is like the Append mode, except that if the file 
        exists then its contents are deleted and its length reset to zero 
        before writing.

   The Input, Output and Append file modes also allow selection of a 
   character encoding to be used when reading from or writing text to the 
   disk file. ASCII or a Unicode encoding may be specified (see the 
   description of the encoding_type parameter above).

   The Binary and Random file modes open disk files for random-access 
   reading or writing of arbitrary sized binary data:
      * The Binary file mode allows reading and writing of simple data 
        type values, like Byte or LongInt, using binary read or write 
        operations, like Get #. LOC and Seek are among the procedures used 
        for reading and writing to arbitrary locations in the disk file.
      * The Random file mode is similar to Binary, except that file I/O 
        operations always use a constant data size when reading or writing.

   By default, the Binary and Random file modes allow both reading and 
   writing operations on the opened disk file, but this can be changed by 
   specifying an access type (see the description for the access_type 
   parameter above). When opening an existing file in Binary or Random file 
   mode, and with the only Write access type specified, all data in the 
   file are previously deleted at opening, before any other operation.

   For any file mode, access to the opened disk file can be restricted or 
   granted to other threads or programs by specifying a lock type (see the 
   description for the lock_type parameter above). If no lock type is 
   specified, other threads of the current program can freely open the disk 
   file (Shared), while other programs cannot (Lock Read Write). Lock and 
   Unlock can be used to temporarily restrict access to parts of a file.

   The error code returned by Open  can be checked using Err in the next 
   line. The function version of  Open returns directly the error code as a 
   32 bit Long.

Example
   ' Create a string and fill it.
   Dim buffer As String, f As Integer
   buffer = "Hello World within a file."

   ' Find the first free file number.
   f = FreeFile

   ' Open the file "file.ext" for binary usage, using the file number "f".
   Open "file.ext" For Binary As #f
   If Err>0 Then Print "Error opening the file":End

   ' Place our string inside the file, using number "f".
   Put #f, , buffer

   ' Close all open files.  
   Close

   ' End the program. (Check the file "file.ext" upon running to see the output.)
   End

   'OPEN A COM PORT
   Open Com "COM1:9600,N,8,1" As #1
   If Err>0 Then Print "The port could not be opened."

   'COM1, 9600 BAUD, NO PARITY BIT, EIGHT DATA BITS, ONE STOP BIT

   'function version of OPEN
   If Open("file.ext" For Binary Access Read As #1) = 0 Then

      Print "Successfully opened file"

      '' ...

      Close #1

   Else

      Print "Error opening file"

   End If

Platform Differences
   * Linux requires the filename case matches the real name of the file. 
     Windows and DOS are case insensitive.
   * Path separators in Linux are forward slashes /. Windows uses backward 
     slashes \ but it allows for forward slashes /.  DOS uses backward 
     slashes \.
   * On Windows, a file number used in a dynamic link library is not the 
     same as an identical file number used in the main program.  File 
     numbers can not be passed or returned and then used between a DLL and 
     an executable.
   * If you try to open a directory on Linux, the Open command will 
     succeed.

Differences from QB
   * Using MS-DOS device names to open streams or hardware devices ("LPT:"
     , "SCR:", etc.) is supported only in the -lang qb dialect; for other 
     modes FreeBASIC's new composite keywords must be used: see Open Com,  
     Open Cons,  Open Err,  Open Pipe,  Open Lpt,  Open Scrn.
   * Open can be called as a function that returns an error code.

Dialect Differences
   * The -lang qb dialect supports the old GW-BASIC-style syntax OPEN 
     mode_string, #filenumber, filename [length] with mode_string being "I" 
     for input, "O" for output, "A" for append, "R" for random, "B" for 
     binary. 

See also
   * Err (and a list of error codes)
   * Close
   * FreeFile
   * Open Cons, Open Err, Open Pipe, Open Lpt, Open Com, Open Scrn



---------------------------------------------------------- KeyPgOpenCom ----
Open Com

Opens a serial port for input and output

Syntax
   Declare Function Open Com ( byref options As String, As filenumber As 
   Long ) As Long

Usage
   result = Open Com( options[,] As[#] filenumber )

Parameters
   options
      A String containing options used in controlling the port.
   filenumber
      The file number to bind to the port.

Return Value
   Open Com() returns a 32 bit Long: a zero (0) on success and a non-zero 
   error code otherwise.

Description
   This command opens a serial port of the PC, allowing to send and receive 
   data by using the normal file commands as Print  #, Input #, Get #, ...

   The main parameter is a String that describes, at the very least, which 
   communications port to open. It has the format:

      "Comn: [ baudrate ][ , [ parity ][ , [ data_bits ][ , [ stop_bits ][ 
      , [ extended_options ]]]]]"

   where,
   n
      Com port to open. "1", "2", "3", "4", etc.  Some platforms will 
      support more serial ports depending on how the operating system is 
      configured.  Where n is not given, "COM:" will map to "COM1:", except 
      on Linux where "COM:" maps to "/dev/modem"
   baudrate
      "300" (default), "1200", ..., etc.
   parity
      "N" (none), "E" (even, default), "O" (odd), "S" (space), "M" (mark), 
      "PE" (QB-quirk: checked, even parity)
   data_bits
      "5", "6", "7" (default) or "8".
   stop_bits
      "1", "1.5" or "2". (default value depends on baud rate and data bits, 
      see table below)

            +-----------------------------------+---------------------------+
            |Condition                          |Default number of stop bits|
            |baud rate <= 110 and data bits = 5 |1.5                        |
            |baud rate <= 110 and data bits >= 6|2                          |
            |baud rate > 110                    |1                          |
            +-----------------------------------+---------------------------+

   extended_options
      Miscellaneous options. (See table below)

            +------+-------------------------------------------------------------------------------+
            |Option|Action                                                                         |
            |'CSn' |Set the CTS duration (in ms) (n>=0), 0 = turn off, default = 1000              |
            |'DSn' |Set the DSR duration (in ms) (n>=0), 0 = turn off, default = 1000              |
            |'CDn' |Set the Carrier Detect duration (in ms) (n>=0), 0 = turn off                   |
            |'OPn' |Set the 'Open Timeout' (in ms) (n>=0), 0 = turn off                            |
            |'TBn' |Set the 'Transmit Buffer' size (n>=0), 0 = default, depends on platform        |
            |'RBn' |Set the 'Receive Buffer' size (n>=0), 0 = default, depends on platform         |
            |'RS'  |Suppress RTS detection                                                         |
            |'LF'  |Communicate in ASCII mode (add LF to every CR) - Win32 doesn't support this one|
            |'ASC' |same as 'LF'                                                                   |
            |'BIN' |The opposite of LF and it'll always work                                       |
            |'PE'  |Enable 'Parity' check                                                          |
            |'DT'  |Keep DTR enabled after CLOSE                                                   |
            |'FE'  |Discard invalid character on error                                             |
            |'ME'  |Ignore all errors                                                              |
            |'IRn' |IRQ number for COM (only supported (?) on DOS)                                 |
            +------+-------------------------------------------------------------------------------+

   All items except for the COM port are optional. The order of baudrate, 
   parity, data_bits, stop_bits is fixed. Any skipped fixed item ( baudrate
   , etc...) must be empty.

   The error code returned by Open Com can be checked using Err in the next 
   line. The function version of  Open Com returns directly the error code 
   as a 32 bit Long.

Example
   Open Com "COM1:9600,N,,2" As 1

   Opens COM1 with 9600 baud, no parity, 7 data bits and 2 stop bits.

   Open Com "COM1:115200" As 1

   Opens COM1 with 115200 baud, "even" parity, 7 data bits and 1 stop bits. 
   

Platform Differences
   * On the Windows platform "COM:" maps to "COM1:"
   * On the Linux platform
      "COM:" maps to "/dev/modem"
      "COM1:" maps to "/dev/ttyS0"
      "COM2:" maps to "/dev/ttyS1", etc 
      "/dev/xyz:" maps to "/dev/xyz", etc
   * The DOS serial driver is experimental and can access COM ports 1 to 4 
     
      It uses the following base io and IRQ's as default: 
      COM1 - &h3f8 - IRQ4 
      COM2 - &h2f8 - IRQ3 
      COM3 - &h3e8 - IRQ4 
      COM4 - &h2e8 - IRQ3 
      An alternate IRQ can be specified using the the "IRn" protocol option 
      where n is 3 through 7.
      Currently not supported: IRQ's on the slave PIC, alternate base I/O 
      addresses, Timeouts and most errors as detected in QB, hardware flow 
      control, FIFO's.
      "COM:" maps to "COM1:"
Dialect Differences
   * In the -lang qb dialect the old syntax OPEN "COMx:... is supported. 

Differences from QB
   * In QB the syntax was OPEN  "COMx:[baudrate] [,parity, [data_bits, 
     [stop_bits, [extended_options]]]]"  FOR INPUT|OUTPUT|RANDOM AS [#] n
   * In QB, only "COM1:" and "COM2:" are supported.  In FreeBASIC, any 
     correctly configured serial port may be used.

See also
   * Open



--------------------------------------------------------- KeyPgOpenCons ----
Open Cons

Opens the console's standard input (stdin) or output (stdout) streams for 
use in file operations.

Syntax
   Open Cons As [#]filenumber
   Open Cons For Input As [#]filenumber
   Open Cons For Output As [#]filenumber

Usage
   result = Open Cons( [For {Input|Output}[,]] As filenumber )
      (or using the QB-like syntax,)
   Open Cons [For {Input|Output}] As filenumber

Parameters
   filenumber
      An available file number to bind to the stdin or stdout stream, which 
      can be found with FreeFile.

Return Value
   In the first usage, Open Cons() returns a 32 bit Long: a zero (0) on 
   success and a non-zero error code otherwise.

Description
   Open Cons opens the console's stdin or stdout streams for reading or 
   writing. A file number is bound to the stream, which is used in 
   subsequent file operations, such as Input #. An available file number 
   can be retrieved with FreeFile.

   The Input file mode opens the stdin stream for reading file operations, 
   such as Line Input #, while the Output file mode opens the stdout stream 
   for writing file operations, such as Print #. The Output file mode is 
   the default if not specified.

   The stdin and stdout streams are the ones used when the calling process' 
   input or output is redirected (piped) by OS commands, or when it is 
   opened with Open Pipe.

   To open both the stdin and stdout streams for file operations, a process 
   must use multiple file numbers.

   The error code returned by Open Cons can be checked using Err in the 
   next line. The function version of  Open Cons returns directly the error 
   code as a 32 bit Long.

   Warning: Presently, Open Cons does not work as described above. Without 
   any file mode specifier, a runtime error 1 (illegal function call) 
   occurs. With the Input file mode specifier, the only input mode is well 
   supported. But with the Output file mode specifier, input and output 
   modes are simultaneously supported.

Runtime errors:
   Open Cons throws one of the following runtime errors:

   (1) Illegal function call
      * filenumber was not free at the time. use FreeFile to ensure that 
        filenumber is free.

Example
   Dim a As String

   Open Cons For Input As #1
   Open Cons For Output As #2

   Print #2,"Please write something and press ENTER"
   Line Input #1,a
   Print #2, "You wrote : ";a

   Close
   Sleep

Differences from QB
   * In QB the syntax was OPEN "CON:" FOR INPUT|OUTPUT AS [#] filenumber

See also
   * Open
   * Open Scrn
   * Open Err
   * FreeFile



---------------------------------------------------------- KeyPgOpenErr ----
Open Err

Opens both the standard input (stdin) and standard error (stderr) streams 
for file operations.

Syntax
   Open Err [for mode] As [#]filenumber As Long

Usage
   Open Err [for mode] as [#]filenumber
      or
   result = Open Err( [for mode[,]] as [#]filenumber )

Parameters
   mode
      Ignored.
   filenumber
      An unused file number.

Return Value
   A 32 bit Long: a zero is returned if Open Err() completed successfully, 
   otherwise a non-zero value is returned to indicate failure.

Description
   This command opens stdin to read from and stderr to write to the console 
   allowing read and write operations with normal file commands.

   stderr is an output stream different from stdout allowing error messages 
   to be redirected separately from the main console output.

   The normal console commands, such as Color and Locate, do not work in 
   this mode, because they do not accept a file number.

   The [For Input|Output] mode is allowed for compatibility, but is 
   ignored.

   The error code returned by Open Err can be checked using Err in the next 
   line. The function version of  Open Err returns directly the error code 
   as a 32 bit Long.

Runtime errors:
   Open Err throws one of the following runtime errors:

   (1) Illegal function call
      * Filenumber was not free at the time. use FreeFile to ensure that 
        filenumber is free.

Example
   Dim a As String
   Open Err For Input  As #1
   Print #1,"Please write something and press ENTER"
   Line Input #1, a 
   Print #1, "You wrote"; a
   Close
   Sleep

Differences from QB
   * New to FreeBASIC

See also
   * Open



---------------------------------------------------------- KeyPgOpenLpt ----
Open Lpt

Open a printer device

Syntax
   Open Lpt ["[LPT[x]:][Printer_Name][,TITLE=Doc_Title][,EMU=TTY]"] [For 
   Input|Output] As #filenumber

Usage
   Open Lpt "LPT..." As [#]filenumber
      or
   result = Open Lpt( "LPT..."[,] As [#]filenumber )

Parameters
   x
      Specifies a port number.  If omitted, output is sent to the system 
      print spooler.
   Printer_Name
      Name of printer to open.  This parameter is ignored on DOS.
   TITLE=Doc_Title
      Title of the print job as seen by the printer spooler.  This 
      parameter is ignored on DOS.
   EMU=TTY
      Emulation of TTY output on a windows GDI printer, using driver text 
      imaging.  This parameter is ignored on DOS and Linux.
   For Input|Output
      clause is allowed for compatibility, but it is ignored.
   filenumber
      An unused file number to assign to the device.

Return Value
   A 32 bit Long: 0 is returned if Open Lpt() completed successfully, 
   otherwise a non-zero value is returned to indicate failure.

Description
   Open Lpt opens a connection to a printer device.  The connection is 
   treated like a file, so data may be written to the printer using Print 
   and Put # commands.  

   Any printer attached to the system may be opened with Open Lpt

   Open Lpt "LPT:" ... will try to open the default printer on Windows and 
   Linux, and "LPT1:" on DOS.

   LPrint will automatically try to open the default printer on Windows and 
   Linux, and "LPT1:" on DOS.

   The error code returned by Open Lpt can be checked using Err in the next 
   line. The function version of  Open Lpt returns directly the error code 
   as a 32 bit Long.

Platform specific notes:

   Windows
      The argument EMU=TTY assumes printable ASCII or Unicode text, and 
      applies printer driver text imaging to the input.  EMU=TTY also 
      allows the usage of CR, LF, BS, TAB, FF, etc., for virtual print-head 
      movement...even when the printer is a GDI printer and therefore 
      doesn't itself understand these special characters.  If ",EMU=TTY" is 
      omitted, the data must be sent in the printer's language (ESC/P, 
      HPGL, PostScript, etc...).  Other useful emulation modes aren't 
      supported yet.

   Linux
      A printer spooler available through lp must be installed to access 
      printers by name or a default printer.  Spooler access was tested 
      only with CUPS, but other spoolers may work that are invoked through 
      lp.  Port are zero-based on Linux. "LPT1:" corresponds with 
      "/dev/lp0".

      The data must be sent in the printer's language (ESC/P, HPGL, 
      PostScript, etc...). Emulation modes aren't supported yet.

   DOS
      FreeBASIC does not support print spoolers on DOS.  Printers must be 
      accessible through "LPTx:".

      The data must be sent in the printer's language (ESC/P, HPGL, 
      PostScript, etc...).  Emulation modes aren't supported yet.

Example
   ' Send some text to the Windows printer on LPT1:, using driver text imaging.
   Open Lpt "LPT1:EMU=TTY" For Output  As #1
   Print #1, "Testing!" 
   Close

   ' Sends contents of text file test.txt to Windows printer named "ReceiptPrinter"
   Dim RptInput As String
   Dim PrintFileNum As Integer, RptFileFileNum As Integer

   RptFileFileNum = FreeFile
   Open "test.txt" For Input As #RptFileFileNum

   PrintFileNum = FreeFile
   Open Lpt "LPT:ReceiptPrinter,TITLE=ReceiptWinTitle,EMU=TTY" As _
      #PrintFilenum

   While (EOF(RptFileFileNum) = 0)
         Line Input #RptFileFileNum, RptInput
         Print #PrintFileNum, RptInput
   Wend

   Close #PrintFileNum  ' Interestingly, does not require CHR(12).  But if pagination is desired, CHR(12) is the way.

   Close #RptFileFileNum

   Print "Press any key to end program..."
   GetKey

   End

   'This simple program will print a PostScript file to a PostScript compatible printer.
   Dim As UByte FFI, PPO
   Dim As String temp

   FFI = FreeFile()
   Open "sample.ps" For Input Access Read As #FFI
   PPO = FreeFile()
   Open Lpt "LPT1:" For Output As #PPO
   While (EOF(FFI) = 0)
   Line Input #FFI, temp
   Print #PPO, temp
   Wend

   Close #FFI
   Close #PPO

   Print "Printing Completed!"

Dialect Differences
   * In the -lang qb dialect the old syntax is supported OPEN "LPT:..." . 
     This syntax used in the other dialects will open a regular file.

See also
   * Open
   * LPrint



--------------------------------------------------------- KeyPgOpenPipe ----
Open Pipe

Opens an external process' standard input (stdin) or output (stdout) stream 
for file operations.

Syntax
   Open Pipe shell_command For Input As [#]filenumber
   Open Pipe shell_command For Output As [#]filenumber
   Open Pipe shell_command For Binary access_type [#]filenumber

Usage
   result = Open Pipe( command[,] For {Input|Output}[,] As filenumber )
      or,
   result = Open Pipe( command[,] For Binary[,] access_type[,] As 
   filenumber )
      (or in the QB-like syntax,)
   Open Pipe filename For {Input|Output} As filenumber
      (or,)
   Open Pipe filename For Binary access_type As filenumber

Parameters
   shell_command
      The external process to execute in the operating system command 
      shell. Relative file paths are relative to the current directory (see 
      CurDir).  When opening a pipe for a process that requires double 
      quotes in either its executable path, or its arguments, the entire 
      pipe string should be nested inside of double quotes.
   access_type
      The type of read or write access requested by the calling process.
         * Access {Read|Write} (either the stdin or stdout stream of the 
           external process can be opened)
   filenumber
      An available file number to bind to the external process' stdin or 
      stdout stream.

Return Value
   In the first usage, Open Pipe() returns a 32 bit Long: a zero (0) on 
   success and a non-zero error code otherwise.

Description
   Open Pipe executes another process in the command shell and opens either 
   its stdin or stdout streams for reading or writing. A file number is 
   bound to the stream, which is used in subsequent file operations, such 
   as Input #. An available filenumber can be retrieved with FreeFile. If 
   the external process does not exist, a runtime error is thrown.

   The Input and Output file modes open the external process' stdin and 
   stdout streams, respectively, for sequential text I/O, useful for 
   reading or writing plain text. Characters, words or whole lines can then 
   be read or written using text-mode file operations, such as Line Input # 
   and Print #.

   The Binary file mode opens the external process' stdin or stdout streams 
   - depending on the access type specified (see description of the 
   access_type parameter above) - for random-access reading or writing of 
   arbitrarily sized and interpreted raw data. Simple data type values, 
   like Byte and LongInt, and whole chunks of memory can be read from or 
   written to the streams with binary-mode file operations like Get # and 
   Put #.
   Bidirectional pipes are not supported by FB and must be implemented 
   using the OS' API functions.

   The error code returned by Open Pipe can be checked using Err in the 
   next line. The function version of  Open Pipe returns directly the error 
   code as a 32 bit Long.

Runtime errors:
   Open Pipe throws one of the following runtime errors:

   (1) Illegal function call
      * filenumber was not free at the time. use FreeFile to ensure that 
        filenumber is free.

Example
   '' This example uses Open Pipe to run a shell command and retrieve its output. 
   #ifdef __FB_UNIX__
   Const TEST_COMMAND = "ls *"
   #else
   Const TEST_COMMAND = "dir *.*"
   #endif

   Open Pipe TEST_COMMAND For Input As #1

   Dim As String ln
   Do Until EOF(1)
      Line Input #1, ln
      Print ln
   Loop

   Close #1

Platform Differences
   * The Binary file mode is not supported on all platforms; Open Pipe 
     will throw an error if it is unable to open the external process' 
     stdin or stdout streams in binary mode.

Differences from QB
   * New to FreeBASIC

See also
   * Shell
   * Open
   * Open Cons
   * Open Err
   * FreeFile



--------------------------------------------------------- KeyPgOpenScrn ----
Open Scrn

Opens the console directly for input and output as a file

Syntax
   Open Scrn [for mode] As [#]filenumber As Long

Usage
   Open Scrn [for mode] as [#]filenumber
      or
   result = Open Scrn( [for mode[,]] as [#]filenumber )

Parameters
   mode
      Either Input or Output.  If omitted, Output is assumed.
   filenumber
      An unused file number.

Return Value
   A 32 bit Long: a zero (0) is returned if Open Scrn() completed 
   successfully, otherwise a non-zero value is returned to indicate 
   failure.

Description
   This command opens the console for both input and output as a file, 
   allowing to read/write from/to it with normal file commands.

   This command may use direct access to the console for speed in some 
   implementations, so  it should not be used when the input / output is 
   required to be redirected or piped with OS commands.    

   The normal console commands, such as Color and Locate, do not work in 
   this mode, because they do not accept a file number.

   The [For Input|Output] clause is allowed for compatibility, but is 
   ignored.

   filenumber is an unused file number.

   An unused file number can be found using FreeFile.

   The error code returned by Open Scrn can be checked using Err in the 
   next line. The function version of  Open Scrn returns directly the error 
   code as a 32 bit Long.

Runtime errors:
   Open Scrn throws one of the following runtime errors:

   (1) Illegal function call
      * filenumber was not free at the time. use FreeFile to ensure that 
        filenumber is free.	

Example
   Dim a As String
   Open Scrn For Input  As #1
   Print #1,"Please write something and press ENTER"
   Line Input #1,a
   Print #1, "You wrote";a
   Close
   Sleep

Differences from QB
   * QB used OPEN "SCRN:" ...

See also
   * Open
   * Open Cons



--------------------------------------------------------- KeyPgOperator ----
Operator

Declares or defines an overloaded operator.

Syntax
   { Type | Class | Union } typename
      Declare Operator Cast () [ ByRef ] As datatype
      Declare Operator @ () [ ByRef ] As datatype Ptr
      Declare Operator assignment_op ( [ ByRef | ByVal ] rhs As datatype )
      Declare Operator [] ( index As datatype ) [ ByRef ] As datatype
      Declare Operator New ( size As UInteger ) As Any Ptr
      Declare Operator New[] ( size As UInteger ) As Any Ptr
      Declare Operator Delete ( buf  As Any Ptr )
      Declare Operator Delete[] ( buf  As Any Ptr )
   End { Type | Class | Union }

   { Type | Class | Union } typename
      Declare Operator For ()
      Declare Operator For ( [ ByRef | ByVal ] stp As typename )
      Declare Operator Step ()
      Declare Operator Step ( [ ByRef | ByVal ] stp As typename )
      Declare Operator Next ( [ ByRef | ByVal ] cond As typename ) As 
      Integer
      Declare Operator Next ( [ ByRef | ByVal ] cond As typename, [ ByRef | 
      ByVal ] stp As typename ) As Integer
   End { Type | Class | Union }

   Declare Operator unary_op ( [ ByRef | ByVal ] rhs As datatype ) As 
   datatype
   Declare Operator binary_op ( [ ByRef | ByVal ] lhs As datatype, [ ByRef 
   | ByVal ] rhs As datatype ) As datatype

   Operator typename.Cast () [ ByRef ] As datatype [ Export ]
   Operator typename.@ () [ ByRef ] As datatype Ptr [ Export ]
   Operator typename.assignment_op ( [ ByRef | ByVal ] rhs As datatype ) [ 
   Export ]
   Operator [] ( index As datatype ) [ ByRef ] As datatype [ Export ]
   Operator unary_op ( [ ByRef | ByVal ] rhs As datatype ) As datatype [ 
   Export ]
   Operator binary_op ( [ ByRef | ByVal ] lhs As datatype, [ ByRef | ByVal 
   ] rhs As datatype ) As datatype [ Export ]
   Operator typename.New ( size as uinteger ) As Any Ptr [ Export ]
   Operator typename.New[] ( size As UInteger ) As Any Ptr [ Export ]
   Operator typename.Delete ( buf  As Any Ptr ) [ Export ]
   Operator typename.Delete[] ( buf  As Any Ptr ) [ Export ]

Parameters
   typename 
      Name of the Type, Class, Union, or Enum.
   assignment_op 
      let += -= *= &= /= \= mod= shl= shr= and= or= xor= imp= eqv= ^=
   unary_op
      - not * -> abs sgn fix frac int exp log sin asin cos acos tan atn len 
      sqr
   binary_op
      + - * & / \ mod shl shr and or xor imp eqv ^ = <> < > <= >=

Description
   The built in operators like =, +, and cast have predefined behaviors 
   when used in expressions.  These operators can be overloaded to do 
   something other than predefined operations when at least one of the 
   arguments to the operator is a Type, Class, Enum, or Union data type.

   Operators are just functions.  The operator '+' has functionality like 
   Function Plus( A as DataType, B as DataType ) as DataType.  See 
   Operator Overloading for more information.  Operators can be overloaded 
   to accept different data types as parameters.  The Cast Operator is the 
   only operator (or function) that can be declared multiple times when 
   only the return type differs, but not the same as the Type, Class, or 
   Union it is declared in (for not explicit usage, the compiler may decide 
   which cast overload to call based on how the object is used).

   Non-static operator members are declared inside the Type, Class, or Union
   .  Global operators are declared outside.  All operator definitions 
   (procedure bodies) must appear outside.

   Let, Cast, and other assignment operators must be declared inside the 
   Type, Class, or Union.  As all non-static member procedures, they have 
   passed a hidden This parameter.

   Unary operators must be declared outside the Type, Class, or Union and 
   have a return data type explicitly declared.  Unary operators can be 
   overloaded to return any valid data type, except for 
   Operator -> (Pointer To Member Access) which must return a Type, Class, 
   or Union data type.

   Binary operators must be declared outside the Type, Class, or Union and 
   have a return data type explicitly declared.  Binary operators can be 
   overloaded with valid data types, including for relational operators, 
   which can also return any valid data type.

   Let refers to the assignment operator, as in LET a=b. The Let keyword is 
   omitted in common practice, and is not allowed in the -lang fb dialect.  
   However, Let() can be used to assign the fields of a UDT to multiple 
   variables.

   See For, Step, and Next for more information on overloading the For..Next
   statement for use with user defined types.

   Member operators New, New[], Delete, and Delete[] are always static, 
   even if not explicitly declared (Static keyword is unnecessary but 
   allowed).

Example
   '' operator1.bas

   Type Vector2D
     As Single x, y

     '' Return a string containing the vector data.
     Declare Operator Cast() As String

     '' Multiply the vector by a scalar.
     Declare Operator *= ( ByVal rhs As Single )
   End Type

   '' Allow two vectors to be able to be added together.
   Declare Operator + ( ByRef lhs As Vector2D, ByRef rhs As Vector2D ) As Vector2D

   '' Return the modulus (single) of the vector using the overloaded operator abs().
   Declare Operator Abs (  ByRef rhs As Vector2D ) As Single

   Operator Vector2D.cast () As String
     Return "(" + Str(x) + ", " + Str(y) + ")"
   End Operator

   Operator Vector2D.*= ( ByVal rhs As Single )
     This.x *= rhs
     This.y *= rhs
   End Operator

   Operator + ( ByRef lhs As Vector2D, ByRef rhs As Vector2D ) As Vector2D
     Return Type<Vector2D>( lhs.x + rhs.x, lhs.y + rhs.y )
   End Operator

   Operator Abs ( ByRef rhs As Vector2D ) As Single
     Return Sqr( rhs.x * rhs.x + rhs.y * rhs.y )
   End Operator

   Dim a As Vector2D = Type<Vector2D>( 1.2, 3.4 )
   Dim b As Vector2D = Type<Vector2D>( 8.9, 6.7 )
   Dim c As Vector2D = Type<Vector2D>( 4.3, 5.6 )

   Print "a = "; a, "abs(a) ="; Abs( a )
   Print "b = "; b, "abs(b) ="; Abs( b )
   Print "a + b = "; a + b, "abs(a+b) ="; Abs( a + b )
   Print "c = "; c, "abs(c) ="; Abs( c )
   Print "'c *= 3'"
   c *= 3
   Print "c = "; c, "abs(c) ="; Abs( c )

   Small use case of the operator "[]": simplest smart pointers for byte 
   buffers.
   '' operator3.bas

   '' A smart pointer is an object which behaves like a pointer but does more than a pointer:
   '' - This object is flexible as a pointer and has the advantage of being an object,
   ''   like constructor and destructor called automatically.
   '' - Therefore, the destructor of the smart pointer will be automatically called
   ''   when this object goes out of scope, and it will delete the user pointer.

   '' Example of simplest smart pointers for byte buffers:
   '' - Constructor and destructor allow to allocate, deallocate, and resize the byte buffer.
   '' - Pointer index operator allows to access buffer elements.
   '' - Copy-constructor and let-operator are just declared in private section,
   ''   in order to disallow copy construction and any assignment.

   Type smartByteBuffer
     Public:
      Declare Constructor (ByVal size As UInteger = 0)
      Declare Operator [] (ByVal index As UInteger) ByRef As Byte
      Declare Destructor ()
     Private:
      Declare Constructor (ByRef rhs As smartByteBuffer)
      Declare Operator Let (ByRef rhs As smartByteBuffer)
      Dim As Byte Ptr psbb
   End Type

   Constructor smartByteBuffer (ByVal size As UInteger = 0)
     This.destructor()
     If size > 0 Then
      This.psbb = New Byte[size]
      Print "Byte buffer allocated"
     End If
   End Constructor

   Operator smartByteBuffer.[] (ByVal index As UInteger) ByRef As Byte
     Return This.psbb[index]
   End Operator

   Destructor smartByteBuffer ()
     If This.psbb > 0 Then
      Delete[] This.psbb
      This.psbb = 0
      Print "Byte buffer deallocated"
     End If
   End Destructor

   Scope
     Dim As smartByteBuffer sbb = smartByteBuffer(256)
     For I As Integer = 0 To 255
      sbb[I] = I - 128
     Next I
     Print
     For I As Integer = 0 To 255
      Print Using "#####"; sbb[I];
     Next I
     Print
   End Scope

Dialect Differences
   * Only available in the -lang fb dialect.

See also
   * Class
   * Union
   * Type
   * Coercion and Conversion



----------------------------------------------------------- KeyPgOption ----
Option()

Specifies additional attributes and/or characteristics of symbols.

Syntax
   Option( "literal-text" )

Parameters
   literal-text
      The literal text specifying the option. See description.

Description
   Option() allows the programmer to specify additional attributes or 
   characteristics.  Enclosing the string into quotes and parentheses is 
   required in the syntax.  Unrecognized options are ignored.

   Option can also be used as a statement to specify other compile time 
   options.  See Compiler Switches.

   Individual options are explained below.

SSE
   Option("SSE") indicates that a floating point value (Single or Double) 
   returned from a function is stored in the xmm0 register.  Option("Sse") 
   is ignored unless the source is compiled with the -fpu SSE command line 
   option.  This option may be used immediately after the return type in a 
   function declaration or function definition.  This option is an 
   optimization only and not required to compile programs using the -fpu SSE
   command line option.

   Declare Function ValueInXmm0 () As Double Option("sse")

FPU
   Option("FPU") indicates that a floating point value (Single or Double) 
   returned from a function is stored in the st(0) register.  This option 
   may be used immediately after the return type in a function declaration 
   or function definition.

   Declare Function ValueInStZero () As Double Option("fpu")

Differences from QB
   * New to FreeBASIC

See also
   * Compiler Option: -fpu
   * Compiler Switches



------------------------------------------------------- KeyPgOptionbase ----
Option Base

Specifies a default lower bound for array declarations

Syntax
   Option Base base_subscript

Parameters
   base_subscript
      an numeric literal value

Description
   Option Base is a statement that sets the default lower bound for any 
   following array declarations. This default remains in effect for the 
   rest of the module in which Option Base is used, and can be overridden 
   by declaring arrays with an explicit lower bound, or with another Option 
   Base statement.

   Note: initially, the default base is 0.

Example
   '' Compile with the "-lang qb" or "-lang fblite" compiler switches

   #lang "fblite"

   Dim foo(10) As Integer      ' declares an array with indices 0-10

   Option Base 5

   Dim bar(15) As Integer      ' declares an array with indices 5-15
   Dim baz(0 To 4) As Integer  ' declares an array with indices 0-4

Dialect Differences
   * Only available in the -lang fblite and -lang qb dialects.
   * In -lang fb, Option Base is not allowed, and the default lower bound 
     is always 0.

Differences from QB
   * QBASIC only supported values of 0 or 1 for base_subscript.
   * In QBASIC the word Base was a reserved keyword, and couldn't be used 
     as a variable name.
   * Arrays must always be explicitly created in FreeBASIC.  QBASIC would 
     implicitly create an array from base_subscript to 10 if one was used 
     in code without being predefined.

See also
   * Dim
   * ReDim
   * LBound



------------------------------------------------------ KeyPgOptionbyval ----
Option ByVal

Specifies parameters are to be passed by value by default in procedure 
declarations

Syntax
   Option ByVal

Description
   Option ByVal is a statement that sets the default passing convention for 
   procedure parameters to by value, as if declared with ByVal. This 
   default remains in effect for the rest of the module in which Option 
   ByVal is used, and can be overridden by specifying ByRef in parameter 
   lists.

Example
   '' compile with the "-lang fblite" compiler switch

   #lang "fblite"

   Sub TestDefaultByref( a As Integer )
     '' change the value
     a = a * 2
   End Sub

   Option ByVal

   Sub TestDefaultByval( a As Integer )
     a = a * 2
   End Sub

   Dim a As Integer = 1

   Print "a = "; a
   TestDefaultByref( a )
   Print "After TestDefaultByref : a = "; a
   Print

   Print "a = "; a
   TestDefaultByval( a )
   Print "After TestDefaultByval : a = "; a
   Print

Dialect Differences
   * Only available in the -lang fblite and -lang qb dialects.

Differences from QB
   * New to FreeBASIC

See also
   * __FB_OPTION_BYVAL__



---------------------------------------------------- KeyPgOptiondynamic ----
Option Dynamic

Specifies variable-length array declarations

Syntax
   Option Dynamic

Description
   Option Dynamic is a statement that specifies that any following array 
   declarations are variable-length, whether they are declared with 
   constant subscript ranges or not. This remains in effect for the rest of 
   the module in which Option Dynamic is used, and can be overridden with 
   Option Static.  It is equivalent to the '$Dynamic metacommand.

Example
   '' Compile with "-lang fblite" compiler switch

   #lang "fblite"

   Dim foo(99) As Integer      ' declares a fixed-length array

   Option Dynamic

   Dim bar(99) As Integer      ' declares a variable-length array
   ' ...
   ReDim bar(199)              ' resize the array

Dialect Differences
   * Only available in the -lang fblite and -lang qb dialects.

Differences from QB
   * New to FreeBASIC

See also
   * __FB_OPTION_DYNAMIC__
   * '$Dynamic
   * '$Static
   * Option Static
   * Dim
   * ReDim



----------------------------------------------------- KeyPgOptionescape ----
Option Escape

Specifies that string literals should be processed for C-like escape 
sequences by default

Syntax
   Option Escape

Description
   Option Escape is a statement that causes string literals to be processed 
   for C-like escape sequences by default. Normally, escape sequences have 
   no effect in string literals unless the string is prefixed with the  
   ! Operator (Escaped String Literal). This default remains in effect for 
   the rest of the module in which Option Escape is used, and can be 
   overridden by prefixing string literals with the 
   $ Operator (Non-Escaped String Literal).

   See Literals in the Programmer's Guide to learn more about escape 
   sequences.

Example
   '' Compile with the "-lang fblite" compiler switch

   #lang "fblite"

   Option Escape

   Print "Warning \a\t The path is:\r\n c:\\Freebasic\\Examples"
   Print $"This string doesn't have expanded escape sequences: \r\n\t"

   #include "crt.bi"

   Dim As Integer a = 2, b = 3
   printf("%d * %d = %d\r\n", a, b, a * b)

Dialect Differences
   * Only available in the -lang fblite and -lang qb dialects.

Differences from QB
   * New to FreeBASIC

See also
   * __FB_OPTION_ESCAPE__
   * Operator ! (Escaped String Literal)
   * Operator $ (Non-Escaped String Literal)
   * Literals



--------------------------------------------------- KeyPgOptionexplicit ----
Option Explicit

Forces variables, objects and arrays to be declared before they are used

Syntax
   Option Explicit

Description
   Option Explicit is a statement that forces any following variable, 
   object or array usage to be preceded by a declaration, with, for 
   example, Dim or Static. This rule remains in effect for the rest of the 
   module in which Option Explicit is used, and cannot be overridden.

Example
   '' Compile with the "-lang qb" or "-lang fblite" compiler switches

   #lang "fblite"

   Option Explicit

   Dim a As Integer            ' 'a' must be declared..
   a = 1                       ' ..or this statement will fail to compile.

   Dialect Differences
   * Only available in the -lang fblite and -lang qb dialects.

Differences from QB
   *New to FreeBASIC

See also
   * __FB_OPTION_EXPLICIT__



------------------------------------------------------ KeyPgOptiongosub ----
Option Gosub

Enables support for GoSub and On Gosub.

Syntax
   Option Gosub

Description
   Option Gosub enables support for GoSub and Return (from gosub).

   Because Return could mean return-from-gosub or return-from-procedure, 
   Option Gosub and Option Nogosub can be used to enable and disable GoSub 
   support.  When GoSub support is disabled, Return is then recognized as 
   return-from-procedure.

Example
   '' Compile with the "-lang fblite" compiler switch

   #lang "fblite"

   '' turn on gosub support
   Option GoSub

   GoSub there
   backagain:
      Print "backagain"
      End

   there:
      Print "there"
      Return

Dialect Differences
   * Only available in the -lang fblite and -lang qb dialects.

Differences from QB
   * New to FreeBASIC

See also
   * __FB_OPTION_GOSUB__
   * Option Nogosub
   * GoSub
   * Return



---------------------------------------------------- KeyPgOptionnogosub ----
Option Nogosub

Disables support for GoSub and On Gosub.

Syntax
   Option Nogosub

Description
   Option Nogosub disables support for GoSub and Return (from gosub).

   Because Return could mean return-from-gosub or return-from-procedure, 
   Option Gosub and Option Nogosub can be used to enable and disable GoSub 
   support.  When GoSub support is disabled, Return is then recognized as 
   return-from-procedure.

Example
   '' Compile with the "-lang qb" compiler switch

   '$lang: "qb"

   '' turn off gosub support
   Option nogosub

   Function foo() As Integer
      Return 1234
   End Function

   Print foo

Dialect Differences
   * Only available in the -lang fblite and -lang qb dialects.

Differences from QB
   * New to FreeBASIC

See also
   * __FB_OPTION_GOSUB__
   * Option Gosub
   * GoSub
   * Return



-------------------------------------------------- KeyPgOptionnokeyword ----
Option NoKeyword

"Undefines" a reserved keyword

Syntax
   Option NoKeyword keyword

Parameters
   keyword
      the keyword to undefine

Description
   Option NoKeyword is a statement that undefines a FreeBASIC reserved 
   keyword, meaning it can be used as an identifier for a variable, object, 
   procedure or any other symbol. The keyword is undefined for the rest of 
   the module in which Option NoKeyword is used.

Example
   '' Compile with the "-lang fblite" compiler switch

   #lang "fblite"

   Option NoKeyword Int        ' remove the keyword 'int' from the internal
                        ' symbol table

   Dim Int As Integer          ' declare a variable with the name 'int'

Dialect Differences
   * Only available in the -lang fblite and -lang qb dialects.

Differences from QB
   * New to FreeBASIC

See also
   * #undef



---------------------------------------------------- KeyPgOptionprivate ----
Option Private

Specifies internal linkage by default for procedure declarations

Syntax
   Option Private

Description
   Option Private is a statement that gives any following procedure 
   declarations internal linkage by default, as if declared with Private. 
   This default remains in effect for the rest of the module in which 
   Option Private is used, and can be overridden by declaring procedures 
   with Public.

Example
   '' Compile with the "-lang fblite" compiler switch

   #lang "fblite"

   Sub ProcWithExternalLinkage()
      ' ...
   End Sub

   Option Private

   Sub ProcWithInternalLinkage()
      ' ...
   End Sub

   Public Sub AnotherProcWithExternalLinkage()
      ' ...
   End Sub

Dialect Differences
   * Only available in the -lang fblite and -lang qb dialects.

Differences from QB
   * New to FreeBASIC

See also
   * __FB_OPTION_PRIVATE__
   * Private
   * Public



----------------------------------------------------- KeyPgOptionstatic ----
Option Static

Reverts to default array declaration behavior

Syntax
   Option Static

Description
   Option Static is a statement that overrides the behavior of 
   Option Dynamic, that is, arrays declared with constant subscript ranges 
   are fixed-length. This remains in effect for the rest of the module in 
   which Option Static is used, and can be overridden with Option Dynamic.  
   It is equivalent to the '$Static metacommand.

Example
   '' Compile with the "-lang fblite" compiler switch

   #lang "fblite"

   Option Dynamic

   Dim foo(100) As Integer         ' declares a variable-length array

   Option Static

   Dim bar(100) As Integer         ' declares a fixed-length array

Dialect Differences 
   * Only available in the -lang fblite and -lang qb dialects.

Differences from QB
   * New to FreeBASIC

See also
   * '$Dynamic
   * '$Static
   * Dim
   * Erase
   * ReDim
   * Option Dynamic
   * Static



------------------------------------------------------------- KeyPgOpOr ----
Operator Or (Inclusive Disjunction)

Returns the bitwise-or (inclusive disjunction) of two numeric values

Syntax
   Declare Operator Or ( ByRef lhs As T1, ByRef rhs As T2 ) As Ret

Usage
   result = lhs Or rhs

Parameters
   lhs
      The left-hand side expression.
   T1
      Any numeric or boolean type.
   rhs
      The right-hand side expression.
   T2
      Any numeric or boolean type.
   Ret
      A numeric or boolean type (varies with T1 and T2).

Return Value
   Returns the bitwise-disjunction of the two operands.

Description
   This operator returns the bitwise-disjunction of its operands, a logical 
   operation that results in a value with bits set depending on the bits of 
   the operands (for conversion of a boolean to an integer, false or true 
   boolean value becomes 0 or -1 integer value).

   The truth table below demonstrates all combinations of a 
   boolean-disjunction operation:

      +-------+-------+------+
      |Lhs Bit|Rhs Bit|Result|
      |0      |0      |0     |
      |1      |0      |1     |
      |0      |1      |1     |
      |1      |1      |1     |
      +-------+-------+------+

   No short-circuiting is performed - both expressions are always 
   evaluated.

   The return type depends on the types of values passed. Byte, UByte and 
   floating-point type values are first converted to Integer. If the left 
   and right-hand side types differ only in signedness, then the return 
   type is the same as the left-hand side type (T1), otherwise, the larger 
   of the two types is returned. Only if the left and right-hand side types 
   are both Boolean, the return type is also Boolean.

   This operator can be overloaded for user-defined types.

Example
   ' Using the OR operator on two numeric values
   Dim As UByte numeric_value1, numeric_value2
   numeric_value1 = 15 '00001111
   numeric_value2 = 30 '00011110

   'Result =  31  =     00011111       
   Print numeric_value1 Or numeric_value2
   Sleep

   ' Using the OR operator on two conditional expressions
   Dim As UByte numeric_value
   numeric_value = 10

   If numeric_value = 5 Or numeric_value = 10 Then Print "Numeric_Value equals 5 or 10"
   Sleep

   ' This will output "Numeric_Value equals 5 or 10" because
   ' while the first condition of the first IF statement is false, the second is true

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * None

See also
   * OrElse
   * Operator Truth Tables



------------------------------------------------------------ KeyPgOrGfx ----
Or

Parameter to the Put graphics statement which uses a bit-wise Or as the 
blitting method

Syntax
   Put [ target, ] [ STEP ] ( x,y ), source [ ,( x1,y1 )-( x2,y2 ) ], Or

Parameters
   Or
      Required.

Description
   The Or method combines each source pixel with the corresponding 
   destination pixel, using the bit-wise Or function.  The result of this 
   is output as the destination pixel.
   This method works in all graphics modes.  There is no mask color, 
   although color values of 0 (RGBA(0, 0, 0, 0) in full-color modes) will 
   have no effect, because of the behavior of Or.

   In full-color modes, each component (red, green, blue and alpha) is kept 
   in a discrete set of bits, so the operation can be made to only affect 
   some of the channels, by making sure the all the values of the other 
   channels are set to 0.

Example
   ''open a graphics window
   ScreenRes 320, 200, 16

   ''create 3 sprites containing red, green and blue circles
   Const As Integer r = 32
   Dim As Any Ptr cr, cg, cb
   cr = ImageCreate(r * 2 + 1, r * 2 + 1, RGBA(0, 0, 0, 0))
   cg = ImageCreate(r * 2 + 1, r * 2 + 1, RGBA(0, 0, 0, 0))
   cb = ImageCreate(r * 2 + 1, r * 2 + 1, RGBA(0, 0, 0, 0))
   Circle cr, (r, r), r, RGB(255, 0, 0), , , 1, f
   Circle cg, (r, r), r, RGB(0, 255, 0), , , 1, f
   Circle cb, (r, r), r, RGB(0, 0, 255), , , 1, f

   ''put the sprite at three different multipier
   ''levels, overlapping each other in the middle
   Put (146 - r, 108 - r), cr, Or
   Put (174 - r, 108 - r), cg, Or
   Put (160 - r,  84 - r), cb, Or

   ''free the memory used by the sprites
   ImageDestroy cr
   ImageDestroy cg
   ImageDestroy cb

   ''pause the program before closing
   Sleep

Differences from QB
   * None

See also
   * Or
   * Put (Graphics)



--------------------------------------------------------- KeyPgOpOrElse ----
Operator Orelse (Short Circuit Inclusive Disjunction)

Returns the short circuit-or (Inclusive Disjunction) of two numeric values

Syntax
   Declare Operator OrElse ( ByRef lhs As T1, ByRef rhs As T2 ) As Ret

Usage
   result = lhs OrElse rhs

Parameters
   lhs
      The left-hand side expression.
   T1
      Any numeric or boolean type.
   rhs
      The right-hand side expression.
   T2
      Any numeric or boolean type.
   Ret
      A numeric or boolean type (varies with T1 and T2).

Return Value
   Returns the short circuit-or (inclusive disjunction) of the two 
   operands.

Description
   This operator evaluates the left hand side expression.  If the result is 
   nonzero, then -1 (true) is immediately returned.  If the result is zero 
   then the right hand side is evaluated, and the logical result from that 
   is returned, returning -1 (true) for a nonzero value or 0 (false) for 
   zero.
   (for conversion of a boolean to an integer, false or true boolean value 
   becomes 0 or -1 integer value)

   The truth table below demonstrates all combinations of a short 
   circuit-or operation, the '-' denotes that the operand is not evaluated.

      +---------+---------+------+
      |Lhs Value|Rhs Value|Result|
      |0        |0        |0     |
      |0        |nonzero  |-1    |
      |nonzero  |-        |-1    |
      +---------+---------+------+

   Short-circuiting is performed - only expressions needed to calculate the 
   result are evaluated.  The left hand side lhs is evaluated first, and 
   only if it evaluates to zero (false) is the right hand side rhs also 
   evaluated. If the left hand side evaluation lhs returns non-zero (true), 
   it is known that at that point that the overall condition is true, so 
   the right hand side rhs is not evaluated (skipped).

   The return type is almost always an Integer, of the value 0 or -1, 
   denoting false and true respectively. Except if the left and right-hand 
   side types are both Boolean, then the return type is also Boolean.

   This operator cannot be overloaded for user-defined types.

Example
   ' Using the ORELSE operator on two numeric values
   Dim As Integer numeric_value1, numeric_value2
   numeric_value1 = 15
   numeric_value2 = 30

   'Result = -1
   Print numeric_value1 OrElse numeric_value2
   Sleep

Differences from QB
   * This operator was not available in QB.

See also
   * AndAlso
   * Or
   * Operator Truth Tables



-------------------------------------------------------------- KeyPgOut ----
Out

Outputs a value to a hardware port.

Syntax
   Declare Function Out ( ByVal port As UShort , ByVal data As UByte ) As 
   Long

Usage
   Out port,value

Parameters
   port
      Hardware port to write to.
   data
      Data value to write.

Description
   This function sends value to port and returns immediately.

Example
   'speakersound.bas 
   Sub Sound(ByVal freq As UInteger, dur As UInteger)
     Dim t As Double,f1 As Unsigned Short
      f1 = 1193181 \ freq
      Out &h61,Inp(&h61) Or 3
      Out &h43,&hb6
      Out &h42,LoByte(f1)
      Out &h42,HiByte(f1)
      t=Timer 
      While ((Timer - t) * 1000) < dur
        Sleep 0,1
      Wend
      Out &h61,Inp(&h61) And &hfc
   End Sub

   Sound(523, 60)  'C5
   Sound(587, 60)  'D5
   Sound(659, 60)  'E5
   Sound(698, 60)  'F5
   Sound(784, 60)  'G5
   Sound(880, 60)  'A5
   Sound(988, 60)  'B5
   Sound(1046, 60) 'C6 

	

Platform Differences
   * In the Windows and Linux versions three port numbers (&H3C7, &H3C8, 
     &H3C9) are hooked by the graphics library when a graphics mode is in 
     use to emulate QB's VGA palette handling. This use  is deprecated; use 
     Palette to retrieve and set palette colors.

   * Using true port access in the Windows version requires the program to 
     install a device driver for the present session. For that reason, 
     Windows executables using hardware port access should be run with 
     administrator permits each time the computer is restarted. Further 
     runs don't require admin rights as they just use the already installed 
     driver. The driver is only 3K in size and is embedded in the 
     executable.

See also
   * Inp
   * Wait
   * Palette

   


----------------------------------------------------------- KeyPgOutput ----
Output

Specifies text file to be opened for output mode

Syntax
   Open filename for Output [Encoding encoding_type] [Lock lock_type] as 
   [#]filenum 

Parameters
   filename
      file name to open for output
   encoding_type
      indicates encoding type for the file
   lock_type
      locking to be used while the file is open
   filenum
      unused file number to associate with the open file

Description
   A file mode used with Open to open a text file for writing.

   This mode is used to write text with Print #, or comma separated values 
   with Write #. 

   Text files can't be simultaneously read and written in FreeBASIC, so if 
   both functions are required on the same file, it must be opened twice.

   filename must be a string expression resulting in a legal file name in 
   the target OS, without wildcards. The file will be sought for in the 
   present directory, unless the filename contains a path . If the file 
   does not exist, it is created. The pointer is set at the first character 
   of the file.

   Encoding_type indicates the Unicode Encoding of the file, so characters 
   are correctly read. If omitted, "ascii" encoding is defaulted. Only 
   little endian character encodings are supported at the moment. 
      *"utf8"
      *"utf16"
      *"utf32" 
      *"ascii" (the default)

   Lock_type indicates the way the file is locked  for other processes, it 
   is one of:
      * Read - the file can be opened simultaneously by other processes, 
        but not for reading
      * Write - the file can be opened simultaneously by other processes, 
        but not for writing
      * Read Write - the file cannot be opened simultaneously by other 
        processes (the default)

   filenum Is a valid FreeBASIC file number (in the range 1..255) not being 
   used for any other file presently open. The file number identifies the 
   file for the rest of file operations. A free file number can be found 
   using the FreeFile function.

Example
   Dim ff As UByte
   Dim randomvar As Integer
   Dim name_str As String
   Dim age_ubyte As UByte

   ff = FreeFile
   Input "What is your name? ",name_str
   Input "What is your age? ",age_ubyte
   Open "testfile" For Output As #ff
   Write #ff, Int(Rnd(0)*42),name_str,age_ubyte
   Close #ff
   randomvar=0
   name_str=""
   age_ubyte=0

   Open "testfile" For Input As #ff
   Input #ff, randomvar,name_str,age_ubyte
   Close #ff

   Print "Random Number was: ", randomvar
   Print "Your name is: " + name_str
   Print "Your age is: " + Str(age_ubyte)

   'File outputted by this sample will look like this,
   'minus the comment of course:
   '23,"Your Name",19 

Differences from QB

See also
   * Append
   * Input (File Mode)
   * Open



--------------------------------------------------------- KeyPgOverload ----
Overload

Specifies that a procedure name can be overloaded

Syntax
   Declare [Static] Sub procedure_name [cdecl|stdcall|pascal] Overload [
   Alias "external_name"] [([parameter_list])] [Constructor [priority]] [
   Static] [Export]

   Declare [Static] Function procedure_name [cdecl|stdcall|pascal] Overload 
   [Alias "external_name"] [([parameter_list])] [ ByRef ] As return_type [
   Static] [Export]

   [Public|Private] Sub procedure_name [cdecl|stdcall|pascal] Overload [
   Alias "external_name"] [([parameter_list])] [Constructor [priority]] [
   Static] [Export]
      ..procedure body..
   End Sub

   [Public|Private] Function procedure_name [cdecl|stdcall|pascal] Overload 
   [Alias "external_name"] [([parameter_list])] [ ByRef ] As return_type  [
   Static] [Export]
      ..procedure body..
   End Function

Description
   In procedure declarations, Overload allows procedure names to be 
   overloaded, that is, other procedures (regardless of whether to be subs 
   or functions) can then be declared with the same name if their parameter 
   lists are unique. Two parameter lists are unique if they contain a 
   different number of parameters, or have parameters of different types. 
   Note that this means that two or more procedures cannot be declared with 
   the same name if they differ in return type alone.
   A variadic procedure name can never be overloaded.

   Once a procedure name has been declared overloaded, further declarations 
   using the name need not specify Overload, but it is allowed.

   Overload is not necessary in member procedure declarations, as they are 
   always implicitly overloaded.

   When calling an overloaded procedure, the compiler determines the most 
   appropriate definition to use among a set of compatible candidates, by 
   comparing the argument types used to call the procedure with the 
   parameter types specified in the definitions. If no match or an 
   ambiguous match is found, the compiler generates an error at compile 
   time.

Example
   Declare Function SUM Overload (A As Integer,B As Integer) As Integer
   Declare Function SUM Overload (A As Single,B As Single) As Single
   Function SUM  (A As Integer,B As Integer) As Integer
      Function=A+B
   End Function   
   Function SUM  (A As Single,B As Single) As Single
      Function=A+B
   End Function   
   Dim As Integer A,B
   Dim As Single A1,B1
   A=2
   B=3
   A1=2.
   b1=3.
   Print SUM(A,B)
   Print SUM (A1,B1)
   Sleep

Differences from QB
   * New to FreeBASIC

See also
   * Declare
   * Sub, Function



--------------------------------------------------------- KeyPgOverride ----
Override

Method attribute; specifies that a method must override a virtual

Syntax
   Type typename Extends basename
      ...
      Declare Sub|Function|Operator|Property|Destructor ... ( [
      parameterlist] ) [[ ByRef ] As datatype] Override
      ...
   End Type

Description
   In method declarations, Override can be used to indicate that this 
   method is expected to override a Virtual or Abstract method from the 
   base class. Then the compiler will show an error if the method does not 
   override anything (only a non-static method can override a virtual or 
   abstract method).

   Use of Override is not mandatory to override a virtual or abstract 
   method, it is highly recommended, as it will help prevent inadvertent 
   errors (name/signature not matching).

   Override can only be specified on the method declaration in the UDT 
   block, but not on the method body, because it is just a compile-time 
   check in the context of the inheritance hierarchy, and does not affect 
   the method in any way.

   Override is only recognized as a keyword at the end of member procedure 
   declarations. It can still be used as identifier elsewhere.

Example
   Type A Extends Object
      Declare Virtual Sub f1( )
      Declare Virtual Function f2( ) As Integer
   End Type

   Type B Extends A
      Declare Sub f1( ) Override
      Declare Function f2( ) As Integer Override
   End Type

   Sub A.f1( )
   End Sub

   Function A.f2( ) As Integer
      Function = 0
   End Function

   Sub B.f1( )
   End Sub

   Function B.f2( ) As Integer
      Function = 0
   End Function

Differences from QB
   * New to FreeBASIC

See also
   * Virtual, Abstract




============================================================================
    P

------------------------------------------------------------ KeyPgPaint ----
Paint

Fills an area delimited by a border of a specified color

Syntax
   Paint [target,] [STEP] (x, y)[, [paint][, [border_color]]]

Parameters
   target
      specifies buffer to draw on.  
   STEP
      indicates that coordinates are relative
   (x, y)
      coordinates of the pixel on which to start the flood fill (paint)
   paint
      the color attribute or fill pattern
      a numeric value indicates a color, while a string indicates a fill 
      pattern
   border_color
      boundary color for the fill

Description
   Graphics command to fill an area delimited by a border of specified 
   color. Also known as 'flood-fill' or 'paint bucket'.

   Paint can operate on the current work page as set by the ScreenSet 
   statement or on the target Get/Put buffer, if specified.

   Filling starts at specified (x,y) coordinates; if STEP is specified, 
   these are relative to the last graphics cursor position. Coordinates are 
   also affected by custom coordinates system set up by Window and/or 
   View (Graphics) statements; clipping set by View also applies.

   If the paint argument is a number, it is assumed a color in the same 
   format used by the Color statement, and the region is flood-filled using 
   that color. If paint is a String, the region will be filled using a 
   pattern; the pattern is always 8*8 pixels, and the passed string must 
   hold pixels data in a format dependent on the current color depth. The 
   string holds pattern pixels row by row, and its size should be as 
   follows:

   For color depths 1, 2, 4 and 8:
   size = 8 * 8 = 64
   For color depths 15 and 16:
   size = (8 * 8) * 2 = 128
   For color depths 24 and 32:
   size = (8 * 8) * 4 = 256

   If the passed string is smaller, missing pixels will be 0. If the paint 
   argument is omitted, normal filling is performed using the current 
   foreground color set by Color. Flood-filling continues until pixels of 
   the specified border color are found; if border_color is omitted, the 
   current background color is assumed.

   Warning: If the border is drawn with a transparent color (in conjunction 
   with the GFX_ALPHA_PRIMITIVES option flag) and some pixels are overdrawn 
   on it, the resultant (blended) color of these overdrawn pixels can cause 
   a leak point through which the fill color escapes outside the border. So 
   drawing a border with a transparent color is not recommended.

Example
   ' draws a white circle painted blue inside
   Screen 13
   Circle (160, 100), 30, 15
   Paint (160, 100), 1, 15
   Sleep

   ' draws a circle and fills it with a checkered pattern

   '' choose the bit depth for the Screen
   '' try setting this to other values: 8, 16 or 32

   Const bit_depth = 8

   '' function for returning a pixel color, represented as a string
   '' returns a the string in the appropriate format for the current bit depth
   Function paint_pixel( ByVal c As UInteger, ByVal bit_depth_ As Integer ) As String
      
      If bit_depth_ <= 8 Then '' 8-bit:
         Function =  Chr( CUByte(c) )
         
      ElseIf bit_depth_ <= 16 Then '' 16-bit:
         Function = MKShort( c Shr 3 And &h1f Or _
                        c Shr 5 And &h7e0 Or _
                        c Shr 8 And &hf800 )
         
      ElseIf bit_depth_ <= 32 Then '' 32-bit:
         Function = MKL(c)
         
      End If
      
   End Function

   '' open a graphics window at the chosen bit depth
   ScreenRes 320, 200, bit_depth

   '' declare variables for holding colors
   Dim As UInteger c, c1, c2, cb

   '' declare string variable for holding the pattern used in Paint
   Dim As String paint_pattern = ""

   '' set colors
   If bit_depth <= 8 Then
      c1 = 7  ''pattern color 1
      c2 = 8  ''pattern color 2
      cb = 15 ''border color
   Else
      c1 = RGB(192, 192, 192) '' pattern color 1
      c2 = RGB(128, 128, 128) '' pattern color 2
      cb = RGB(255, 255, 255) '' border color
   End If

   '' make the pattern to be used in Paint
   For y As UInteger = 0 To 7
      For x As UInteger = 0 To 7
         
         '' choose the color of the pixel (c)
         If (x \ 4 + y \ 4) Mod 2 > 0 Then
            c = c1
         Else
            c = c2
         End If
         
         '' add the pixel to the pattern
         paint_pattern = paint_pattern + paint_pixel(c, bit_depth)
         
         '' the following line can be used if you want to draw the 
         '' pattern tile in the top left hand corner of the screen:
         
         ' pset (x, y), c
         
      Next x
   Next y

   '' draw a circle with the border color
   Circle (160, 100), 50, cb, , , 1.0

   '' paint the circle region with paint_pattern, stopping at the border color
   Paint (160, 100), paint_pattern, cb

   '' pause before ending the program
   Sleep

Differences from QB
   * target is new to FreeBASIC
   * In QB, the fill pattern was always 8-bits wide, and the height was 
     the length of the string (up to 64). In FreeBASIC, the fill pattern is 
     8 pixels wide, independent of the color depth, and the height is 
     always 8
   * The background color parameter supported by QB is not supported by 
     the FreeBASIC version

See also
   * Screen



---------------------------------------------------------- KeyPgPalette ----
Palette

Customizes colors in modes with paletted colors

Syntax
   Palette [Get] [index, color]
   Palette [Get] [index, r, g, b]
   Palette [Get] Using arrayname(idx)

Parameters
   Get
      indicates getting palette information rather than setting palette 
      information
   index
      palette index
   color
      color attribute
   r
      red color component
   g
      green color component
   b
      blue color component
   Using
      indicates using array of color values
   arrayname(idx)
      array and index to get/set color attributes

Description
   The Palette statement is used to retrieve or customize the current 
   palette for graphics modes with a color depth of up to 8bpp; using 
   Palette while in a mode with a higher color depth will have no effect. 
   Calling Palette with no argument restores the default palette for 
   current graphics mode, as set by the Screen (Graphics) statement.
   The GfxLib sets a default palette when a Screen mode is initialized.

   First form
      If you specify index and color, these are dependent on the current 
      mode:
         +-----------+-----------+-----------+
         |Screen mode|index range|color range|
         |1          |0-3        |0-15       |
         |2          |0-1        |0-15       |
         |7,8        |0-15       |0-15       |
         |9          |0-15       |0-63       |
         |11         |0-1        |see below  |
         |12         |0-15       |see below  |
         |13 to 21   |0-255      | see below |
         +-----------+-----------+-----------+

      In screen modes 1, 2, 7, 8 and 9 you can assign to each color index 
      one of the colors in the available range. In other screen modes, the 
      color must be specified in the form &hBBGGRR, where BB, GG and RR are 
      the blue, green and red components ranging &h0-&h3F in hexadecimal (0
      -63 in decimal). If you don't like hexadecimal form, you can use the 
      following formula to compute the integer value to pass to this 
      parameter:
      color = red Or (green Shl 8) Or (blue Shl 16)
      Where red, green and blue must range 0-63. Please note that color 
      values accepted by Palette are not the in the same form as returned 
      by the RGB macro (the red and blue fields are inverted, and the range 
      is different); this is for backward compatibility with QB.

   Second form
      In the second form, you specify the red, green and blue components 
      for a palette entry directly, by calling Palette with 4 parameters. 
      In this case r, g and b must be in the range 0-255.

   Third form
      Calling Palette Using allows to set a list of color values all at 
      once; you should pass an array holding enough elements as the color 
      indices available for your current graphics mode color depth (2 for 
      1bpp, 4 for 2bpp, 16 for 4bpp or 256 for 8bpp). The array elements 
      must be integer color values in the form described above. The colors 
      stored into arrayname starting with given idx index are then assigned 
      to each palette index, starting with index 0.

   Form 1 and 3 are for backward compatibility with QB; form 2 is meant to 
   ease palette handling. Any change to the palette is immediately visible 
   on screen.

   If the Get option is specified, Palette retrieves instead of setting 
   color values for the current palette. The parameters have the same 
   meaning as specified for the form being used, but in this case color, r, 
   g and b must be variables passed by reference that will hold the color 
   RGB values on function exit.

Example
   ' Setting a single color, form 1.
   Screen 15
   Locate 1,1: Color 15
   Print "Press any key to change my color!"
   Sleep
   ' Now change color 15 hues to bright red
   Palette 15, &h00003F
   Sleep

   ' Getting a single color, form 2.
   Dim As Integer r, g, b
   Screen 13
   Palette Get 32, r, g, b
   Print "Color 32 hues:"
   Print Using "Red:### Green:### Blue:###"; r; g; b
   Sleep

   ' Getting whole palette, form 3.
   Dim pal(0 To 255) As Integer
   Screen 13
   Palette Get Using pal
   For i As Integer = 0 To 15
      Print Using "Color ## = &"; i; Hex(pal(i), 6)
   Next i
   Sleep

Differences from QB
   * QBasic did not support PALETTE GET to retrieve a palette.
   * QBasic did not allow passing individual red/green/blue values.

See also
   * Screen (Graphics)
   * Color
   * Using
   * Internal Pixel Formats
   * Default Palettes



----------------------------------------------------------- KeyPgPascal ----
pascal

Specifies a Pascal-style calling convention in a procedure declaration

Syntax
   Sub name pascal [Overload] [Alias "alias"] ( parameters )
   Function name pascal [Overload] [Alias "alias"] ( parameters ) [ ByRef ] 
   As return_type

Description
   In procedure declarations, pascal specifies that a procedure will use 
   the pascal calling convention. In the Pascal calling convention, any 
   parameters are to be passed (pushed onto the stack) in the same order in 
   which they are listed, that is, from left to right. The procedures need 
   not preserve the EAX, ECX or EDX registers, and must clean up the stack 
   (pop any parameters) before it returns.

   pascal is not allowed to be used with variadic procedure declarations 
   (those with the last parameter listed as "...").

   pascal is the default calling convention for procedures in Microsoft 
   QuickBASIC, and is the standard convention used in the Windows 3.1 API.

Example
   Declare Function MyFunc pascal Alias "MyFunc" (MyParm As Integer) As Integer

Differences from QB
   * New to FreeBASIC

See also
   * cdecl, stdcall
   * Declare
   * Sub, Function



------------------------------------------------------------ KeyPgPcopy ----
PCopy

Copies one graphical or text page onto another

Syntax
   Declare Function PCopy ( ByVal source As Long = -1, ByVal destination As 
   Long = -1 ) As Long

Usage
   PCopy [ source ] [, destination ]

Parameters
   source
      page to copy from
   destination
      page to copy to

Return Value
   Returns zero (0) if successful, or a non-zero error code to indicate a 
   failure.

Description
   Copies one graphical or text video page to another. Useful for drawing 
   all graphics on one invisible page and copying it to the active visible 
   page - creating smooth graphics and animation. Known as 'double 
   buffering' or 'page flipping'.

   source and destination refer to page numbers. The 'source' page is 
   copied over the 'destination' page when pcopy is called.

   If the source argument is omitted, the current working page is assumed.  
   If the destination page is omitted, the current visible page is assumed.

   PCopy is inactive if the destination page is locked.

   The error code returned by PCopy can be checked using Err in the next 
   line. The function version of  PCopy returns directly the error code as 
   a 32 bit Long.

Example

   'Sets up the screen to be 320x200 in 8-bit color with 2 video pages.
   ScreenRes 320, 200, 8, 2

   'Sets the working page to 1 and the displayed page to 0
   ScreenSet 1, 0

   'Draws a circle moving across the top of the screen
   For x As Integer = 50 To 269
      Cls                    'Clears the screen so we can start fresh
      Circle (x, 50), 50, 14 'Draws a yellow circle with a 50 pixel radius on page 1
      PCopy 1, 0             'Copies our image from page 1 to page 0
      Sleep 25               'Waits for 25 milliseconds.
   Next x

   'Wait for a keypress before the screen closes
   Sleep

   '' Compile with -lang fblite or qb

   #lang "fblite"

   '' Console mode example:

   '' Set the working page number to 0, and the visible page number to 1
   #if __FB_LANG__ = "QB"
   Screen ,, 0, 1
   #else
   Screen , 0, 1
   #endif

   Dim As Integer i, frames, fps
   Dim As Double t

   t = Timer

   Do
      '' Fill working page with a certain color and character
      Cls
      Locate 1, 1
      Color (i And 15), 0
      Print String$(80 * 25, Hex$(i, 1));
      i += 1

      '' Show frames per second
      Color 15, 0
      Locate 1, 1
      Print "fps: " & fps,
      If Int(t) <> Int(Timer) Then
         t = Timer
         fps = frames
         frames = 0
      End If
      frames += 1

      '' Copy working page to visible page
      PCopy

      '' Sleep 50ms per frame to free up cpu time
      Sleep 50, 1

      '' Run loop until the user presses a key
   Loop Until Len(Inkey$)

Platform Differences
   * Maximum number of text pages in Windows is 4.
   * Maximum number of text pages in DOS is 8.
   * Maximum number of text pages in all other targets is 1.
   * Maximum number of graphics pages depends on what was specified when 
     the Screen or ScreenRes statement was called.

Differences from QB
   * None

See also
   * ScreenCopy
   * Flip
   * Screen



------------------------------------------------------------- KeyPgPeek ----
Peek

Gets the value of an arbitrary type at an address in memory

Syntax
   Declare Function Peek ( ByVal address As Any Ptr ) ByRef As UByte
   Declare Function Peek ( datatype, ByVal address As Any Ptr ) ByRef As 
   datatype

Usage
   Peek( [ datatype, ] address )

Parameters
   address
      The address in memory to get the value from.
   datatype
      The type of value to get. If omitted, UByte is assumed.

Description
   This procedure returns a reference to the value in memory given by a 
   memory address, and is equivalent to

      *cast(ubyte ptr, address)
         or
      *cast(datatype ptr, address)

   Note: When using Peek, the -exx compiler option does not add code for 
   null-pointer checking (no nullity test on the value of address).

Example
   Dim i As Integer, p As Integer Ptr
   p = @i

   Poke Integer, p, 420
   Print Peek(Integer, p)

   will produce the output:

   420

Differences from QB
   * Peek did not support the datatype parameter in QB, and could only 
     return individual bytes.
   * Peek returns a reference in FB, so can be used to set the memory 
     contents of the address, like with Operator * (Value Of).
   * DEF SEG isn't needed anymore because the address space is 32-bit flat 
     in FreeBASIC.

See also
   * Poke
   * Operator * (Value Of)


------------------------------------------------------------- KeyPgPmap ----
PMap

Maps coordinates between view and physical mapping.

Syntax
   Declare Function PMap ( ByVal coord As Single, ByVal func As Long ) As 
   Single

Usage
   result = PMap( coord, func )

Parameters
   coord
      An expression indicating the coordinate to be mapped.
   func
      The mapping function number to be applied to given coordinate.

Return Value
   The mapped coordinate value.

Description
   This function converts a coordinate between view (as defined by the 
   Window statement) and physical (as set by the View (Graphics) statement) 
   mappings. Depending on the value of func, expr is used to compute a 
   different mapping to be returned by PMap:

         +-----------+---------------------------------------------------------------------------------+
         |func value:|return value:                                                                    |
         |0          |Treats expr as x view coordinate and returns corresponding x physical coordinate.|
         |1          |Treats expr as y view coordinate and returns corresponding y physical coordinate.|
         |2          |Treats expr as x physical coordinate and returns corresponding x view coordinate.|
         |3          |Treats expr as y physical coordinate and returns corresponding y view coordinate.|
         +-----------+---------------------------------------------------------------------------------+

Example
   ScreenRes 640, 480
   Window Screen (0, 0)-(100, 100)
   Print "Logical x=50, Physical x="; PMap(50, 0)   '' 320
   Print "Logical y=50, Physical y="; PMap(50, 1)   '' 240
   Print "Physical x=160, Logical x="; PMap(160, 2) '' 25
   Print "Physical y=60, Logical y="; PMap(60, 3)   '' 12.5
   Sleep

Differences from QB
   * None

See also
   * Window
   * View (Graphics)



------------------------------------------------------------ KeyPgPoint ----
Point

Returns the color attribute of a specified pixel coordinate

Syntax
   result = Point( coord_x, coord_y [,buffer] )
   or 
   result = Point( function_index )

Usage
   coord_x
      x coordinate of the pixel
   coord_y
      y coordinate of the pixel
   buffer
      the image buffer to read from
   function_index
      the type of screen coordinate to return: one of the values 0, 1, 2, 3

Return Value
   The return datatype is always an Integer.

   If the x, y coordinates of a pixel are provided Point returns the color 
   attribute at the specified coordinates, as an 8-bit palette index in 8 
   bpp indexed modes, a 24-bit RGB value in 16 bpp modes (upper 8 bits of 
   the integer unused, limited precision of R,G,B), and a 32-bit RGB or 
   RGBA value in 32 bpp modes (upper 8 bits unused or holding Alpha).  Note 
   that it does NOT return a 16-bit value (5 bits R + 6 bits G + 5 bits B).

   If the argument is a function index, Point returns one of the graphics 
   cursor coordinates set by the last graphics command.

      +--------+------------------------------------------------------------------------------------------------------------------------------+
      |Argument| Value Returned                                                                                                               |
      | 0      |The current physical x coordinate.                                                                                            |
      |1       |The current physical y coordinate.                                                                                            |
      | 2      |The current view x coordinate. This returns the same value as the POINT(0) function if the WINDOW statement has not been used.|
      |3       |The current view y coordinate. This returns the same value as the POINT(1) function if the WINDOW statement has not been used.|
      +--------+------------------------------------------------------------------------------------------------------------------------------+

Description
   GfxLib Function with two different uses. 
   If supplied with two coordinates it reads the color of the pixel at the 
   coordinate coord_x, coord_y of the screen, or of the buffer, if 
   supplied. 
   The value return is a color index in a 256 or less color Screen, and an 
   RGB value in true color modes. If the coordinates are off-screen or 
   off-buffer, -1 is returned

   If supplied with a single value it returns the one of the coordinates of 
   the graphics cursor as set by the last graphics command executed. If the 
   last command was executed in a buffer, the values returned will be 
   coordinates in the buffer. Arguments out of the range 0-3 will return 0.

   The function Point does not work in text modes.

   Speed note: while Point provides valid results, it is quite slow to call 
   repeatedly due to the overhead of additional calculations and checks. 
   Much better performance can be achieved by using direct memory access 
   using the results obtained from ImageInfo and ScreenInfo/ScreenPtr.

Example
   ' Set an appropriate screen mode - 320 x 240 x 8bpp indexed color
   ScreenRes 320, 240, 8

   ' Draw a line using color 12 (light red)
   Line (20,20)-(100,100), 12

   ' Print the color of a point on the line
   Print Point(20,20)

   ' Sleep before the program closes
   Sleep

Output:

   12

Differences from QB
   * buffer is new to FreeBASIC
   * In 16 bpp and 32 bpp modes, a 32-bit value is returned instead of an 
     8-bit palette index

See also
   * PSet - write pixels
   * PMap
   * Color
   * View (Graphics)
   * Window
   * Internal pixel formats



------------------------------------------------------- KeyPgPointCoord ----
PointCoord

Queries Draw's pen position in graphics mode

Syntax
   Declare Function PointCoord( ByVal func As Long ) As Single

Usage
   result = PointCoord( func )

Description
   The PointCoord function can be used to query x and y position of the Draw
   pen in graphics mode. The result value depends on the passed func value:

      +-----------+---------------------------------------------------------+
      |func value:|return value:                                            |
      |0          |x physical coordinate, same as PMap( PointCoord( 2 ), 0 )|
      |1          |y physical coordinate, same as PMap( PointCoord( 3 ), 1 )|
      |2          |x view coordinate                                        |
      |3          |y view coordinate                                        |
      +-----------+---------------------------------------------------------+

Example
   Screen 12

   Print "--- Default window coordinate mapping ---"
   Print "DRAW pen position, at the default (0,0):"
   Print "Physical:", PointCoord( 0 ), PointCoord( 1 )
   Print "View:", PointCoord( 2 ), PointCoord( 3 )

   Draw "BM 50,50"
   Print "DRAW pen position, after being moved to (50,50):"
   Print "Physical:", PointCoord( 0 ), PointCoord( 1 )
   Print "View:", PointCoord( 2 ), PointCoord( 3 )

   Print "--- Changing window coordinate mapping ---"
   Window Screen (-100, -100) - (100, 100)

   Draw "BM 0,0"
   Print "DRAW pen position, after being moved to (0,0):"
   Print "Physical:", PointCoord( 0 ), PointCoord( 1 )
   Print "View:", PointCoord( 2 ), PointCoord( 3 )

   Draw "BM 50,50"
   Print "DRAW pen position, after being moved to (50,50):"
   Print "Physical:", PointCoord( 0 ), PointCoord( 1 )
   Print "View:", PointCoord( 2 ), PointCoord( 3 )

   Sleep

Differences from QB
   * New to FreeBASIC

See also
   * PMap
   * Window



-------------------------------------------------------------- KeyPgPtr ----
(Pointer | Ptr)

A variable declaration type modifier

Syntax
   Dim symbolname As DataType {Pointer | Ptr}

Description
   Declares a pointer variable.

   Operator @ (Address Of) operator or VarPtr are used to take the address 
   of a variable. The Operator * (Value Of) operator is used to dereference 
   the pointer, that is, access the actual value stored in the memory 
   location the pointer is pointing at.

Example
   ' Create the pointer.
   Dim p As Integer Ptr

   ' Create an integer value that we will point to using pointer "p"
   Dim num As Integer = 98845

   ' Point p towards the memory address that variable "num" occupies.
   p = @num

   ' Print the value stored in memory pointed to by pointer "p"
   Print "Pointer 'p' ="; *p
   Print 

   ' Print the actual location in memory that pointer "p" points at.
   Print "Pointer 'p' points to memory location:"
   Print p

   Dim p As ZString Pointer
   Dim text As String
   text = "Hello World!"
   p = StrPtr(text) + 6
   Print text
   Print *p

   '' Output:
   '' Hello World!
   '' World!

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Pointer or __Ptr.

Differences from QB
   * New to FreeBASIC

See also
   * Allocate



------------------------------------------------------------- KeyPgPoke ----
Poke

Assigns a value to a location in memory.

Syntax
   Declare Sub Poke ( ByVal address As Any Ptr, ByRef value As UByte )
   Declare Sub Poke ( datatype, ByVal address As Any Ptr, ByRef value As 
   datatype )

Usage
   Poke [ datatype, ] address, value

Parameters
   datatype
      The type of data at the specified address. If omitted, UByte is 
      assumed.
   address
      The location in memory to assign to.
   value
      The value to assign.

Description
   Poke assigns a value to a location in memory. It is equivalent to
      *cast(ubyte ptr, address) = value
         or
      *cast(datatype ptr, address) = value

   When datatype is a user-defined type, Poke assigns value using the 
   type's Operator Let.

   Note: When using Poke, the -exx compiler option does not add code for 
   null-pointer checking (no nullity test on the value of address).

Example
   Dim i As Integer, p As Integer Ptr
   p = @i

   Poke Integer, p, 420
   Print Peek(Integer, p)

   Will produce the output:

   420

Differences from QB
   * Only the byte form were supported in QB.
   * DEF SEG isn't needed anymore because the address space is 32-bit flat 
     in FreeBASIC.

See also
   * Peek



-------------------------------------------------------------- KeyPgPos ----
Pos

Returns the horizontal (left to right) position of the text cursor

Syntax
   Declare Function Pos ( ) As Long
   Declare Function Pos ( ByVal dummy As Long ) As Long

Usage
   result = Pos[ ( dummy ) ]

Parameters
   dummy
      An unused parameter retained for backward compatibility with QBASIC.

Return Value
   Returns the horizontal position of the text cursor.

Description
   Returns the horizontal (left to right) position of the text cursor. The 
   leftmost column is number 1.

Example
   Dim As Integer p

   '' print starting column position
   p = Pos()
   Print "position: "; p

   '' print a string, without a new-line
   Print "ABCDEF";

   '' print new column position:
   p = Pos()
   Print: Print "position: "; p
   Print

   ''position changes after each Print:
   Print "Column numbers: "
   Print Pos(), Pos(), Pos(), Pos(), Pos()

Differences from QB
   * The dummy parameter was not optional in QBASIC.

See also
   * CsrLin
   * Tab
   * Locate



--------------------------------------------------------- KeyPgPreserve ----
Preserve

Used with ReDim to preserve contents will resizing an array

Syntax
   ReDim Preserve array(...) [As datatype]

Description
   Used with ReDim so that when an array is resized, data is not reset but 
   is preserved. This means when the array is enlarged that only new data 
   is reset, while the old data remains the same (but not necessarily at 
   the same absolute addresses in memory).

   NOTE: ReDim Preserve may not work as expected in all cases:
      Preserve's current behavior is to keep the original data contiguous 
      in memory, and only expand or truncate the size of the memory (if 
      resizing is not possible, the whole original data block is first 
      shifted to another memory location).
      Its behavior (with a single dimension) is well-defined only when the 
      upper bound is changed.  If the lower bound is changed, the current 
      result is that the data is in effect shifted to start at the new 
      lower bound.
      If there are multiple dimensions, only the upper bound of only the 
      first dimension may be changed safely.  If the first dimension is 
      reduced, the existing mappable data may be lost.  If lower-order 
      dimensions are resized at all, the effects can be hard to predict 
      (because multidimensional arrays are stored in row-major order : 
      values differing only in the last index are contiguous).

Example
   ReDim array(1 To 3) As Integer
   Dim i As Integer

   array(1) = 10
   array(2) = 5
   array(3) = 8

   ReDim Preserve array(1 To 10)

   For i = 1 To 10
      Print "array("; i; ") = "; array(i)
   Next

Differences from QB
   * Preserve wasn't supported until PDS 7.1

See also
   * Dim
   * LBound
   * ReDim
   * UBound



----------------------------------------------------------- KeyPgPreset ----
PReset

Plots a single pixel

Syntax
   PReset [target ,] [STEP] (x, y) [,color]

Parameters
   target
      specifies buffer to draw on.  
   STEP
      indicates that coordinates are relative
   (x, y)
      coordinates of the pixel.
   color
      the color attribute.

Description
   target specifies buffer to draw on.  target may be an image created with 
   ImageCreate or Get (Graphics).  If omitted, target defaults to the 
   screen's current work page.

   (x, y) are the coordinates of the pixel.  STEP if present, indicates 
   that (x, y) coordinates are relative to the graphics cursor position.  
   If omitted, (x, y) are relative to the upper left-hand corner of target. 
   The x and y coordinates are affected by the last call to the 
   View (Graphics) and Window statements, and respect the current clipping 
   region as set by the View (Graphics) statement.

   color specifies the color attribute.  If omitted, color defaults to the 
   current background color.  See Color.  color is graphics mode specific, 
   see Color and Screen (Graphics) for details.

Example
   Screen 13

   'Set background color to 15
   Color , 15

   'Draw a pixel with the background color at 10, 10
   PReset (10,10)

   'Draw a pixel with the background color at Last x cord +10, Last y cord +10
   PReset Step (10,10)
   Sleep

Differences from QB
   * target is new to FreeBASIC

See also
   * PSet



------------------------------------------------------------ KeyPgPrint ----
(Print | ?)

Writes text to the screen

Syntax
   (Print | ?) [ expressionlist ] [ , | ; ]

Parameters
   expressionlist
      list of items to print

Description
   Print outputs a list of values to the screen. Numeric values are 
   converted to their string representation, with left padding for the 
   sign. Objects of user-defined types must overload Operator Cast () As 
   String.

   Consecutive values in the expression list are separated either by a 
   comma (,) or semicolon (;). A comma indicates printing should take place 
   at the next 14 column boundary, while a semicolon indicates values are 
   printed with no space between them.  This has a similar effect to 
   concatenating expressions using + or &.

   Print also supports the special expressions, Spc() and Tab().  These can 
   be used to space out expressions, or to align the printing to a specific 
   column.

   A new-line character is printed after the values in the expression list 
   unless the expression list is followed by a comma or semicolon.  A Print 
   without any expressions or separators following it will just print a 
   new-line.

   NOTE: Print resets the Err value after each expression is printed.

   NOTE: In graphics mode, Draw String provides a flexible alternative to 
   Print: it prints a string to the screen with pixel positioning, 
   transparent background, and can use a user-supplied font.

Example
   '' print "Hello World!", and a new-line
   Print "Hello World!"

   '' print several strings on one line, then print a new-line
   Print "Hello";
   Print "World"; "!";
   Print

   '' column separator
   Print "Hello!", "World!"

   '' printing variables/expressions
   Dim As Double pi = Atn(1) * 4
   Dim As String s = "FreeBASIC"

   Print "3 * 4 ="; 3 * 4

   Print "Pi is approximately"; pi
   Print s; " is great!"

Dialect Differences
   * In the -lang qb dialect, an extra space is printed after numbers.

Differences from QB
   * None, when using QBASIC's variable types in -lang qb.
   * Unsigned numbers are printed without a space before them.
   * QB did not support casting for UDTs, so didn't allow them to be Print
     ed.

See also
   * Spc
   * Tab
   * Print #
   * ? #
   * Print Using
   * ? Using
   * Write
   * Draw String
   * Input



---------------------------------------------------------- KeyPgPrintPp ----
(Print | ?) #

Writes a list of values to a file or device

Syntax
   (Print | ?) # filenum, [ expressionlist ] [ , | ; ]

Parameters
   filenum
      The file number of a file or device opened for Output or Append.
   expressionlist
      List of values to write.

Description
   Print # outputs a list of values to a text file or device. Numeric 
   values are converted to their string representation, with left padding 
   for the sign. Objects of user-defined types must overload Operator Cast 
   () As String.

   Consecutive values in the expression list are separated either by a 
   comma (,) or semicolon (;). A comma indicates printing should take place 
   at the next 14 column boundary, while a semicolon indicates values are 
   printed with no space between them.

   A new-line character is printed after the values in the expression list 
   unless the expression list is followed by a comma or semicolon.

   Note that the comma (,) immediately following the file number is still 
   necessary, even the expression list is empty.  In this case a new-line 
   is printed, just as with a normal expression list that doesn't have a 
   comma or semicolon at the end.

Example
   Open "bleh.dat"  For Output As #1
      
      Print #1, "abc def"
      Print #1, 1234, 5678.901, "xyz zzz"
      
      Close #1

Dialect Differences
   * In the -lang qb dialect, an extra space is printed after numbers.

Differences from QB
   * None, when using QBASIC's variable types in -lang qb.
   * Unsigned numbers are printed without a space before them.
   * QB did not support casting for UDTs, so didn't allow them to be Print
     ed.

See also
   * Print Using
   * ? Using
   * Print
   * ?
   * Write #
   * Open



------------------------------------------------------- KeyPgPrintusing ----
(Print | ?) Using

Outputs formatted text to the screen or output device

Syntax
   (Print | ?) [# filenum ,] [ printexpressionlist {,|;} ] Using 
   formatstring ; [ expressionlist [ ; ] ]

Parameters
   filenum
      The file number of a file or device opened for Output or Append.  
      (Alternatively LPrint may be used where appropriate, instead of 
      Print #)
   printexpressionlist
      Optional preceding list of items to print, separated by commas (,) or 
      semi-colons (;) (see Print for more details).
   formatstring
      Format string to use.
   expressionlist
      List of items to format, separated by semi-colons (;).

Description
   Print to screen various expressions using a format determined by the 
   formatstring parameter. Internally, Print Using uses a buffer size of 
   2048 bytes: while it is highly unlikely that this buffer would be 
   filled, it should be noted that output would be truncated should this 
   limit be reached.

   If no expression list is given, the format string will be printed up to 
   the first special marker.  Note that the semi-colon after formatstring 
   is still necessary, even if no expression list is given.

   The format string dictates how the expressions are to be formatted when 
   output to the screen, indicated by the use of special marker characters. 
   There are markers for formatting both string and numeric output:

   String formatting

         +------+----------------------------------------------------------------------+
         |Marker|Formatting                                                            |
         |!     |prints the first character of a string                                |
         |\   \ |prints as many characters of a string as occupied between the pair \ \|
         |&     |prints the entire string                                              |
         +------+----------------------------------------------------------------------+

   Numeric formatting

         +------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
         |Marker|Formatting                                                                                                                                                            |
         |#     |placeholder for either an integer digit, or a decimal digit if a decimal point precedes it                                                                            |
         |,     |placed after integer digit indicates groups of 3 digits should be separated by commas in fixed-point notation                                                         |
         |.     |placed near # indicates place for the decimal point                                                                                                                   |
         |^^^^  |uses exponential notation (E+/-###) when placed after the digit characters                                                                                            |
         |+     |placed before/after the format string, controls whether the sign of a number is prepended/appended, and causes an explicit '+' sign to be printed for positive numbers|
         |-     |placed after the format string, causes the sign of the number to be appended rather than prepended, appending a space/negative sign for positive/negative numbers     |
         |$$    |placed at the start of integer digits, causes a dollar sign to be prepended to the number (after the sign if one is prepended)                                        |
         |**    |placed at the start of integer digits, causes any padding on the left to be changed from spaces to asterisks                                                          |
         |**$   |placed at the start of integer digits, pads on the left with asterisks, and prepends a dollar sign after the asterisks                                                |
         |&     |prints a number intelligently, using the exact number of digits required (new to version 0.21.0b)                                                                     |
         +------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+

   All of the special marker characters can be escaped by preceding them 
   with the underscore character "_", allowing them to be printed directly. 
   For example, "_!" is printed as "!", and "__" is printed as "_".

   If a numerical value cannot fit in the number of digits indicated by the 
   format string, the formatting is adapted to fit the number, possibly 
   switching to scientific notation, and the number is printed preceded by 
   the percent "%" character. E.g., the number 1234 with a formatstring of 
   "##.##" would be printed as "%1234.00".

   All other characters within the format string are printed as they 
   appear.

   A new-line character is printed after the values in the expression list 
   unless the expression list is followed by a semicolon (;).

Example

   Print Using "The value is #.## seconds"; 1.019
   Print Using "The ASCII code for the pound sign (_#) is ###"; Asc("#")
   Print Using "The last day in the year is & \ \"; 31; "December"

   will produce the output:

   The value Is 1.02 seconds
   The ASCII code For the pound sign (#) Is  35
   The last Day in the Year Is 31 Dec

Differences from QB
   * QB didn't allow "&" to be used for printing numbers.

See also
   * Print
   * ?
   * Print #
   * ? #
   * Format
   * Using
   * Palette Using



---------------------------------------------------------- KeyPgPrivate ----
Private

Specifies a procedure having internal linkage

Syntax
   Private Sub procedure_name [cdecl|stdcall|pascal] [Overload] [Alias 
   "external_name"] [([parameter_list])] [Constructor [priority]] [Static] 
   [Export]
      ..procedure body..
   End Sub

   Private Function procedure_name [cdecl|stdcall|pascal] [Overload] [Alias 
   "external_name"] [([parameter_list])] [ ByRef ] As return_type  [Static] 
   [Export]
      ..procedure body..
   End Function

Description
   In procedure definitions (forbidden at declaration line level), Private 
   specifies that a procedure has internal linkage, meaning its name is not 
   visible to external modules.
   Therefore among the compiled modules, two procedures with the same 
   identifier, but defined inside different modules, may exist if both are 
   Private.

   The compiler removes the Private procedures that are not called, but 
   this does not currently work for Private procedures that are only called 
   by other Private procedures that are not called themselves, because the 
   first one appears as being called.

   The Option Private statement allows procedures to be defined with 
   internal linkage by default.

Example
   'e.g.

   Private Sub i_am_private
   End Sub

   Sub i_am_public
   End Sub

Differences from QB
   * New to FreeBASIC

See also
   * Private: (Access Control)
   * Public
   * Option Private
   * Sub
   * Function



------------------------------------------------------- KeyPgVisPrivate ----
Private: (Access Control)

Specifies private member access control in a Type or Class

Syntax
   Type typename
      Private:
         member declarations
   End Type

Parameters
   typename
      name of the Type or Class
   member declarations
      declarations for fields, functions, or enumerations

Description
   Private: indicates that member declarations following it have private 
   access.  Private members are accessible only from inside a member 
   function for the Type or Class (so not accessible from inside a member 
   function for types or classes which are derived from the Type or Class).

   member declarations following Private: are private until a different 
   access control specifier is given, like Public: or Protected:.

   Members in a Type declaration are Public: by default if no member access 
   control specifier is given.

Example
   Type testing
     number As Integer
     Private:
      nome As String
     Declare Sub setNome( ByRef newnome As String )
   End Type

   Sub testing.setnome( ByRef newnome As String )
     '' This is OK. We're inside a member function for the type
     this.nome = newnome
   End Sub

   Dim As testing myVariable

   '' This is OK, number is public
   myVariable.number = 69

   '' this would generate a compile error 
   '' - nome is private and we're trying to access it outside any of this TYPE's member functions 
   '' myVariable.nome = "FreeBASIC"

Dialect Differences
   * Available only in the -lang fb dialect.

Differences from QB
   * New to FreeBASIC

See also
   * Private
   * Public: (Access Control)
   * Protected: (Access Control)
   * Type



-------------------------------------------------------- KeyPgOpProcptr ----
Operator Procptr (Procedure Pointer)

Returns the address of a procedure

Syntax
   Declare Operator ProcPtr ( ByRef lhs As T ) As T Ptr

Usage
   result = ProcPtr ( lhs )

Parameters
   lhs
      A procedure.
   T
      The type of procedure.

Return Value
   Returns the address of the procedure.

Description
   This operator returns the address of a Sub or Function procedure.

   Operator @ (Address Of), when used with procedures, has identical 
   behavior.

Example
   ' This example uses ProcPtr to demonstrate function pointers
   Declare Function Subtract( x As Integer, y As Integer) As Integer
   Declare Function Add( x As Integer, y As Integer) As Integer
   Dim myFunction As Function( x As Integer, y As Integer) As Integer

   ' myFunction will now be assigned to Add
   myFunction = ProcPtr( Add )
   Print myFunction(2, 3)

   ' myFunction will now be assigned to Subtract.  Notice the different output.
   myFunction = ProcPtr( Subtract )
   Print myFunction(2, 3)

   Function Add( x As Integer, y As Integer) As Integer
      Return x + y
   End Function

   Function Subtract( x As Integer, y As Integer) As Integer
      Return x - y
   End Function

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Procptr.

Differences from QB
   * New to FreeBASIC

See also
   * Sub
   * VarPtr
   * StrPtr
   * Pointers



--------------------------------------------------------- KeyPgProperty ----
Property

Declares or defines a property in a type or class

Syntax
   { Type | Class } typename
      Declare Property fieldname () [ ByRef ] As datatype
      Declare Property fieldname ( [ ByRef | ByVal ] new_value As datatype 
      )
      Declare Property fieldname ( [ ByRef | ByVal ] index As datatype ) [ 
      ByRef ] As datatype
      Declare Property fieldname ( [ ByRef | ByVal ] index As datatype, [ 
      ByRef | ByVal ] new_value As datatype )
   End { Type | Class }

   Property typename.fieldname () [ ByRef ] As datatype [ Export ]
      statements
   End Property

   Property typename.fieldname ( [ ByRef | ByVal ] new_value As datatype ) 
   [ Export ]
      statements
   End Property

   Property typename.fieldname (  [ ByRef | ByVal ] index As datatype ) [ 
   ByRef ] As datatype [ Export ]
      statements
   End Property

   Property typename.fieldname (  [ ByRef | ByVal ] index As datatype, [ 
   ByRef | ByVal ] new_value As datatype ) [ Export ]
      statements
   End Property

Parameters
   typename 
      name of the Type or Class
   fieldname 
      name of the property
   new_value 
      the value passed to property to be assigned
   index 
      the property index value

Description
   Property fields are used to get and set values of a Type or Class in the 
   same way as other data fields except instead of a simple assignment to a 
   field or a value retrieved from field, a procedure is executed.

   typename is the name of the type for which the Property method is 
   declared and defined.  Name resolution for typename follows the same 
   rules as procedures when used in a Namespace.

   A Property may optionally have one index parameter.  When indexed, 
   properties are accessed as fieldname(Index) = Value.
   A get-Property can also return a reference by specifying ByRef As 
   return_type.

   A hidden This parameter having the same type as typename is passed to 
   the property procedure.  This is used to access the fields of the Type 
   or Class.

   Note: A standard Property (get & set) does not work with combination 
   operators (as "+="). But a result byref get-Property (as more generally 
   any result byref function) works with combination operators.

   Note: When a get-Property is defined with one index parameter, the 
   fieldname= syntax can not be used to return a value. For such a get-
   Property, the property= syntax (in addition to the Return syntax) is 
   only the one allowed.

Example
   Type Vector2D
     As Single x, y
     Declare Operator Cast() As String
     Declare Property Length() As Single
     Declare Property Length( ByVal new_length As Single )
   End Type

   Operator Vector2D.cast () As String
     Return "(" + Str(x) + ", " + Str(y) + ")"
   End Operator

   Property Vector2D.Length() As Single
     Length = Sqr( x * x + y * y )
   End Property

   Property Vector2D.Length( ByVal new_length As Single )
     Dim m As Single = Length
     If m <> 0 Then
      '' new vector = old / length * new_length
      x *= new_length / m
      y *= new_length / m
     End If
   End Property

   Dim a As Vector2D = ( 3, 4 )

   Print "a = "; a
   Print "a.length = "; a.length
   Print

   a.length = 10

   Print "a = "; a
   Print "a.length = "; a.length

Output:

   a = (3, 4)
   a.length =  5

   a = (6, 8)
   a.length =  10

Property Indexing:
     '' True/False
   Namespace BOOL
     Const False = 0
     Const True = Not False
   End Namespace

   Type BitNum
     Num As UInteger
     
      '' Get/Set Properties each with an Index.
     Declare Property NumBit( ByVal Index As Integer ) As Integer
     Declare Property NumBit( ByVal Index As Integer, ByVal Value As Byte )
   End Type

     '' Get a bit by it's index.
   Property BitNum.NumBit( ByVal Index As Integer ) As Integer
     Return Bit( This.Num, Index )
   End Property

     '' Set a bit by it's index.
   Property BitNum.NumBit( ByVal Index As Integer, ByVal Value As Byte )

      '' Make sure index is in Integer range.
     If Index >= ( SizeOf(This.Num) * 8 ) Then
      Print "Out of uInteger Range!"
      Exit Property
     Else
      If Index < 0 Then Exit Property
     End If
     
     If Value = BOOL.FALSE Then
      This.Num = BitReset( This.Num, Index )
     End If
     
     If Value = BOOL.TRUE Then
      This.Num = BitSet( This.Num, Index )
     End If
     
   End Property

   Dim As BitNum Foo

   Print "Testing property indexing with data types:"
   Print "FOO Number's Value: " & Foo.Num

     '' Set the bit in the number as true.
   Foo.NumBit(31) = BOOL.TRUE
   Print "Set the 31st bit of FOO"

     '' Print to see if our bit has been changed.
   Print "FOO Number's Value: " & Foo.Num
   Print "FOO 31st Bit Set? " & Foo.NumBit(31)
   Sleep
   Print ""

Output:

   Testing Property indexing With Data types:
   FOO Number's Value: 0
   Set the 31st Bit of FOO
   FOO Number's Value: 2147483648
   FOO 31st Bit Set? -1

See also
   * Class
   * Type



----------------------------------------------------- KeyPgVisProtected ----
Protected: (Access Control)

Specifies protected member access control in a Type or Class

Syntax
   Type typename
      Protected:
         member declarations
   End Type

Parameters
   typename
      name of the Type or Class
   member declarations
      declarations for fields, functions, or enumerations

Description
   Protected: indicates that member declarations following it have 
   protected access.  Protected members are accessible only from inside a 
   member function for the Type or Class, and classes which are derived 
   from the Type or Class.

   member declarations following Protected: are protected until a different 
   access control specifier is given, like Private: or Public:.

   Members in a Type declaration are Public: by default if no member access 
   control specifier is given.

Example
   Type animal
     Dim As String animalName
     Protected:
      Dim As Integer serialNumber
   End Type

   Type dog Extends animal
     Dim As String masterName
     Declare Sub setSerialNumber ( ByVal number As Integer )
   End Type

   Sub dog.setSerialNumber ( ByVal number As Integer )
     '' This is OK. We're inside a member function of the derived type
     This.serialNumber = number
   End Sub

   Dim As dog d

   '' This is OK, animalName is public
   d.animalName = "Buddy"

   '' this would generate a compile error: 
   '' - serialNumber is protected and we're trying to access it outside its type and the derived type
   '' d.serialNumber = 123456789

   ' Example to illustrate the access control 'Protected' with a token provided by an admin right for an user right:
   '    - The 'admin_right' type extends the 'user_right' type.
   '    - Create directly an 'user_right' object is forbidden.
   '         ('default user_right.constructor' access and 'copy user_right.constructor' access are 'Protected')
   '    - The 'user_right' type has only the access right to get the token.
   '         ('user_right.token' get-property access is 'Public' and 'user_right.token' set-property access is 'protected')
   '    - The 'admin_right' type has the access rights to set and to get the token.
   '         ('admin_right.token' get-property access and 'admin_right.token' set-property access are 'Public')
   '
   ' An 'admin_right' object is created, and then a reference of type 'user_right' to this object is defined.
   '    (create directly an 'user_right' object is forbidden)

   Type user_right
     Public:
      Declare Property token () As String          '' 'Public' to authorize user_right token get
     Protected:
      Declare Constructor ()                       '' 'Protected' to forbid user_right object default-construction
      Declare Constructor (ByRef u As user_right)  '' 'Protected' to forbid user_right object copy-construction
      Declare Property token (ByRef s As String)   '' 'Protected' to forbid user_right token set
     Private:
      Dim As String user_right_token               '' 'Private' to forbid access from outside user_right
   End Type

   Constructor user_right ()  '' Default-constructor
   End Constructor

   Constructor user_right (ByRef u As user_right)  '' Protected copy-constructor
     This.user_right_token = u.user_right_token
   End Constructor

   Property user_right.token () As String  '' Public property user_right token get
     Return This.user_right_token
   End Property

   Property user_right.token (ByRef s As String)  '' Protected property user_right token set
     This.user_right_token = s
   End Property

   Type admin_right Extends user_right
     Public:
      Declare Property token () As String         '' 'Public' to authorize admin_right token get
      Declare Property token (ByRef s As String)  '' 'Public' to authorize admin_right token set
   End Type

   Property admin_right.token () As String  '' Public property admin_right token get
     Return Base.token                      '' 'Base.' to access to the base type property shadowed by this property name
   End Property

   Property admin_right.token (ByRef s As String)  '' Public property admin_right token set
     Base.token = s                                '' 'Base.' to access to the base type property shadowed by this property name
   End Property

   Dim As admin_right ar       '' Create an admin_right type object 'ar'
   ar.token = "fxm123456789"   '' admin_right set the token for user_right
   Print "'" & ar.token & "'"  '' admin_right get the user_right token
   Print

   Dim ByRef As user_right ur = ar  '' Create a user_right type reference 'ur' to the 'ar' instance of admin_right type
   Print "'" & ur.token & "'"       '' user_right get its token
   'ur.token = "fxm0"               '' Error: Illegal member access, USER_RIGHT.TOKEN.property.set (user_right cannot set its token)

   'Dim As user_right ur1       '' Error: The default constructor has no public access
   'Dim As user_right ur2 = ar  '' Error: Constructor has no public access

   Sleep

Dialect Differences
   * Available only in the -lang fb dialect.

Differences from QB
   * New to FreeBASIC

See also
   * Class
   * Private: (Access Control)
   * Public: (Access Control)
   * Type



------------------------------------------------------------- KeyPgPset ----
PSet

Plots a single pixel

Syntax
   PSet [target ,] [STEP] (x, y) [,color]

Parameters
   target
      specifies buffer to draw on.  
   STEP
      indicates that coordinates are relative
   (x, y)
      coordinates of the pixel.
   color
      the color attribute.

Description
   target specifies buffer to draw on.  target may be an image created with 
   ImageCreate or Get (Graphics).  If omitted, target defaults to the 
   screen's current work page.

   (x, y) are the coordinates of the pixel.  STEP if present, indicates 
   that (x, y) coordinates are relative to the graphics cursor position.  
   If omitted, (x, y) are relative to the upper left-hand corner of target. 
   The x and y coordinates are affected by the last call to the 
   View (Graphics) and Window statements, and respect the current clipping 
   region as set by the View (Graphics) statement.

   color specifies the color attribute, as an 8-bit palette index in 8 bpp 
   indexed modes, a 24-bit RGB value in 16 bpp modes (upper 8 bits of the 
   integer unused, limited precision of R,G,B), and a 32-bit RGB or RGBA 
   value in 32 bpp modes (upper 8 bits unused or holding Alpha). Note that 
   it does NOT accept a 16-bit value (5 bits R + 6 bits G + 5 bits B).  If 
   omitted, color defaults to the current foreground color.

   Speed note: while PSet provides valid results, it is quite slow to call 
   repeatedly due to the overhead of additional calculations and checks. 
   Much better performance can be achieved by using direct memory access 
   using the results obtained from ImageInfo and ScreenInfo/ScreenPtr.

Example
   ' Set an appropriate screen mode - 320 x 240 x 8bpp indexed color
   ScreenRes 320, 240, 8

   ' Plot a pixel at the coordinates 100, 100, Color 15. (white)
   PSet (100, 100), 15
   ' Confirm the operation.
   Locate 1: Print "Pixel plotted at 100, 100"
   ' Wait for a keypress.
   Sleep
    
   ' Plot another pixel at the coordinates 150, 150, Color 4. (red) 
   PSet (150, 150), 4
   ' Confirm the operation.
   Locate 1: Print "Pixel plotted at 150, 150"
   ' Wait for a keypress.
   Sleep
    
   ' Plot a third pixel relative to the second, Color 15. (white)
   ' This pixel is given the coordinates 60, 60. It will be placed
   ' at 60, 60 plus the previous coordinates (150, 150), thus plotting at 210, 210.
   PSet Step (60, 60), 15
   ' Confirm the operation.
   Locate 1: Print "Pixel plotted at 150 + 60, 150 + 60"
   ' Wait for a keypress
   Sleep

   ' Explicit end of program
   End

Differences from QB
   * target is new to FreeBASIC
   * In 16 bpp and 32 bpp modes, a 32-bit value is required instead of an 
     8-bit palette index

See also
   * Point - read out pixels
   * PReset
   * View (Graphics)
   * Window
   * Internal pixel formats



---------------------------------------------------------- KeyPgPsetGfx ----
PSet

Parameter to the Put graphics statement which selects PSet as the blitting 
method

Syntax
   Put [ target, ] [ STEP ] ( x,y ), source [ ,( x1,y1 )-( x2,y2 ) ], PSet

Parameters
   PSet
      Required.

Description
   The PSet method copies the source pixel values onto the destination 
   pixels.

   This is the simplest Put method. The pixels in the destination buffer 
   are directly overwritten with the pixels in the source buffer.  No 
   additional operations are done, and there are no color values that are 
   treated as transparent.  It has the same effect as PSetting each pixel 
   individually.

Example
   '' set up a screen: 320 * 200, 16 bits per pixel
   ScreenRes 320, 200, 16
   Line (0, 0)-(319, 199), RGB(0, 128, 255), bf

   '' set up an image with the mask color as the background.
   Dim img As Any Ptr = ImageCreate( 33, 33, RGB(255, 0, 255) )
   Circle img, (16, 16), 15, RGB(255, 255, 0),     ,     , 1, f
   Circle img, (10, 10), 3,  RGB(  0,   0, 0),     ,     , 2, f
   Circle img, (23, 10), 3,  RGB(  0,   0, 0),     ,     , 2, f
   Circle img, (16, 18), 10, RGB(  0,   0, 0), 3.14, 6.28

   Dim As Integer x = 160 - 16, y = 100 - 16

   '' Put the image with PSET
   Put (x, y), img, PSet

   '' free the image memory
   ImageDestroy img

   '' wait for a keypress
   Sleep

Differences from QB
   * None

See also
   * PSet
   * Put (Graphics)



-------------------------------------------------------------- KeyPgPtr ----
(Pointer | Ptr)

A variable declaration type modifier

Syntax
   Dim symbolname As DataType {Pointer | Ptr}

Description
   Declares a pointer variable.

   Operator @ (Address Of) operator or VarPtr are used to take the address 
   of a variable. The Operator * (Value Of) operator is used to dereference 
   the pointer, that is, access the actual value stored in the memory 
   location the pointer is pointing at.

Example
   ' Create the pointer.
   Dim p As Integer Ptr

   ' Create an integer value that we will point to using pointer "p"
   Dim num As Integer = 98845

   ' Point p towards the memory address that variable "num" occupies.
   p = @num

   ' Print the value stored in memory pointed to by pointer "p"
   Print "Pointer 'p' ="; *p
   Print 

   ' Print the actual location in memory that pointer "p" points at.
   Print "Pointer 'p' points to memory location:"
   Print p

   Dim p As ZString Pointer
   Dim text As String
   text = "Hello World!"
   p = StrPtr(text) + 6
   Print text
   Print *p

   '' Output:
   '' Hello World!
   '' World!

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Pointer or __Ptr.

Differences from QB
   * New to FreeBASIC

See also
   * Allocate



----------------------------------------------------------- KeyPgPublic ----
Public

Specifies a procedure having external linkage.

Syntax
   Public Sub procedure_name [cdecl|stdcall|pascal] [Overload] [Alias 
   "external_name"] [([parameter_list])] [Constructor [priority]] [Static] 
   [Export]
      ..procedure body..
   End Sub

   Public Function procedure_name [cdecl|stdcall|pascal] [Overload] [Alias 
   "external_name"] [([parameter_list])] [ ByRef ] As return_type  [Static] 
   [Export]
      ..procedure body..
   End Function

Description
   In procedure definitions (forbidden at declaration line level), Public 
   specifies that a procedure has external linkage, meaning its name is 
   visible to external modules. If Public or Private is not specified, a 
   procedure is defined as if Public was specified.

Example
   Private Sub i_am_private
   End Sub

   Public Sub i_am_public
   End Sub

Differences from QB
   * New to FreeBASIC

See also
   * Public: (Access Control)
   * Private
   * Option Private
   * Sub
   * Function



-------------------------------------------------------- KeyPgVisPublic ----
Public: (Access Control)

Specifies public member access control in a Type or Class

Syntax
   Type typename
      Public:
         member declarations
   End Type

Parameters
   typename
      name of the Type or Class
   member declarations
      declarations for fields, functions, or enumerations

Description
   Public: indicates that member declarations following it have public 
   access.  Public members are accessible with any usage of the Type or 
   Class.

   member declarations following Public: are public until a different 
   access control specifier is given, like Private: or Protected:

   Members in a Type declaration are Public: by default if no member access 
   control specifier is given.

Example
   Type testing
     Private:
      nome As String
     Public:
      number As Integer
     Declare Sub setNome( ByRef newnome As String )
   End Type

   Sub testing.setnome( ByRef newnome As String )
     this.nome = newnome 
   End Sub

   Dim As testing myVariable

   '' We can access these members anywhere since
   '' they're public
   myVariable.number = 69 ''
   myVariable.setNome( "FreeBASIC" )

Dialect Differences
   * Available only in the -lang fb dialect.

Differences from QB
   * New to FreeBASIC

See also
   * Class
   * Private: (Access Control)
   * Protected: (Access Control)
   * Public
   * Type



------------------------------------------------------ KeyPgPutgraphics ----
Put (Graphics)

Copies an image on to another image or screen

Syntax
   Put [target, ] [ [STEP](x, y), source [, (x1, y1)-[STEP](x2, y2) ] [, 
   method [, ( alphaval|value|blender [, param]) ] ]

Parameters
   target
      is the address of the buffer where the image is to be drawn. If it's 
      omitted, the image gets blitted to screen. See below.
   [STEP](x, y)
      specify offsets from the upper-left corner of the destination buffer, 
      or screen, that the image gets drawn to.  STEP indicates that (x, y) 
      offsets are relative to the current graphics cursor position.
   source
      is the address of the buffer of the image to be drawn. See below.
   (x1, y1)-[STEP](x2, y2)
      specify a rectangular area in the source buffer to draw. If omitted, 
      the entire buffer is drawn. STEP indicates that x2 and y2 are 
      relative to x1 and y1, respectively.
   method
      specifies the method used to draw the image to the destination 
      buffer, and can be any one of the following (the default method is 
      XOR):

      Background-independent methods
         PSet : Source pixel values are copied without modification.
         PRESET : Source pixel values are 1's-complement negated before 
         being copied.
         Trans : Source pixel values are copied without modification. Does 
         not draw source pixels of mask color. See below.
      Background-dependent methods
         And : Destination pixels are bitwise Anded with source pixels. See 
         below.
         Or : Destination pixels are bitwise Ored with source pixels. See 
         below.
         Xor : Destination pixels are bitwise Xored with source pixels. See 
         below.
         Alpha : Source is blended with a transparency factor specified 
         either in the value parameter, or in the image's individual 
         pixels.  See below.
         Add: Source is multiplied by a value and added with saturation to 
         the destination. See below.
         Custom : Uses a user-defined function to perform blending the 
         source with the destination. See below.

   value
      is a 0..255 value specifying the transparency value for an ADD or 
      ALPHA method blit.
   blender 
      specifies the address of a user-defined function to be called in a 
      CUSTOM method blit. See below.
   param 
      specifies a parameter to pass to the custom blender.

Description
   The Put statement can be used to draw an image onto another image or 
   screen. The x and y coordinates are affected by the last call to the View
   and Window statements, and plotted image respects the current clipping 
   region set by last call to the View statement. The source image can 
   overflow the destination buffer or screen (then the copied image is 
   clipped accordingly).

   Valid Image Buffers
      The source and target image buffers must be valid image buffers. 
      Valid image buffers are created using the Get or ImageCreate 
      statements. Valid image buffers can be specified in a Put statement 
      using an array name with optional index (but never with empty 
      parentheses), or a pointer with optional index.

   Drawing methods
      Depending on the method used, the existing pixel values in the 
      destination buffer are used to calculate the pixel values that are 
      actually drawn. The PSET, PRESET and TRANS methods do not use the 
      destination buffer for calculating final pixel values, while the AND, 
      OR, XOR, ALPHA and ADD methods do. Images that are drawn with these 
      latter methods will look differently depending on the content of the 
      destination buffer.

   Different pixel formats
      The pixel format of an image buffer must be compatible with the 
      current graphics mode color depth; that is, if you acquire an image 
      using Get and you later change screen mode via the Screen statement, 
      the image data may not be valid in the new graphics mode, and you may 
      not be able to draw it on the screen. You should note however that 
      you will always be able to draw image buffers onto other image 
      buffers via Put as long as these buffers were created with the same 
      depth.

      The AND, OR and XOR methods produce different results depending on 
      the current color depth, as pixels are stored in different formats; 
      see Internal pixel formats for details.

   Mask Color
      The TRANS, ALPHA and ADD methods do not draw pixels in the source 
      image that use the mask color. The mask color depends on target 
      (being it an image buffer or the screen) depth: in depths up to 8 bpp 
      (paletted modes) it is equal to color index 0, while in hi/truecolor 
      depths (16 and 32 bpp) it is equal to magenta, which is RGB(255, 0, 
      255). Note that in 32 bpp modes the alpha value of a color does not 
      affect the identification of the transparent color; only the lower 24 
      bits are used to identify it. See Internal pixel formats for details. 
      

   Alpha drawing
      The ALPHA method can be used in two modes. If the value parameter is 
      specified, this is used to specify the level of transparency for the 
      whole image to be drawn; a value of 0 will draw a completely 
      transparent image, whereas a value of 255 will draw a completely 
      solid one. This mode works only when drawing onto hi/truecolor 
      targets (16 and 32 bpp).
      If the value parameter is omitted, the ALPHA method will take the 
      alpha level value on a per-pixel basis, allowing to draw images with 
      an alpha channel (certain parts of the image can be made more or less 
      transparent than others). This mode works only with 32 bpp image 
      buffers, as this is the only color depth that allows for an embedded 
      alpha value in each pixel.

   Dealing with the alpha channel
      Normally Put only allows to draw image buffers onto targets with the 
      same depth, but there is an exception. When drawing an 8 bpp image 
      buffer onto a 32 bpp target and the ALPHA method is used, the 8 bpp 
      source image is drawn into the alpha channel of the 32 bpp target. 
      This allows to easily set the whole alpha channel of an image without 
      having to deal with low level access of its pixel data.

   Custom Blend Function
      The CUSTOM method uses a user-defined function to calculate the final 
      pixel values to be drawn to the destination buffer. This function 
      will be called once for every pixel of the source image, and will 
      receive the source and destination pixel values, and a data pointer 
      passed by the Put function. The pixel value returned will be the 
      value used to draw to the destination buffer. The function has the 
      form:

      Declare Function identifier ( ByVal source_pixel As UInteger, ByVal 
      destination_pixel As UInteger, ByVal parameter As Any Ptr) As UInteger
         identifier is the name of the function. Can be anything.
         source_pixel is the current pixel value of the source image.
         destination_pixel is the current pixel value of the destination 
         image.
         parameter is the parameter that is passed by the Put command.  It 
         should be a data Pointer.  If omitted, its value will be zero.

Example
   The following program gives a simple example of how to Put an image to 
   the screen, including setting up an image buffer, and freeing its memory 
   after.
   '' set up the screen and fill the background with a color
   ScreenRes 320, 200, 32
   Paint (0, 0), RGB(64, 128, 255)

   '' set up an image and draw something in it
   Dim img As Any Ptr = ImageCreate( 32, 32, RGB(255, 0, 255) )
   Circle img, (16, 16), 15, RGB(255, 255, 0),     ,     , 1, f
   Circle img, (10, 10), 3,  RGB(  0,   0, 0),     ,     , 2, f
   Circle img, (23, 10), 3,  RGB(  0,   0, 0),     ,     , 2, f
   Circle img, (16, 18), 10, RGB(  0,   0, 0), 3.14, 6.28

   '' PUT the image in the center of the screen
   Put (160 - 16, 100 - 16), img, Trans

   '' free the image memory
   ImageDestroy img

   '' wait for a keypress
   Sleep

   The following example shows how to allocate memory for an image, draw 
   that image using various methods, including a custom blender, and free 
   the memory for the image:
   Declare Function checkered_blend( ByVal src As UInteger, ByVal dest As UInteger, ByVal param As Any Ptr ) As UInteger

      Screen 14, 32                                   '' set 320*240*32 gfx mode
      
      Dim As Any Ptr sprite
      Dim As Integer counter = 0
      
      sprite = ImageCreate( 32, 32 )                  '' allocate memory for 32x32 sprite
      
      Line sprite, ( 0, 0 )-( 31, 31 ), RGBA(255, 0, 0, 64), bf  '' draw a sprite ...
      Line sprite, ( 4, 4 )-( 27, 27 ), RGBA(255, 0, 0, 192), bf
      Line sprite, ( 0, 0 )-( 31, 31 ), RGB(0, 255, 0), b
      Line sprite, ( 8, 8 )-( 23, 23 ), RGBA(255, 0, 255, 64), bf
      Line sprite, ( 1, 1 )-( 30, 30 ), RGBA(0, 0, 255, 192)
      Line sprite, ( 30, 1 )-( 1, 30 ), RGBA(0, 0, 255, 192)
      
      Cls
      Dim As Integer i : For i = 0 To 63              '' draw the background
        Line( i,0 )-( i,240 ), RGB( i * 4, i * 4, i * 4 )
      Next i
      
      '' demonstrate all drawing methods ...
      Put( 8,14 ), sprite, PSet
      Put Step( 16,20 ), sprite, PReset
      Put Step( -16,20 ), sprite, And
      Put Step( 16,20 ), sprite, Or
      Put Step( -16,20 ), sprite, Xor
      Put Step( 16,20 ), sprite, Trans
      Put Step( -16,20 ), sprite, Alpha, 96
      Put Step( 16,20 ), sprite, Alpha
      Put Step( -16,20 ), sprite, Add, 192
      Put Step( 16,20 ), sprite, Custom, @checkered_blend, @counter
      
      '' print a description near each demo
      Draw String (100, 26), "<- pset"
      Draw String Step (0, 20), "<- preset"
      Draw String Step (0, 20), "<- and"
      Draw String Step (0, 20), "<- or"
      Draw String Step (0, 20), "<- xor"
      Draw String Step (0, 20), "<- trans"
      Draw String Step (0, 20), "<- alpha (uniform)"
      Draw String Step (0, 20), "<- alpha (per pixel)"
      Draw String Step (0, 20), "<- add"
      Draw String Step (0, 20), "<- custom"
      
      ImageDestroy( sprite )                          '' free allocated memory for sprite
      Sleep : End 0

   '' custom blender function: chequered put
   Function checkered_blend( ByVal src As UInteger, ByVal dest As UInteger, ByVal param As Any Ptr ) As UInteger
      Dim As Integer Ptr counter
      Dim As UInteger pixel
      
      counter = Cast(Integer Ptr, param)
      pixel = IIf(((*counter And 4) Shr 2) Xor ((*counter And 128) Shr 7), src, dest)
      *counter += 1
      Return pixel
   End Function

Differences from QB
   * target is new to FreeBASIC
   * The TRANS, ALPHA, ADD and CUSTOM methods are new to FreeBASIC
   * FB uses a different image format internally, which is unsupported by 
     QB
   * QB throws a run-time error instead of clipping out-of-bounds images
   * In QB, only arrays can be specified as source images

See also
   * Put (File I/O)
   * Get (Graphics)
   * ImageCreate
   * Alpha
   * Internal pixel formats



-------------------------------------------------------- KeyPgPutfileio ----
Put (File I/O)

Writes data from a buffer to a file

Syntax
   Put #filenum As Long, [position As LongInt], data As Any [, amount As 
   UInteger]
   Put #filenum As Long, [position As LongInt], data As String
   Put #filenum As Long, [position As LongInt], data() As Any

Usage
   Put #filenum, position, data [, amount]
   varres = Put (#filenum, position, data [, amount])

Parameters
   filenum
      The value passed to Open when the file was opened.
   position
      Is the position where Put must start in the file. If the file was 
      opened For Random, the position is in records, else it is given in 
      bytes. If omitted, writing starts at the present file pointer 
      position.  The position is 1-based: i.e. the first record or byte of 
      a file is at position 1.
      If position is omitted or zero (0), file writing will start from the 
      current file position.
   data
      Is the buffer where data is written from. It can be a numeric 
      variable, a string, an array or a user-defined type. The operation 
      will try to transfer to disk the complete variable, unless amount is 
      given.
      When putting arrays, data should be followed by an empty pair of 
      brackets: '()'.  Put will write all of the data in the array.  amount 
      is not allowed.
      When putting Strings, the number of bytes written is the same as the 
      number of bytes in the string data.  amount is not allowed.
      Note: If you want to write values from a buffer, you should NOT pass 
      a pointer to the buffer; instead you should pass the first variable 
      in the buffer.  (This can be done by dereferencing the pointer with 
      Operator * (Value Of).) If you pass a pointer directly, then Put will 
      put the memory from the pointer variable, not the memory it points 
      to.
   amount
      Makes Put write to file amount consecutive variables to the file - 
      i.e. it writes ( amount * SizeOf(data) ) bytes of data, starting at 
      data's location in memory, into the file.  If amount is omitted it 
      defaults to 1, meaning that Put just writes a single variable.

Return Value
   Put() returns a 32 bit Long: 0 on success; nonzero on error. "disk full" 
   is considered as an error, and results in return code 3. An "exact" 
   amount of data written before is not available, and wouldn't be really 
   useful anyway. 

Description
   Writes binary data from a buffer variable to a file opened in Binary or 
   Random mode.

   Put can be used as a function, and will return 0 on success or an error 
   code on failure.	

   For files opened in Random mode, the size in bytes of the data to write 
   must match the specified record size.

Example
   ' Create variables for the file number, and the number to put
   Dim As Integer f
   Dim As Long value

   ' Find the first free file number
   f = FreeFile()

   ' Open the file "file.ext" for binary usage, using the file number "f"
   Open "file.ext" For Binary As #f

     value= 10

     ' Write the bytes of the integer 'value' into the file, using file number "f"
     ' starting at the beginning of the file (position 1)
     Put #f, 1, value

   ' Close the file
   Close #f

   ' Create an integer array
   Dim buffer(1 To 10) As Integer
   For i As Integer = 1 To 10
      buffer(i) = i
   Next

   ' Find the first free file file number
   Dim f As Integer
   f = FreeFile()

   ' Open the file "file.ext" for binary usage, using the file number "f"
   Open "file.ext" For Binary As #f
   ' Write the array into the file, using file number "f"
   ' starting at the beginning of the file (position 1)
   Put #f, 1, buffer()

   ' Close the file
   Close #f

   Dim As Byte Ptr lpBuffer
   Dim As Integer hFile, Counter, Size

   Size = 256

   lpBuffer = Allocate(Size)
   For Counter = 0 To Size-1
     lpBuffer[Counter] = (Counter And &HFF)
   Next

   ' Get free file file number
   hFile = FreeFile()

   ' Open the file "test.bin" in binary writing mode
   Open "test.bin" For Binary Access Write As #hFile

     ' Write 256 bytes from the memory pointed to by lpBuffer
     Put #hFile, , lpBuffer[0], Size

   ' Close the file
   Close #hFile

   ' Free the allocated memory
   Deallocate lpBuffer

Differences from QB
   * Put can write full arrays as in VB or, alternatively, write a 
     multiple of the data size from buffer's memory location.
   * Put can be used as a function in FB, to find the success/error code 
     returned without having to use error handling procedures.

See also
   * Put (Graphics) different usage of same keyword 
   * Get (File I/O)
   * Open
   * Close
   * Random
   * Binary
   * FreeFile




============================================================================
    R

----------------------------------------------------------- KeyPgRandom ----
Random

Specifies file or device to be opened for random access mode

Syntax
   Open filename for Random [Access access_type] [Lock lock_type] as [#]
   filenum [Len = record_length]

Parameters
   filename
      file name to open
   access_type
      indicates whether the file may be read from, written to or both
   lock_type
      locking to be used while the file is open
   filenum
      unused file number to associate with the open file
   record_length
      the size of the record used for the file

Description
   Opens a file or device for reading and/or writing binary data in the 
   given file filenum, with records of size record_length.
   If the file does not exist, a new file will be created, otherwise any 
   data existing in the file is preserved by Open.  The file pointer is 
   initialized by Open at the start of the file, at record number 1. File 
   operations move the file position in steps of record_length bytes.
   This file mode uses an user-defined Type buffer variable to read/write 
   full records in a file. The buffer variable uses to include several 
   fields.
   The data is saved in binary mode, in the same internal format FreeBASIC 
   uses, by means of Get # and Put #.

   filename must be string expression resulting in a legal file name in the 
   target OS, without wildcards. The file will be sought for in the present 
   directory, unless a path is given.

   Access_type - By default Random mode allows to both read and write the 
   file, unless an Access type is specified, it must be one of:
      * Read - the file is opened for input only
      * Write - the file is opened for output only
      * Read Write - the file is opened for input and output (the default)

   Lock_type indicates the way the file is locked for other processes 
   (users or threads), it is one of:
      * Shared - The file can be freely accessed by other processes     
      * Lock Read - The file can't be opened simultaneously for reading
      * Lock Write - The file can't be opened simultaneously for writing
      * Lock Read Write - The file cannot be opened simultaneously by 
        other processes.
      If no lock type is stated, the file will be Shared for other threads 
      of the program and Lock Read Write for other programs.
      Lock and Unlock can be used to restrict temporally access to parts of 
      a file.

   filenum is a valid FreeBASIC file number (in the range 1..255) not being 
   used for any other file presently open. This number identifies the file 
   for the rest of file operations. A free file number can be found using 
   the FreeFile function.

   record_length is the amount of bytes the file pointer will move for each 
   individual Get and Put, it must match the size of the buffer variable 
   used when Getting and Putting data. If omitted, it defaults to 128.

Example
   '' This example generates a test file and then lets you view random records
   '' that are read live from the file.

   Type Entry
      slen As Byte
      sdata As String * 10
   End Type

   Dim u As Entry
   Dim s As String

   Open "testfile" For Random As #1 Len = SizeOf(Entry)

   '' Write out 9 records with predefined data
   For i As Integer = 1 To 9
      Read s
      u = Type( Len(s), s )
      Put #1, i, u
   Next

   Data ".,-?!'@:", "abc",      "def"
   Data "ghi",      "jkl",      "mno"
   Data "pqrs",     "tuv",      "wxyz"

   '' Let the user view records by specifying their index number
   Do
      Dim i As Integer
      Input "Record number: ", i
      If i < 1 Or i > 9 Then Exit Do

      Get #1, i, u
      Print i & ": " & Left( u.sdata, u.slen )
      Print
   Loop

   Close #1

   Type ScoreEntry Field = 1
      As String * 20 Name
      As Single score
   End Type

   Dim As ScoreEntry entry

   '' Generate a fake boring highscore file
   Open "scores.dat" For Random Access Write As #1 Len = SizeOf(entry)
   For i As Integer = 1 To 10
      entry.name = "Player " & i
      entry.score = i
      Put #1, i, entry
   Next
   Close #1

   '' Read out and display the entries
   Open "scores.dat" For Random Access Read As #1 Len = SizeOf(entry)
   For i As Integer = 1 To 10
      Get #1, i, entry
      Print i & ":", entry.name, Str(entry.score), entry.score
   Next
   Close #1

Differences from QB
   * Care must be taken with dynamic or fixed length strings inside user 
     defined types (UDT), see the warning at Type.
   * The keyword Field can only be used with Type to specify the packing 
     of the UDT. 

See also
   * Open
   * Binary
   * Get #
   * Put #



-------------------------------------------------------- KeyPgRandomize ----
Randomize

Seeds the random number generator

Syntax
   Declare Sub Randomize ( ByVal seed As Double = -1.0,  ByVal algorithm As 
   Long = 0 )

Usage
   Randomize [ seed ][, algorithm ]

Parameters
   seed
      A Double seed value for the random number generator.  If omitted, a 
      value based on Timer will be used instead.
   algorithm
      An integer value to select the algorithm. If omitted, the default 
      algorithm for the current language dialect is used.

Description
   Sets the random seed that helps Rnd generate random numbers, and selects 
   the algorithm to use. Valid values for algorithm are:
      0 - Default for current language dialect. This is algorithm 3 in the 
      -lang fb dialect, 4 in the -lang qb dialect and 1 in the -lang fblite 
      dialect.
      1 - Uses the C runtime library's rand() function. This will give 
      different results depending on the platform.
      2 - Uses a fast implementation. This should be stable across all 
      platforms, and provides 32-bit granularity, reasonable degree of 
      randomness.
      3 - Uses the Mersenne Twister. This should be stable across all 
      platforms, provides 32-bit granularity, and gives a high degree of 
      randomness.
      4 - Uses a function that is designed to give the same random number 
      sequences as QBASIC. This should be stable across all platforms, and 
      provides 24-bit precision, with a low degree of randomness.
      5 - Available on Win32 and Linux, using system features (Win32 Crypto 
      API, Linux /dev/urandom) to provide cryptographically random numbers. 
      If those system APIs are unavailable, algorithm 3 will be used 
      instead.

      For any given seed, each algorithm will produce a specific, 
      deterministic sequence of numbers for that seed.  If you want each 
      call to Randomize to produce a different sequence of numbers, a seed 
      that is not quite predictable should be used - for example, the value 
      returned from Timer.  Omitting the seed parameter will use a value 
      based on this.
      Note: using the Timer value directly as a parameter will produce the 
      same seed if used more than once in the same second.  However, it is 
      generally not worth calling Randomize twice with unpredictable seeds 
      anyway, because the second sequence will be no more random than the 
      first.  In most cases, the Mersenne twister should provide a 
      sufficiently random sequence of numbers, without requiring reseeding 
      between Rnd calls.

      When you call Randomize with the QB compatible algorithm, part of the 
      old seed is retained.  This means that if you call Randomize several 
      times with the same seed, you will not get the same sequence each 
      time.  To get a specific sequence in QB compatible mode, set the seed 
      by calling Rnd with a negative parameter.

Example
   '' Seed the RNG to the method using C's rand()
   Randomize , 1

   '' Print a sequence of random numbers
   For i As Integer = 1 To 10
      Print Rnd
   Next

Dialect Differences
   The default algorithm used depends on the current dialect in use:
      * With the -lang fb dialect, a 32 bit Mersenne Twister function with 
        a granularity of 32 bits is used.
      * With the -lang qb dialect, a function giving the same output as Rnd
        in QB is used. The granularity is 24 bits.
      * With the -lang deprecated and -lang fblite dialects, the function 
        in the C runtime available in the system is used. The function has 
        a granularity of 15 bits in Win32, and 32 bits in Linux and DOS.

Differences from QB
   * The algorithm parameter is new to FreeBASIC.
   * QBASIC only had one algorithm (replicated in FB in algorithm number 4
     , and set as the default in the -lang qb dialect).

See also
   * Rnd
   * Language dialects



------------------------------------------------------------- KeyPgRead ----
Read

Reads values stored with the Data statement.

Syntax
   Read variable_list

Description
   Reads data stored in the application with the Data command. 

   The elements of the variable_list must be of basic types, numeric, 
   strings or elements of arrays and user defined types.

   All the Data statements in the program behave as a single list, after 
   the last element of one Data statement is read, the first element of the 
   following Data statement will be read.
   The program should not attempt to Read after the last Data element.  The 
   results are (in all dialects) undefined,  and the program may crash 
   (Page Fault).

   Data constants can only be of simple types (numeric or string).  A 
   string read into a numeric variable will be evaluated by the Val 
   function.

   The "Restore label" statement makes the first Data item after label the 
   next item to be read, allowing the user to choose specific sections of 
   data to be read.

Example
   ' Create an array of 5 integers and a string to hold the data.
   Dim As Integer h(4)
   Dim As String hs
   Dim As Integer readindex

   ' Set up to loop 5 times (for 5 numbers... check the data)
   For readindex = 0 To 4

     ' Read in an integer.
     Read h(readindex)

     ' Display it.
     Print "Number" ; readindex ; " = " ; h(readindex)

   Next readindex

   ' Spacer.
   Print

   ' Read in a string.
   Read hs

   ' Print it.
   Print  "String = " + hs

   ' Await a keypress.
   Sleep

   ' Exit program.
   End

   ' Block of data.
   Data 3, 234, 4354, 23433, 87643, "Bye!"

Dialect Differences
   * None in syntax and usage of Read
   * See the Data page for more information on differences in storing the 
     data

Differences from QB
   * None in syntax and usage of Read
   * See the Data page for more information on differences in storing the 
     data

See also
   * Data
   * Restore



--------------------------------------------------------- KeyPgReadFile ----
Read (File Access)

File access specifier

Syntax
   Open filename As String For Binary Access Read As #filenum As Integer

Description
   Specifier for the Access clause in the Open statement.  Read specifies 
   that the file is accessible for input.

Example
   See example at Access

Differences from QB
   * None known.

See also
   * Access
   * Open



---------------------------------------------------- KeyPgReadWriteFile ----
Read Write (File Access)

File access specifier

Syntax
   Open filename As String For Binary Access Read Write As #filenum As 
   Integer

Description
   Specifier for the Access clause in the Open statement.  Read Write 
   specifies that the file is accessible for both input and output.

Example
   See example at Access

Differences from QB
   * None known.

See also
   * Access
   * Open



------------------------------------------------------- KeyPgReallocate ----
Reallocate

Reallocates storage for an existing reserved block of memory

Syntax
   Declare Function Reallocate cdecl ( ByVal pointer As Any Ptr, ByVal 
   count As UInteger ) As Any Ptr

Usage
      result = Reallocate( pointer, count )

Parameters
   pointer
      The address of allocated memory to be reallocated.
   count
      The number of bytes, in total, to be reallocated.

Return Value
   The address of the reallocated memory. A null (0) pointer is returned if 
   reallocation was unsuccessful, and the original memory pointed to by 
   pointer remains unchanged.

Description
   Attempts to reallocate, or resize, memory previously allocated with 
   Allocate or CAllocate. The contents of the buffer are preserved, 
   although if count is less than the original size of the memory block, 
   the buffer will be truncated.  If the size is increased, the added 
   memory range is not initialized to anything.

   When using Reallocate, the result pointer must be saved to prevent a 
   potential memory leak, because the original pointer may no longer be 
   valid after reallocation.  The value of the new pointer should be 
   checked - if it is 0, the reallocation has failed - the original pointer 
   remains valid, and the amount of memory allocated to it has not changed.

   Reallocated memory must be freed with Deallocate when no longer needed.

   If pointer is null (0), then ReAllocate behaves identically to Allocate. 
   If pointer is valid and count is null (0), then ReAllocate behaves 
   similar to Deallocate and a null (0) pointer is returned.

   If the memory has previously been deallocated by a call to Deallocate or 
   ReAllocate, the behavior is undefined.

   When manually allocating memory for String descriptors (or Udts that 
   contain one), if count is larger than the original size of the memory 
   block, the new extra memory range must be explicitly cleared to zeroes 
   before the first string use (for example, using Clear).  Otherwise 
   accessing the string will cause undefined results (trying to write or 
   read at a random place in memory, or trying to deallocate a random 
   pointer).

   This function is not part of the FreeBASIC runtime library, it is an 
   alias for the C runtime library's realloc, so it's not guaranteed to be 
   thread safe in all platforms.

   NOTE: Reallocating a pointer inside an object function, when that 
   pointer contains the parent object of the function, is undefined, and 
   will likely result in horrible crashes.

Example
   Dim a As Integer Ptr, b As Integer Ptr, i As Integer

   a = Allocate( 5 * SizeOf(Integer) )   ' Allocate memory for 5 integers

   If a = 0 Then Print "Error Allocating a": End

   For i = 0 To 4
     a[i] = (i + 1) * 2   ' Assign integers to the buffer
   Next i

   b = Reallocate( a, 10 * SizeOf(Integer) )   ' Reallocate memory for 5 additional integers

   If b <> 0 Then

      a = b   ' Discard the old pointer and use the new one

      For i = 5 To 9
        a[i] = (i + 1) * 2   ' Assign more integers to the buffer
      Next i

      For i = 0 To 9   ' Print the integers
        Print i, a[i]
      Next i
      Print

   Else '' Reallocate failed, memory unchanged

      Print "Error Reallocating a"

      For i = 0 To 4   ' Print the integers
        Print i, a[i]
      Next i
      Print

   End If

   Deallocate a   ' Clean up

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Reallocate.

Differences from QB
   * New to FreeBASIC

See also
   * Allocate
   * CAllocate
   * Deallocate



------------------------------------------------------------ KeyPgRedim ----
ReDim

Defines or resizes a variable-length array

Syntax
   Declaring a Dynamic Array:
      ReDim [ Shared ] symbolname([subscript [, ...]]) As datatype [, ...]
      ReDim [ Shared ] As datatype symbolname([subscript [, ...]]) [, ...]

   Resizing a Dynamic Array:
      ReDim [ Preserve ] symbolname([subscript [, ...]]) [, ...]

Parameters
   Shared
      Specifies shared (file-scope) access to the array throughout the 
      module.
   Preserve
      When used with an existing array, the contents of the array will be 
      preserved during the resize. Note that in some cases Preserve will 
      not preserve data at its original index, see below.
   symbolname
      A new or existing array id.
   subscript: [ lowerbound To ] upperbound
      The lower and upper bound range for a dimension of the array. Lower 
      bound defaults to zero (0), or the default Base, if not specified.
   datatype
      The type of elements contained in the array.

Description
   ReDim can be used to define new variable-length arrays, or resize 
   existing variable-length arrays while keeping the same number of 
   dimensions. ReDim always produces variable-length arrays, so, unlike Dim
   , variable-length arrays can be defined with constant subscripts.

   When defining a new variable-length array, its elements are default 
   constructed. For simple data types like Integer or Double, the elements 
   are initialized to zero (0). For user-defined types with a default 
   constructor, that will be called.

   When used with in a user-defined type, ReDim creates variable-length 
   arrays while being able to pre-size them with constant subscripts.

   NOTES: 
      * ReDim Preserve may not work as expected in all cases:
         * Preserve's current behavior is to keep the original data 
           contiguous in memory, and only expand or truncate the size of 
           the memory (if resizing is not possible, the whole original data 
           block is first shifted to another memory location).
         * Its behavior (with a single dimension) is well-defined only 
           when the upper bound is changed.  If the lower bound is changed, 
           the current result is that the data is in effect shifted to 
           start at the new lower bound.
         * With multiple dimensions, only the upper bound of only the 
           first dimension may be safely increased.  If the first dimension 
           is reduced, the existing mappable data may be lost. If 
           lower-order dimensions are resized at all, the effects can be 
           hard to predict (because multidimensional arrays are stored in 
           row-major order : values differing only in the last index are 
           contiguous).
      * ReDim cannot be used on fixed-size arrays - i.e. arrays with 
        constant bounds made with Dim.  This includes the fixed-size arrays 
        contained in UDTs (user-defined Types).  This also includes 
        fixed-length arrays passed as parameters in a function.  FreeBASIC 
        cannot prevent you trying this at compile-time, but the results at 
        run-time will be undefined.
      * Using ReDim within a member procedure with an array that contains 
        the instance of the object class is undefined, and will [hopefully] 
        result in horrible crashes (if array data are shifted in memory, 
        the This reference becomes incoherent, similarly to a dangling 
        pointer).
      * For use of ReDim with a complex array expression (especially if 
        the array expression itself contains parentheses), the array 
        expression must be enclosed in parentheses in order to solve the 
        parsing ambiguity.

Example
   '' Define a variable-length array with 5 elements
   ReDim array(0 To 4) As Integer

   For index As Integer = LBound(array) To UBound(array)
      array(index) = index
   Next

   '' Resize a variable-length array with 10 elements 
   '' (the lower bound should be kept the same)
   ReDim Preserve array(0 To 9)

   Print "index", "value"
   For index As Integer = LBound(array) To UBound(array)
      Print index, array(index)
   Next

   This program will produce the following output:

   index         value
    0             0
    1             1
    2             2
    3             3
    4             4
    5             0
    6             0
    7             0
    8             0
    9             0

   '' Define a variable-length array
   Dim array() As Integer

   '' ReDim array to have 3*4 elements
   ReDim array(1 To 3, 1 To 4)

   Dim As Integer n = 1, i, j

   Print "3 * 4:"
   Print
   For i = LBound(array, 1) To UBound(array, 1)
      For j = LBound(array, 2) To UBound(array, 2)
         array(i, j) = n
         Print Using "##  "; array(i, j);
         n += 1
      Next
      Print
   Next
   Print

   '' ReDim Preserve array to have 4*4 elements, preserving the contents
   '' (only the first upper bound should be changed)
   ReDim Preserve array(1 To 4, 1 To 4)

   Print "4 * 4:"
   Print
   For i = LBound(array, 1) To UBound(array, 1)
      For j = LBound(array, 2) To UBound(array, 2)
         Print Using "##  "; array(i, j);
      Next
      Print
   Next
   Print

   '' ReDim Preserve array to have 2*4 elements, preserving but trancating the contents
   '' (only the first upper bound should be changed)
   ReDim Preserve array(1 To 2, 1 To 4)

   Print "2 * 4:"
   Print
   For i = LBound(array, 1) To UBound(array, 1)
      For j = LBound(array, 2) To UBound(array, 2)
         Print Using "##  "; array(i, j);
      Next
      Print
   Next
   Print

   This program will produce the following output:

   3 * 4:

    1   2   3   4
    5   6   7   8
    9  10  11  12

   4 * 4:

    1   2   3   4
    5   6   7   8
    9  10  11  12
    0   0   0   0

   2 * 4:

    1   2   3   4
    5   6   7   8

   '' Define a variable-length array as UDT field
   Type UDT
      Dim As Integer array(Any)
   End Type

   Dim As UDT u(0 To 3)

   '' For use of Redim with a complex array expression
   '' (especially if the array expression itself contains parentheses),
   '' the array expression must be enclosed in parentheses
   '' in order to solve the parsing ambiguity:
   ''    Redim u(0).array(0 To 9)
   ''    induces error 4: Duplicated definition, u in 'Redim u(0).array(0 To 9)'
   ReDim (u(0).array)(0 To 9)

Differences from QB
   * Preserve was in Visual Basic, but not in QBASIC.
   * Multi-dimensional arrays in FreeBASIC are in row-major order, rather 
     than column-major order.

See also
   * Common
   * Dim
   * Erase
   * Extern
   * LBound
   * Preserve
   * Shared
   * Static
   * UBound
   * Var



-------------------------------------------------------------- KeyPgRem ----
Rem

Indicates comments in the source code.

Syntax
   Rem comment

   ' Comment

   /' Multi-line
      comment '/

Description
   A source code line beginning with Rem indicates that the line is a 
   comment and will not be compiled.  

   The single quote character (') may also be used to indicate a comment 
   and may appear after other keywords on a source line.

   Multi-line comments are marked with the tokens /' and '/.  All text 
   between the two markers is considered comment text and is not compiled.

Example
   /' this is a multi line 
   comment as a header of
   this example '/

   Rem This Is a Single Line comment

   ' this is a single line comment

   ? "Hello" : Rem comment following a statement

   Dim a As Integer ' comment following a statement

   ? "FreeBASIC" : ' also acceptable 

   Dim b As /' can comment in here also '/    Integer

   #if 0
      This way of commenting Out code was
      required before version 0.16
   #endif

Differences from QB
   * Rem may also appear after other keywords on a source line in 
     FreeBASIC
   * Multiline comments are new to FreeBASIC

See also
   * #if



------------------------------------------------------------ KeyPgReset ----
Reset

Closes all open files, or resets standard I/O handles.

Syntax
   Declare Sub Reset ( )
   Declare Sub Reset ( ByVal streamno As Long )

Usage
   Reset
or
   Reset( streamno )

Parameters
   streamno
      The stream number to reset, 0 for stdin or 1 for stdout.

Description
   Reset, when called with no arguments, closes all disk files.

   Reset, when called with the streamno argument, will reset the redirected 
   or piped streams associated with stdin (0), or stdout (1).

Runtime errors:
   Reset(streamno) can set one of the following runtime errors:

   (1) Illegal function call
      * streamno was neither 0 nor 1

   (3) File I/O error
      * Resetting of stdin or stdout failed

Example
   Open "test.txt" For Output As #1
   Print #1, "testing 123"
   Reset

   Dim x As String

   '' Read from STDIN from piped input
   Open Cons For Input As #1
   While EOF(1) = 0
     Input #1, x
     Print """"; x; """"
   Wend
   Close #1

   '' Reset to read from the keyboard
   Reset(0)

   Print "Enter some text:"
   Input x

   '' Read from STDIN (now from keyboard)
   Open Cons For Input As #1
   While EOF(1) = 0
     Input #1, x
     Print """"; x; """"
   Wend
   Close #1

      Note: Under Windows, to specify to the program that data entry is 
      completed (transfer EOF), you can press CTRL+Z then press ENTER.

Differences from QB
   * None for Reset().
   * The Reset(streamno) usage is new to FreeBASIC.

See also
   * Close
   * Open
   * Open Cons
   * IsRedirected



---------------------------------------------------------- KeyPgRestore ----
Restore

Changes the next read location for values stored with the Data statement.

Syntax
   Restore [label]

Description
   Sets the next-data-to-read pointer to the first element of the first Data
   statement after the label.  The label must be contained in the same 
   module as the currently-executing code.  Restore alters the normal top 
   to bottom order in which Data are Read. It allows re-reading some Data 
   or using multiple sets of Data in a single module.	
   If label is omitted, the next-data-to-read pointer is set to the first 
   Data statement found in the module.

Example
   ' Create an 2 arrays of integers and a 2 strings to hold the data.
   Dim h(4) As Integer
   Dim h2(4) As Integer
   Dim hs As String
   Dim hs2 As String
   Dim read_data1 As Integer
   Dim read_data2 As Integer

   ' Set the data read to the label 'dat2:'
   Restore dat2

   ' Set up to loop 5 times (for 5 numbers... check the data)
   For read_data1 = 0 To 4

     ' Read in an integer.
     Read h(read_data1)

     ' Display it.
     Print "Bloc 1, number"; read_data1;" = "; h(read_data1)

   Next

   ' Spacer.
   Print

   ' Read in a string.
   Read hs

   ' Print it.
   Print  "Bloc 1 string = " + hs

   ' Spacers.
   Print
   Print

   ' Set the data read to the label 'dat1:'
   Restore dat1

   ' Set up to loop 5 times (for 5 numbers... check the data)
   For read_data2 = 0 To 4

     ' Read in an integer.
     Read h2(read_data2)

     ' Display it.
     Print "Bloc 2, number"; read_data2;" = "; h2(read_data2)

   Next

   ' Spacer.
   Print

   ' Read in a string.
   Read hs2

   ' Print it.
   Print  "Bloc 2 string = " + hs2

   ' Await a keypress.
   Sleep

   ' Exit program.
   End

   ' First block of data.
   dat1:
   Data 3, 234, 4354, 23433, 87643, "Bye!"

   ' Second block of data.
   dat2:
   Data 546, 7894, 4589, 64657, 34554, "Hi!"

Differences from QB
   * None

See also
   * Data
   * Read
   * Labels



----------------------------------------------------------- KeyPgResume ----
Resume

Error handling statement to resume execution after a jump to an error 
handler

Syntax
   Resume

Description
   Resume is used in the traditional QB error handling mechanism within an 
   error handler (called by On Error) to return execution to the line that 
   caused the error.  Usually this is used after the error has been handled 
   gracefully in order to try the previously erroneous operation again with 
   corrected data.

   Resume resets the Err value to 0

Example
   '' Compile with -lang fblite or qb

   #lang "fblite"

   Dim As Single i, j

   On Error Goto ErrHandler

   i = 0
   j = 1 / i ' this line causes a divide-by-zero error on the first try; execution jumps to ErrHandler label

   Print j ' after the value of i is corrected, prints 0.5

   End ' end the program so that execution does not fall through to the error handler again

   ErrHandler:

   i = 2
   Resume ' execution jumps back to 'j = 1 / i' line, which does not cause an error this time

Dialect Differences
   *  RESUME is not supported in the -lang fb dialect. Statements can be 
     used in its function form to return an error code
   If Open( "text" For Input As #1 ) <> 0 Then
     Print "Unable to open file"
   End If

 

Differences from QB
   * Does not accept line numbers or labels
   * Must compile with -ex or -exx option

See also
   * Err
   * Resume Next
   * Error Handling



------------------------------------------------------- KeyPgResumenext ----
Resume Next

Error handling statement to resume execution after a jump to an error 
handler

Syntax
   Resume Next

Description
   Resume Next is used in the traditional QB error handling mechanism 
   within an error handler (called by On Error) to return execution to the 
   line after the one that caused the error.  Usually this is used to avoid 
   executing the same line and causing the error again.

   Resume Next resets the Err value to 0

Example
   '' Compile with -lang fblite or qb

   #lang "fblite"

   Dim As Single i, j

   On Error Goto ErrHandler

   i = 0
   j = 5
   j = 1 / i ' this line causes a divide-by-zero error; execution jumps to ErrHandler label

   Print "ending..."

   End ' end the program so that execution does not fall through to the error handler again

   ErrHandler:

   Resume Next ' execution jumps to 'Print "ending..."' line, but j is now in an undefined state

Dialect Differences
   *  RESUME NEXT is not supported in the -lang fb dialect. Statements can 
     be used in its function form to return an error code
   If Open( "text" For Input As #1 ) <> 0 Then
     Print "Unable to open file"
   End If

 

Differences from QB
   * Must compile with -ex or -exx option

See also
   * Err
   * Resume
   * Error Handling



----------------------------------------------------------- KeyPgReturn ----
Return

Control flow statement to return from a procedure or GoSub.

Syntax
   Return expression
or
   Return [ label ]

Description
   Return is used to return from a procedure or return from a gosub GoSub.

   Because Return could mean return-from-gosub or return-from-procedure, 
   Option Gosub and Option Nogosub can be used to enable and disable GoSub 
   support.  When GoSub support is disabled, Return is then recognized as 
   return-from-procedure.  When GoSub support is enabled, Return is then 
   recognized as return-from-gosub.

   Return (from procedure) is used inside a procedure to exit the procedure 
   possibly with a return value:
      * A Sub cannot specify a return return value. Return is roughly 
        equivalent to the Exit Sub idiom.
      * In a Function, Return must specify its return value.  Return 
        expression is roughly equivalent to the Function = expression : Exit
        Function idiom.

   Return (from gosub) is used to return control back to the statement 
   immediately following a previous GoSub call. When used in combination 
   with GoSub, no return value can be specified.  If the optional label is 
   specified, execution continues at the specified label.  If no GoSub was 
   made, a runtime error is generated, and execution continues immediately 
   after Return.

   A GoSub should always have a matching Return statement.  However, if 
   Return (from gosub) is used where no GoSub was made, a run-time error is 
   generated.

Example
   '' GOSUB & RETURN example, compile with "-lang qb" or use "$lang" as below

   '$lang: "qb"

   Print "Let's Gosub!"
   GoSub MyGosub
   Print "Back from Gosub!"
   Sleep
   End

   MyGosub:
   Print "In Gosub!"
   Return

   '' Return from function

   Type rational              '' simple rational number type
      numerator As Integer
      denominator As Integer
   End Type

   '' multiplies two rational types
   Function rational_multiply( r1 As rational, r2 As rational ) As rational

      Dim r As rational
      '' multiply the divisors ...
      r.numerator   = r1.numerator   * r2.numerator
      r.denominator = r1.denominator * r2.denominator

      '' ... and return the result
      Return r

   End Function

   Dim As rational r1 = ( 6, 105 )   '' define some rationals r1 and r2
   Dim As rational r2 = ( 70, 4 )
   Dim As rational r3

   r3 = rational_multiply( r1, r2 )  '' multiply and store the result in r3

   '' display the expression
   Print r1.numerator & "/" & r1.denominator; " * ";
   Print r2.numerator & "/" & r2.denominator; " = ";
   Print r3.numerator & "/" & r3.denominator

Dialect Differences
   * In the -lang fb dialect Return always means return-from-procedure.
   * In the -lang qb dialect, Return means return-from-gosub by default 
     unless changed with Option Nogosub, in which case the compiler will 
     recognize Return as return-from-procedure.
   * In the -lang fblite dialect, Return means return-from-procedure by 
     default unless changed with Option Gosub, in which case the compiler 
     will recognize Return as return-from-gosub.

Differences from QB
   * None when using the -lang qb dialect.

See also
   * Sub
   * Function
   * GoSub
   * Option Gosub
   * Option Nogosub
   * Labels



-------------------------------------------------------------- KeyPgRgb ----
RGB

Computes a valid color value for hi/truecolor modes

Syntax
   #define RGB(r,g,b) ((CUInt(r) Shl 16) Or (CUInt(g) Shl 8) Or CUInt(b) Or 
   &hFF000000)

Usage
   result = RGB(red, green, blue)

Parameters
   red
      red color component value
   green
      green color component value
   blue
      blue color component value

Return Value
   The combined color.

Description
   red, green and blue are components ranging 0-255.

   The RGB function can be used to compute a valid color value for use 
   while in hi/truecolor modes. It returns an unsigned integer  in the 
   format &hAARRGGBB, where RR, GG and BB equal the values passed to this 
   function, in hexadecimal format. AA is the implicit alpha value and is 
   automatically set to &hFF (opaque).
   It is possible to retrieve the red, green, blue and alpha values from a 
   color value, by using a combination of And and Shr.  The second example 
   below shows how to #define and use macros to do this.

   Note for Windows API programmers: The macro named RGB in the Windows 
   references has been renamed BGR in the FB headers for Windows to avoid 
   collisions. 

Example
   See Put (Graphics) example in addition.

   ScreenRes 640,480,32  '32 bit color
   Line(0,0)-(319,479), RGB(255,0,0) 'draws a bright red box on the left side of the window
   Line(639,0)-(320,479), RGB(0,0,255) 'draws a bright blue box on the right side of the window

   Sleep 'wait before exiting

   '' setting and retrieving Red, Green, Blue and Alpha values

   #define RGBA_R( c ) ( CUInt( c ) Shr 16 And 255 )
   #define RGBA_G( c ) ( CUInt( c ) Shr  8 And 255 )
   #define RGBA_B( c ) ( CUInt( c )        And 255 )
   #define RGBA_A( c ) ( CUInt( c ) Shr 24         )

   Dim As UInteger r, g, b, a

   Dim As UInteger col = RGB(128, 192, 64)

   Print Using "Color: _&H\      \"; Hex(col, 8)

   r = RGBA_R( col )
   g = RGBA_G( col )
   b = RGBA_B( col )
   a = RGBA_A( col )

   Print
   Print Using "Red:         _&H\\ = ###"; Hex(r, 2); r
   Print Using "Green:       _&H\\ = ###"; Hex(g, 2); g
   Print Using "Blue:        _&H\\ = ###"; Hex(b, 2); b
   Print Using "Alpha:       _&H\\ = ###"; Hex(a, 2); a

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Rgb.

Differences from QB
   * New to FreeBASIC

See also
   * RGBA
   * Color
   * #define

   

   


------------------------------------------------------------- KeyPgRgba ----
RGBA

Computes a valid color value including alpha (transparency) for 
hi/truecolor modes

Syntax
   #define RGBA(r,g,b,a) ((CUInt(r) Shl 16) Or (CUInt(g) Shl 8) Or CUInt(b) 
   Or (CUInt(a) Shl 24))

Usage
   result = RGBA(red, green, blue, alpha)

Parameters
   red
      red color component value
   green
      green color component value
   blue
      blue color component value
   alpha
      alpha component value

Return Value
   the combined color

Description
   red, green, blue and alpha are components ranging 0-255.

   The RGBA function can be used to compute a valid color value including 
   an alpha channel for use while in hi/truecolor modes. It returns an 
   unsigned integer in the format &hAARRGGBB, where RR, GG, BB, AA equal 
   the values passed to this function, in hexadecimal format.
   It is possible to retrieve the red, green, blue  and alpha values from a 
   color value, by using a combination of And and Shr.  The second example 
   below shows how to #define and use macros to do this.

Example
   'open a graphics screen (320 * 240, 32-bit)
   ScreenRes 320, 240, 32

   Dim As Any Ptr img
   Dim As Integer x, y

   'make an image that varies in transparency and color
   img = ImageCreate(64, 64)
   For x = 0 To 63
     For y = 0 To 63
      PSet img, (x, y), RGBA(x * 4, 0, y * 4, (x + y) * 2)
     Next y
   Next x
   Circle img, (31, 31), 25,      RGBA(0, 127, 192, 192), ,,, F 'semi-transparent blue circle
   Line   img, (26, 20)-(38, 44), RGBA(255, 255, 255, 0),    BF 'transparent white rectangle

   'draw a background (diagonal white lines)
   For x = -240 To 319 Step 10
     Line (x, 0)-Step(240, 240), RGB(255, 255, 255)
   Next

   Line (10,  10)-(310,  37), RGB(127, 0, 0), BF 'red box for text
   Line (10, 146)-(310, 229), RGB(0, 127, 0), BF 'green box for Putting onto

   'draw the image and some text with PSET
   Draw String(64, 20), "PSet"
   Put(48,  48), img, PSet
   Put(48, 156), img, PSet

   'draw the image and some text with ALPHA
   Draw String (220, 20), "Alpha"
   Put(208,  48), img, Alpha
   Put(208, 156), img, Alpha

   'Free the image memory
   ImageDestroy img

   'Keep the window open until the user presses a key
   Sleep

   '' setting and retrieving Red, Green, Blue and Alpha values

   #define RGBA_R( c ) ( CUInt( c ) Shr 16 And 255 )
   #define RGBA_G( c ) ( CUInt( c ) Shr  8 And 255 )
   #define RGBA_B( c ) ( CUInt( c )        And 255 )
   #define RGBA_A( c ) ( CUInt( c ) Shr 24         )

   Dim As UInteger r, g, b, a

   Dim As UInteger col = RGBA(255, 192, 64, 128)

   Print Using "Color: _&H\      \"; Hex(col, 8)

   r = RGBA_R( col )
   g = RGBA_G( col )
   b = RGBA_B( col )
   a = RGBA_A( col )

   Print
   Print Using "Red:         _&H\\ = ###"; Hex(r, 2); r
   Print Using "Green:       _&H\\ = ###"; Hex(g, 2); g
   Print Using "Blue:        _&H\\ = ###"; Hex(b, 2); b
   Print Using "Alpha:       _&H\\ = ###"; Hex(a, 2); a

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Rgba.

Differences from QB
   * New to FreeBASIC

See also
   * RGB
   * Color
   * #define



------------------------------------------------------------ KeyPgRight ----
Right

Returns the rightmost substring of a string

Syntax
   Declare Function Right ( ByRef str As Const String, ByVal n As Integer ) 
   As String
   Declare Function Right ( ByRef str As Const WString, ByVal n As Integer 
   ) As WString

Usage
   result = Right[$]( str, n )

Parameters
   str
      The source string.
   n
      The substring length, in characters.

Return Value
   Returns the rightmost substring from str.

Description
   Returns the rightmost n characters starting from the right (end) of str. 
   If str is empty, then the null string ("") is returned. If n <= 0 then 
   the null string ("") is returned. If n > len(str) then the entire source 
   string is returned.

Example
   Dim text As String = "hello world"
   Print Right(text, 5)

   will produce the output:

   world

An Unicode example:

dim text as wstring*20
text = "&#1055;&#1088;&#1080;&#1074;&#1077;&#1090;, &#1084;&#1080;&#1088;!"
print right(text, 5) 'displays " &#1084;&#1080;&#1088;!"

Platform Differences
   * DOS does not support the wide-character string version of Right.

Dialect Differences
   * The string type suffix "$" is obligatory in the -lang qb dialect.
   * The string type suffix "$" is optional in the -lang fblite dialect.
   * The string type suffix "$" is forbidden in the -lang fb dialect.

Differences from QB
   * QB does not support Unicode.

See also
   * Left
   * Mid (Function)



------------------------------------------------------------ KeyPgRmdir ----
RmDir

Removes a folder/directory from the file system

Syntax
   Declare Function RmDir ( ByRef folder As Const String ) As Long

Usage
   result = RmDir( folder )

Parameters
   folder
      The folder/directory to be removed.

Return Value
   Returns zero (0) on success, and negative one (-1) on failure.

Description
   Removes a folder from the file system. The function will fail if the 
   folder is not empty.

Example
   Dim pathname As String = "foo\bar\baz"
   Dim result As Integer = RmDir( pathname )

   If 0 <> result Then Print "error: unable to remove folder " & pathname & " in the current path."

Platform Differences
   * Linux requires the folder case matches the real name of the file. 
     Windows and DOS are case insensitive. 
   * Path separators in Linux are forward slashes / . Windows uses 
     backward slashes \ but it allows for forward slashes .  DOS uses 
     backward  \ slashes. 

Differences from QB
   * None

See also
   * Shell
   * CurDir
   * ChDir
   * MkDir
   * Kill



-------------------------------------------------------------- KeyPgRnd ----
Rnd

Returns a random Double precision number in the range [0, 1)

Syntax
   Declare Function Rnd ( ByVal seed As Single = 1.0 ) As Double

Usage
   result = Rnd( seed )

Parameters
   seed
      Optional Single argument. If seed has a value of zero (0.0), the last 
      random number generated is repeate.  For any other number a new 
      random number is returned. With the QB-compatible algorithm, a 
      negative number fully reseeds the generator.  The default for no 
      argument is to return a new random number.

Return Value
   Returns the random number generated.

Description
   Returns a number of type Double in the range [0, 1) (i.e. 0 <= Rnd < 1), 
   based on a random seed (see Randomize).

   Rnd can use a variety of different algorithms - see Randomize for 
   details of the default and selectable algorithms.

   Rnd will return the same sequence of numbers every time a program is 
   run.  This sequence can be changed by reseeding the generator.

Example
   '' Function to a random number in the range [first, last), or {first <= x < last}.
   Function rnd_range (first As Double, last As Double) As Double
      Function = Rnd * (last - first) + first
   End Function

   '' seed the random number generator, so the sequence is not the same each time
   Randomize

   '' prints a random number in the range [0, 1), or {0 <= x < 1}.
   Print Rnd

   '' prints a random number in the range [0, 10), or  {0 <= x < 10}.
   Print Rnd * 10

   '' prints a random integral number in the range [1, 11), or  {1 <= x < 11}.
   '' with integers, this is equivalent to [1, 10], or {1 <= n <= 10}.
   Print Int(Rnd * 10) + 1

   '' prints a random integral number in the range [69, 421), or {69 <= x < 421}.
   '' this is equivalent to [69, 420], or {69 <= n <= 420}.
   Print Int(rnd_range(69, 421))

Dialect Differences
   The default algorithm used depends on the current dialect in use:
      * With the -lang fb dialect, a 32 bit Mersenne Twister function with 
        a granularity of 32 bits is used.
      * With the -lang qb dialect, a function giving the same output as 
        Rnd in QB is used. The granularity is 24 bits.
      * With the -lang deprecated and -lang fblite dialects, the function 
        in the C runtime available in the system is used. The function 
        available in Win32 has a granularity of 15 bits, and 32 bits in 
        Linux and DOS.

Differences from QB
   * None, if compiled in the -lang qb dialect.  Other dialects can also 
     use the same seeding and generating algorithms by calling Randomize 
     with the appropriate parameter.
   * For the non-QB-compatible algorithms, if the optional argument is 
     less than 0, it has the same meaning as passing an argument of 1.

See also
   * Randomize
   * Timer
   * Int



------------------------------------------------------------- KeyPgRset ----
RSet

Right justifies a string in a string buffer

Syntax
   Declare Sub RSet ( ByRef dst As String, ByRef src As Const String )
   Declare Sub RSet ( ByVal dst As WString Ptr, ByVal src As Const WString 
   Ptr )

Usage
   RSet dst, src

Parameters
   dst
      A String or WString buffer to copy the text into.
   src
      The source String or WString to be right justified.

Description
   RSet right justifies text into the string buffer dst, filling the right 
   part of the string with src and the left part with spaces.  The string 
   buffer size is not modified.

   If text is too long for the string buffer size, RSet truncates 
   characters from the right.

Example
   Dim buffer As String
   buffer = Space(10)
   RSet buffer, "91.5"
   Print "-[" & buffer & "]-"

Differences from QB
   * In QBasic the syntax was RSet dst = src. That syntax is also 
     supported by FB.

See also
   * LSet
   * Space
   * Put (File I/O)
   * MKD
   * MKI
   * MKL
   * MKS

   


------------------------------------------------------------ KeyPgRtrim ----
RTrim

Removes surrounding substrings or characters on the right side of a string

Syntax
   Declare Function RTrim ( ByRef str As Const String, [ Any ] ByRef 
   trimset As Const String = " " ) As String
   Declare Function RTrim ( ByRef str As Const WString, [ Any ] ByRef 
   trimset As Const WString = WStr(" ") ) As WString

Usage
   result = RTrim[$]( str [, [ Any ] trimset ] )

Parameters
   str
      The source string.
   trimset
      The substring to trim.

Return Value
   Returns the trimmed string.

Description
   This procedure trims surrounding characters from the right (end) of a 
   source string. Substrings matching trimset will be trimmed if specified, 
   otherwise spaces (ASCII code 32) are trimmed.

   If the Any keyword is used, any character matching a character in 
   trimset will be trimmed.

   All comparisons are case-sensitive.

Example
   Dim s1 As String = "Article 101  "
   Print "'" + RTrim(s1) + "'"
   Print "'" + RTrim(s1, " 01") + "'"
   Print "'" + RTrim(s1, Any " 10") + "'"

   Dim s2 As String = "Test Pattern aaBBaaBaa"
   Print "'" + RTrim(s2, "Baa") + "'"
   Print "'" + RTrim(s2, Any "Ba") + "'"

   will produce the output:


   'Article 101'
   'Article 101  '
   'Article'
   'Test Pattern aaB'
   'Test Pattern '

Platform Differences
   * DOS version/target of FreeBASIC does not support the wide-character 
     version of RTrim.

Dialect Differences
   * The string type suffix "$" is obligatory in the -lang qb dialect.
   * The string type suffix "$" is optional in the -lang fblite dialect.
   * The string type suffix "$" is forbidden in the -lang fb dialect.

Differences from QB
   * QB does not support specifying a trimset string or the ANY clause.

See also
   * LTrim
   * Trim



-------------------------------------------------------------- KeyPgRun ----
Run

Transfers execution to an external program

Syntax
   Declare Function Run ( ByRef program As Const String, ByRef arguments As 
   Const String = "" ) As Long

Usage
   result = Run( program [, arguments ] )

Parameters
   program
      The file name (including file path) of the program (executable) to 
      transfer control to.
   arguments
      The command-line arguments to be passed to the program.

Return Value
   Returns negative one (-1) if the program could not be executed.

Description
   Transfers control over to an external program. When the program exits, 
   execution will return to the system.

Example
   '' Attempt to transfer control to "program.exe" in the current directory.
   Dim result As Integer = Run("program.exe")

   '' at this point, "program.exe" has failed to execute, and
   '' result will be set to -1.

Platform Differences
   * Linux requires the program case matches the real name of the file. 
     Windows and DOS  are case insensitive. The program being run may be 
     case sensitive for its command line parameters.
   * Path separators in Linux are forward slashes ("/"). Windows uses 
     backward slashes ("\") although some versions of Windows allow forward 
     slashes.  DOS uses backward slashes. 

Differences from QB
   * Run needs the full executable name, including extension (.exe) on 
     platforms that have one (Win32, DOS).
   * Returning an error code is new to FreeBASIC.

See also
   * Exec transfer temporarily, with arguments  
   * Chain transfer temporarily, without arguments
   * Command pick arguments




============================================================================
    S

------------------------------------------------------------- KeyPgSadd ----
SAdd

Returns a pointer to a string variable's data

Syntax
   Declare Function SAdd ( ByRef str As String ) As ZString Ptr
   Declare Function SAdd ( ByRef str As WString ) As ZString Ptr
   Declare Function SAdd ( ByRef str As ZString ) As ZString Ptr

Usage
   result = SAdd( str )

Parameters
   str
      the string expression or variable to get the address of

Return Value
   A pointer to the data associated with str.

Description
   Returns the memory offset of the string data in the string variable.

Example
   Dim s As String

   Print SAdd(s)
   s = "hello"
   Print SAdd(s)
   s = "abcdefg, 1234567, 54321"
   Print SAdd(s)

Differences from QB
   * QB returned an integer instead of a pointer.

See also
   * StrPtr
   * VarPtr
   * ProcPtr



------------------------------------------------------------ KeyPgScope ----
Scope...End Scope

Statement to begin a new scope block

Syntax
   Scope
      [statements]
   End Scope

Description
   The Scope block allows variables to be (re)defined and used locally in a 
   program.

   When a variable is (re)defined with Dim within a scope structure, this 
   local working variable can be used from its (re)definition until the end 
   of the scope.  During this time, any variables outside the scope that 
   have the same name will be ignored, and will not be accessible by that 
   name. Any statements in the Scope block before the variable is redefined 
   will use the variable as defined outside the Scope.

   The local variables are reserved on stack at granularity level of each 
   procedure (including the main part of the program), not at granularity 
   level of each individual scope block. So a same memory space can be used 
   by local variables belonging to different scope blocks.

   Scope..End Scope is not permitted when compiling with in the -lang qb 
   dialect.

Example
   Dim As Integer x = 5, y = 2
   Print "x ="; x; ", "; "y ="; y
   Scope
      Dim x As Integer = 3
      Print "x ="; x; ", "; "y ="; y
      Scope
         Dim y As Integer = 4
         Print "x ="; x; ", "; "y ="; y
      End Scope
   End Scope
   Print "x ="; x; ", "; "y ="; y

Dialect Differences
   * Explicit Scope..End Scope blocks are available only in the -lang fb 
     and -lang deprecated dialects.
   * Explicit Scope..End Scope blocks are not available in the -lang fblite
     and -lang qb dialects.

Differences from QB
   * New to FreeBASIC

See also
   * Dim
   * ReDim
   * Static
   * Var
   * Byref (Variables)



--------------------------------------------------- KeyPgScreengraphics ----
Screen (Graphics)

Initializes a graphics mode using QB-like mode numbers

Syntax
   -lang fb|fblite dialects:
      Screen mode [, [ depth ] [, [ num_pages ] [, [ flags ] [, [ 
      refresh_rate ]]]]]
      Screen , [ active_page ] [, [ visible_page ]]
   -lang qb dialect:
      Screen [ mode ] [, [ colormode ] [, [ active_page ] [, [ visible_page 
      ]]]]
 
Parameters
   mode 
      is a QB style graphics screen mode number (see below).  If mode is 0, 
      then any currently set graphics mode is closed, and all functions 
      resume their normal console-mode functionality.  See below for 
      available modes.
   depth
      is the color depth in bits per pixel.  This only has an effect for 
      modes 14 and higher.  Values of 8, 16 and 32 are allowed.  15 and 24 
      are also allowed as aliases for 16 and 32, respectively.  If omitted, 
      it defaults to 8.
   num_pages
      is the number of video pages you want, see below.  If omitted, it 
      defaults to 1.
   flags
      Are used to select several things as graphics driver priority, 
      fullscreen mode. There are constants predefined in the fbgfx.bi file 
      ready to use.  See the page ScreenRes for available flags.
   refresh_rate
      requests a refresh rate.  If it is not available in the present card 
      or the parameter is omitted, FreeBASIC chooses the rate 
      automatically.
   active_page
      Used to set the active page, where printing/drawing commands take 
      effect
   visible_page
      Used to set the visible page, which is shown to the user
   colormode
      Unused - allowed for compatibility with the QB syntax

Description
   Screen tells the compiler to link the GfxLib and initializes a QB-only, 
   QB-on-GUI or OpenGL graphics mode, depending on the flags setting.

   In QB-only modes a dumb window or fullscreen resolution is set, one or 
   more buffers in standard memory are created, console commands are 
   redirected to their graphic versions, a default palette is set and an 
   automatic screen refresh thread is started.  QB-like graphics and 
   console statements can be used.

   In QB-on-GUI modes one or more buffers in standard memory are created, 
   console commands are redirected to their graphic versions and a 
   default palette is set.  QB-like graphics and console statements can be 
   used.  It is up to the user to create a window and to refresh it with 
   the contents of the graphics buffers.

   In OpenGL modes a dumb window or fullscreen resolution is set, one or 
   more buffers in standard memory are created, and the OS's OpenGL library 
   is initialized.  From here only OpenGL commands can be used; QB-like and 
   console commands are forbidden.  This allows to initialize OpenGL in a 
   portable way; you can then also use ScreenControl to properly customize 
   the GL pixel format to be used before Screen is called or to retrieve 
   the list of supported OpenGL extensions after a mode has been set, and 
   ScreenGLProc to obtain extension function pointers.

   Any buffer that is created in standard memory uses one of three 
   supported internal pixel formats, depending on the desired color depth; 
   see Internal pixel formats for details.

   If Screen fails to set the required mode, an "Illegal function call" 
   error is issued and the screen pointer is set to 0. Thus Screen failures 
   can be detected using standard On Error processing or retrieving the 
   screen pointer with ScreenPtr.

   Before setting a fullscreen mode the program should check if that mode 
   is available in the graphics card using ScreenList.

mode details
   Available modes list:
   QB compatibility modes:
   +-------+----------+---------+--------------+-----------+----------------------------------------+
   |Mode nr|Resolution|Emulation|Text          |char size  |colors on screen                        |
   |1      |320x200   |CGA      |40X25         |8x8        |16 background, 1 of four sets foreground|
   |2      |640x200   |CGA      |80x25         |8x8        |16 colors to 2 attributes               |
   |7      |320x200   |EGA      |40x25         |8x8        |16 colors to 16 attributes              |
   |8      |640x200   |EGA      |80x25         |8x8        |16 colors to 16 attributes              |
   |9      |640x350   |EGA      |80x25 0r 80x43|8x14 or 8x8|16 colors to 16 attributes              |
   |11     |640x480   |VGA      |80x30 or 80x60|8x16 or 8x8|256K colors to 2 attributes             |
   |12     |640x480   |VGA      |80x30 or 80x60|8x16 or 8x8|256K colors to 16 attributes            |
   |13     |320x200   |MCGA     |40X25         |8X8        |256K colors to 256 attributes           |
   +-------+----------+---------+--------------+-----------+----------------------------------------+

   New FreeBASIC modes:
   +-------+----------+---------+-----------------+-----------+---------------------------------------------+
   |Mode nr|Resolution|Emulation|Text             |char size  |colors on screen                             |
   |14     |320x240   |         |40x30            |8x8        |256K colors to 256 attributes or direct color|
   | 15    |400x300   |         |50x37            |8x8        |256K colors to 256 attributes or direct color|
   | 16    |512x384   |         |64x24 or 64x48   |8x16 or 8x8|256K colors to 256 attributes or direct color|
   |17     |640x400   |         |80x25 or 80x50   |8x16 or 8x8|256K colors to 256 attributes or direct color|
   |18     |640x480   |         |80x30 or 80x60   |8x16 or 8x8|256K colors to 256 attributes or direct color|
   | 19    |800x600   |         |100x37 or 100x75 |8x16 or 8x8|256K colors to 256 attributes or direct color|
   |20     |1024x768  |         |128x48 or 128x96 |8x16 or 8x8|256K colors to 256 attributes or direct color|
   | 21    |1280x1024 |         |160x64 or 160x128|8x16 or 8x8|256K colors to 256 attributes or direct color|
   +-------+----------+---------+-----------------+-----------+---------------------------------------------+
 

depth details
   For modes 14 and up, the depth parameter changes the color depth to the 
   specified new one; if depth is not specified, these modes run in 8bpp.  
   For modes 13 and below, depth has no effect.

num_pages details
   You can request any number of pages for any video mode; if you omit the 
   parameter, only the visible page (number 0) will be available.  A page 
   is either the visible screen or an offscreen buffer, you can show a page 
   while working on another one; see the ScreenSet statement for details.  
   All pages are created in standard memory, the video card memory is never 
   used for video buffering.

flags details:
   (documented at the page ScreenRes)

Other details
   While in windowed mode, clicking on the window close button will add a 
   keypress of (Chr(255) & "k") to the Inkey buffer.  Clicking on the 
   Maximize window button will switch to fullscreen mode if possible.  A 
   successful Screen call sets currently visible and working pages both to 
   page number 0, resets the palette to the specified mode one (see 
   Default palettes), resets the clipping region to the size of the screen, 
   disables custom coordinates mappings, moves the graphics cursor to the 
   center of the screen, moves the text cursor to the top-left corner of 
   the screen (but never visible on any graphics screen), and sets 
   foreground and background colors to bright white and black respectively.

Note on using Screen 0
   Screen 0 closes any graphics window, but also clears the console window 
   if it exists.
   Screen 0, , , SCREEN_EXIT (with SCREEN_EXIT=&h80000000) also closes any 
   graphics window, but does not clear the console window if it exists 
   (previous text is preserved).

Example
   ' Sets screen mode 13 (320*200, 8bpp)
   Screen 13
   Print "Screen mode 13 set"

   Sleep

   #include "fbgfx.bi"
   #if __FB_LANG__ = "fb"
   Using FB '' Screen mode flags are in the FB namespace in lang FB
   #endif

   ' Sets screen mode 18 (640*480) with 32bpp color depth and 4 pages, in windowed mode; switching disabled
   Screen 18, 32, 4, (GFX_WINDOWED Or GFX_NO_SWITCH)

   ' Check to make sure Screen was opened successfully
   If ScreenPtr = 0 Then
      Print "Error setting video mode!"
      End
   End If

   Print "Successfully set video mode"
   Sleep

Platform Differences
   * In DOS, Windowing and OpenGL related switches are not available, and 
     other issues, see GfxLib overview

Dialect Differences
   * In the -lang fb and -lang fblite dialects, the usage is:
      Screen mode [, [depth] [, [num_pages] [, [flags] [, [refresh_rate
      ]]]]]
   or:
      Screen , [active_page] [, [visible_page]]]

   * In the -lang qb dialect, the usage is:
      Screen [mode] [, [colormode] [, [active_page] [, [visible_page]]]]

Differences from QB
   * None in the -lang qb dialect.
   * In QB the syntax was Screen mode,colormode,active_page,visible_page. 
     Of those parameters FreeBASIC supports only mode and redefines the 
     rest. The use of Screen , , apage,vpage to swap screen pages is only 
     available in the -lang qb dialect.
   * ScreenSet should be used in the -lang fb and -lang fblite dialects.

See also
   * Screen (Console)
   * ScreenRes More flexible alternative to Screen
   * ScreenList Check display modes available for FB GfxLib to use
   * ScreenControl Select driver and more 
   * ScreenLock
   * ScreenUnlock
   * ScreenPtr Semi-low level access
   * ScreenSet
   * ScreenCopy
   * ScreenInfo
   * ScreenGLProc
   * Internal pixel formats



------------------------------------------------------- KeyPgScreenCons ----
Screen (Console)

Gets the character or color attribute at a given location

Syntax
   Declare Function Screen ( ByVal row As Long, ByVal column As Long, ByVal 
   colorflag As Long = 0 ) As Long

Usage
   result = Screen( row, column [, colorflag ] )

Parameters
   row
      1-based offset from the top left corner of the console.
   column
      1-based offset from the top left corner of the console.
   colorflag
      If equal to 0, the ASCII code is returned, otherwise the color 
      attribute is returned.  If omitted, it defaults to 0.

Return Value
   The ASCII or color attribute of the character.

Description
   Screen returns the character or the color attribute found at a given 
   position of a console output. It works in console mode and in graphics 
   mode.

   The format of the color attribute depends on the current color depth:

   If the color type is a palette type with up to 4 bits per pixel (such as 
   the Win32 console), then the color attribute is an 8-bit value, where 
   the higher four bits hold the cell background color and the lower four 
   bits hold the foreground (character) color.

   If the color type is an 8-bit palette, then the color attribute is a 
   16-bit value, where the high byte holds the background color and the low 
   byte holds the foreground color.

   If the color type is full color, then the color attribute is a 32-bit 
   integer, holding a single color value.  If colorflag is equal to 1, then 
   the foreground color is returned; if colorflag is equal to 2, then the 
   background color is returned.

   The color values for the standard 16 color palette are:

         +-----+-------+-----+------------+
         |Value|Color  |Value|Color       |
         |0    |Black  |8    |Gray        |
         |1    |Blue   |9    |Bright Blue |
         |2    |Green  |10   |Bright Green|
         |3    |Cyan   |11   |Bright Cyan |
         |4    |Red    |12   |Bright Red  |
         |5    |Magenta|13   |Pink        |
         |6    |Brown  |14   |Yellow      |
         |7    |White  |15   |Bright White|
         +-----+-------+-----+------------+

Example
   Dim character_ascii_value As Integer
   Dim attribute As Integer
   Dim background As Integer
   Dim cell_color As Integer
   Dim row As Integer, col As Integer

   character_ascii_value = Screen( row, col )
   attribute = Screen( row, col, 1 )
   background = attribute Shr 4
   cell_color = attribute And &hf

   '' open a graphics screen with 4 bits per pixel
   '' (alternatively, omit this line to use the console)
   ScreenRes 320, 200, 4

   '' print a character
   Color 7, 1
   Print "A"

   Dim As UInteger char, col, fg, bg

   '' get the ASCII value of the character we've just printed
   char = Screen(1, 1, 0)

   ''get the color attributes
   col = Screen(1, 1, 1)
   fg = col And &HF
   bg = (col Shr 4) And &HF

   Print Using "ASCII value: ### (""!"")"; char; Chr(char)
   Print Using "Foreground color: ##"; fg
   Print Using "Background color: ##"; bg
   Sleep

   '' open a graphics screen with 8 bits per pixel
   ScreenRes 320, 200, 8

   '' print a character
   Color 30, 16
   Print "Z"

   Dim As UInteger char, col, fg, bg

   '' get the ASCII value of the character we've just printed
   char = Screen(1, 1, 0)

   ''get the color attributes
   col = Screen(1, 1, 1)
   fg = col And &HFF
   bg = (col Shr 8) And &HFF

   Print Using "ASCII value: ### (""!"")"; char; Chr(char)
   Print Using "Foreground color: ###"; fg
   Print Using "Background color: ###"; bg
   Sleep

   '' open a full-color graphics screen
   ScreenRes 320, 200, 32

   '' print a character
   Color RGB(255, 255, 0), RGB(0, 0, 255) 'yellow on blue
   Print "M"

   Dim As Integer char, fg, bg

   '' get the ASCII value of the character we've just printed
   char = Screen(1, 1, 0)

   ''get the color attributes
   fg = Screen(1, 1, 1)
   bg = Screen(1, 1, 2)

   Print Using "ASCII value: ### (""!"")"; char; Chr(char)
   Print Using "Foreground color: &"; Hex(fg, 8)
   Print Using "Background color: &"; Hex(bg, 8)
   Sleep

Platform Differences
   * On the Linux version, the value returned can differ from the 
     character shown on the console.  For example, unprintable control 
     codes - such as the LF character (10) that implicitly occurs after the 
     end of Printed text - may be picked up instead of the untouched 
     character in its place.

Differences from QB
   * In QB Screen triggered an error if the coordinates were out of 
     screen.

See also
   * Screen (Graphics)
   * Color



------------------------------------------------------- KeyPgScreencopy ----
ScreenCopy

Copies the contents of a graphical page into another graphical page

Syntax
   Declare Function ScreenCopy ( ByVal from_page As Long = -1, ByVal 
   to_page As Long = -1 ) As Long

Usage
   ScreenCopy [ from_page ] [, to_page ]

Parameters
   from_page
      page to copy from
   to_page
      page to copy to

Return Value
   Returns zero (0) if successful, or a non-zero error code to indicate a 
   failure.

Description
   from_page is the page to copy from. If this argument is omitted, the 
   current work page is assumed.  to_page is the page to copy to. If this 
   argument is omitted, the currently visible page is assumed.  Page 
   numbers range from 0 to num_pages - 1, where num_pages is the number of 
   pages specified when setting the graphics mode with ScreenRes or Screen.

   You can use this function to add a double buffer to your graphics. Any 
   graphics screen mode with multiple pages supports this function.

   ScreenCopy is inactive if the destination page is locked.

   There are two other functions similar to this: Flip and PCopy.  Flip is 
   designed to work in OpenGL modes, while PCopy supports console pages on 
   some platforms.  Both do the same thing as ScreenCopy in normal graphics 
   modes.

   The error code returned by ScreenCopy can be checked using Err in the 
   next line. The function version of  ScreenCopy returns directly the 
   error code as a 32 bit Long.

Example
   See also ScreenSet example.

   '' 320x200x8, with 3 pages
   Screen 13,,3

   '' image for working page #1 (visible page #0)
   ScreenSet 1, 0
   Cls
   Circle( 160, 100 ), 90, 1 ,,,, f
   Circle( 160, 100 ), 90, 15
   Print "Press 2 to copy page #2 to visible page"
   Print "Press escape to exit"

   '' image for working page #2 (visible page #0)
   ScreenSet 2, 0
   Cls
   Line( 50, 50 )-( 270, 150 ), 2, bf
   Line( 50, 50 )-( 270, 150 ), 15, b
   Print "Press 1 to copy page #1 to visible page"
   Print "Press escape to exit"

   '' page #0 is the working page (visible page #0)
   ScreenSet 0, 0
   Cls
   Print "Press 1 to copy page #1 to visible page"
   Print "Press 2 to copy page #2 to visible page"
   Print "Press escape to exit"

   Dim k As String

   Do
     k = Inkey
     Select Case k
     Case Chr(27)
      Exit Do
     Case "1"
      ScreenCopy 1, 0
     Case "2"
      ScreenCopy 2, 0
     End Select

     Sleep 25
   Loop

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Screencopy.

Differences from QB
   * New to FreeBASIC. It is a graphics-only version of PCopy - which 
     works in both text and graphics modes.

See also
   * PCopy
   * Screen (Graphics)
   * ScreenRes
   * ScreenSet



---------------------------------------------------- KeyPgScreencontrol ----
ScreenControl

Sets or gets internal graphics library settings

Syntax
   Declare Sub ScreenControl ( ByVal what As Long, ByRef param1 As Integer 
   = 0, ByRef param2 As Integer = 0, ByRef param3 As Integer = 0, ByRef 
   param4 As Integer = 0 )
   Declare Sub ScreenControl ( ByVal what As Long, ByRef param As String = 
   "" )

Usage
   ScreenControl( what [, [ param1 ][, [ param2 ][, [ param3 ][, [ param4 
   ]]]]] )
      or,
   ScreenControl( what [, param ] )

Parameters
   what
      specifies the function to perform
   param1
      optional first integer parameter, contains value to be set on entry 
      or value got on exit
   param2
      optional second integer parameter, contains value to be set on entry 
      or value got on exit
   param3
      optional third integer parameter, contains value to be set on entry 
      or value got on exit
   param4
      optional fourth integer parameter, contains value to be set on entry 
      or value got on exit
   param
      optional string parameter, contains text to be set on entry or text 
      got on exit

Description
   This function can be used to set or get internal GfxLib states. The what 
   parameter specifies which operation to perform. On operations that set 
   states, the param* parameters must contain the values to be set. On 
   operations that get states, param* will hold the values returned by 
   GfxLib when the function returns.
   The meaning of the param* parameters depend on the what parameter, whose 
   possible values are defined as constants in fbgfx.bi.  In lang fb, they 
   are set to be stored in the FB Namespace.
   Below is a list of the supported what constants - and their values as 
   defined at time of writing - along with the parameters associated with 
   them.

   Supported operations

      Note:
         (*) denotes operations that are allowed while a graphics mode has 
         not yet been set via Screen (Graphics) or ScreenRes,
         (**) denotes the operations that must be performed before the 
         graphics mode is set via Screen (Graphics) or ScreenRes,
         for all other operations, return values are zero (0) or the empty 
         string ("") and the operation has no effect if a graphics mode is 
         not available at call time.

      Get operations
   * GET_WINDOW_POS Returns the current window position, in desktop 
     coordinates.
      [OUT] param1 x
      [OUT] param2 y
   * (*) GET_WINDOW_TITLE Returns the title of the program window.
      [OUT] param title
   * GET_WINDOW_HANDLE Returns a handle to the program window.
      [OUT] param1 handle; this is a HWND in Windows, a "Window" XID in X11
      [OUT] param2 display ptr in X11
   * (*) GET_DESKTOP_SIZE Returns the desktop size, in pixels.
      [OUT] param1 width
      [OUT] param2 height
   * GET_SCREEN_SIZE Returns the current screen size in pixels.
      [OUT] param1 width
      [OUT] param2 height
   * GET_SCREEN_DEPTH Returns current graphics mode screen depth.
      [OUT] param1 bits per pixel
   * GET_SCREEN_BPP Returns current graphics mode BPP.
      [OUT] param1 bytes per pixel
   * GET_SCREEN_PITCH Returns the current graphics mode framebuffer pitch, 
     in bytes.
      [OUT] param1 pitch
   * GET_SCREEN_REFRESH Returns the current graphics mode refresh rate, in 
     hertz.
      [OUT] param1 rate
   * GET_DRIVER_NAME Returns the current graphics mode driver name.
      [OUT] param name
   * GET_TRANSPARENT_COLOR Returns the transparent color value for the 
     current graphics mode depth.
      [OUT] param1 value
   * GET_VIEWPORT Returns the current viewport as set by the 
     View (Graphics) statement, in screen coordinates.
      [OUT] param1 x1
      [OUT] param2 y1
      [OUT] param3 x2
      [OUT] param4 y2
   * GET_PEN_POS Returns the last graphical pen position, in screen 
     coordinates. This position is used in graphics functions supporting 
     relative coordinates using the Step keyword.
      [OUT] param1 x
      [OUT] param2 y
   * GET_COLOR Returns the current graphics mode color.
      [OUT] param1 foreground
      [OUT] param2 background
   * GET_ALPHA_PRIMITIVES Returns if primitives drawing support for alpha 
     channel is enabled.
      [OUT] param1 TRUE (-1) if alpha primitives is enabled, FALSE (0) 
      otherwise
   * GET_GL_EXTENSIONS Returns a string holding all supported GL 
     extensions, or the empty string if not in OpenGL mode.
      [OUT] param supported GL extensions
   * GET_HIGH_PRIORITY Returns if GFX_HIGH_PRIORITY was specified in the 
     flags passed to Screen or ScreenRes.
      [OUT] param1 higher priority graphics processing enabled

      Set operations
   * SET_WINDOW_POS Sets the current program window position, in desktop 
     coordinates.
      [IN] param1 x
      [IN] param2 y
   * (*) SET_WINDOW_TITLE Sets the current program window title. This is 
     equivalent to calling WindowTitle( param ).
      [IN] param title
   * SET_PEN_POS Sets the current graphical pen position, in screen 
     coordinates. This position is used in graphics functions supporting 
     relative coordinates using the Step keyword.
      [IN] param1 x
      [IN] param2 y
   * (*) SET_DRIVER_NAME Sets the name of the internal graphics driver to 
     be used in subsequent calls to Screen or ScreenRes.
      [IN] param driver name
   * SET_ALPHA_PRIMITIVES Sets if primitives drawing should honor alpha 
     channel.
      [IN] param1 enabled
   * (*) SET_GL_COLOR_BITS Sets the number of bits dedicated to the OpenGL 
     color buffer
      [IN] param1 bits
   * (*) SET_GL_COLOR_RED_BITS Sets the number of bits dedicated to the 
     red component of the OpenGL color buffer
      [IN] param1 bits
   * (*) SET_GL_COLOR_GREEN_BITS Sets the number of bits dedicated to the 
     green component of the OpenGL color buffer
      [IN] param1 bits
   * (*) SET_GL_COLOR_BLUE_BITS Sets the number of bits dedicated to the 
     blue component of the OpenGL color buffer
      [IN] param1 bits
   * (*) SET_GL_COLOR_ALPHA_BITS Sets the number of bits dedicated to the 
     alpha component of the OpenGL color buffer
      [IN] param1 bits
   * (*) SET_GL_DEPTH_BITS Sets the number of bits dedicated to the OpenGL 
     depth buffer
      [IN] param1 bits
   * (*) SET_GL_STENCIL_BITS Sets the number of bits dedicated to the 
     OpenGL stencil buffer
      [IN] param1 bits
   * (*) SET_GL_ACCUM_BITS Sets the number of bits dedicated to the OpenGL 
     accumulation buffer
      [IN] param1 bits
   * (*) SET_GL_ACCUM_RED_BITS Sets the number of bits dedicated to the 
     red component of the OpenGL accumulation buffer
      [IN] param1 bits
   * (*) SET_GL_ACCUM_GREEN_BITS Sets the number of bits dedicated to the 
     green component of the OpenGL accumulation buffer
      [IN] param1 bits
   * (*) SET_GL_ACCUM_BLUE_BITS Sets the number of bits dedicated to the 
     blue component of the OpenGL accumulation buffer
      [IN] param1 bits
   * (*) SET_GL_ACCUM_ALPHA_BITS Sets the number of bits dedicated to the 
     alpha component of the OpenGL accumulation buffer
      [IN] param1 bits
   * (*) SET_GL_NUM_SAMPLES Sets the number of samples to be used for 
     OpenGL multisampling
      [IN] param1 samples
   * (**) SET_GL_2D_MODE Sets OpenGL 2D render
      [IN] param1:
         OGL_2D_NONE No rendering
         OGL_2D_MANUAL_SYNC Manual rendering (when Flip is called)
         OGL_2D_AUTO_SYNC Automatic rendering
   * (**) SET_GL_SCALE Apply a zoom factor on OpenGL 2D render (only 
     allowed if OpenGL 2D render mode has yet been activated via 
     SET_GL_2D_MODE)
      [IN] param1 zoom factor (0: no rendering)

      Other operations
   * POLL_EVENTS Cause the library to poll all events, ie to check the 
     system event queue, specifically used for retrieving keyboard and 
     mouse events.  This is most useful for OpenGL code where Flip is not 
     used, as normally Flip will cause these events to be polled.

Example
   '' include fbgfx.bi for some useful definitions
   #include "fbgfx.bi"

   '' use FB namespace for easy access to types/constants
   Using FB

   Dim e As Event
   Dim As Integer x0, y0, x, y
   Dim As Integer shakes = 0
   Dim As Any Ptr img

   ScreenRes 320, 200, 32
   Print "Click to shake window"

   '' find window coordinates
   ScreenControl GET_WINDOW_POS, x0, y0

   Do

      If (shakes > 0) Then
         
         '' do a shake of the window

         If (shakes > 1) Then

            '' move window to a random position near its original coordinates
            x = x0 + Int(32 * (Rnd() - 0.5))
            y = y0 + Int(32 * (Rnd() - 0.5))
            ScreenControl SET_WINDOW_POS, x, y

         Else

            '' move window back to its original coordinates
            ScreenControl SET_WINDOW_POS, x0, y0

         End If

         shakes -= 1

      End If

      If (ScreenEvent(@e)) Then
         Select Case e.type
         
         '' user pressed the mouse button
         Case EVENT_MOUSE_BUTTON_PRESS

            If (shakes = 0) Then
               '' set to do 20 shakes
               shakes = 20

               '' find current window coordinates to shake around
               ScreenControl GET_WINDOW_POS, x0, y0
            End If

         '' user closed the window or pressed a key
         Case EVENT_WINDOW_CLOSE, EVENT_KEY_PRESS
            '' exit to end of program
            Exit Do

         End Select
      End If

      '' free up CPU for other programs
      Sleep 5

   Loop

   '' include fbgfx.bi for some useful definitions
   #include "fbgfx.bi"

   Dim As String driver

   #ifdef __FB_WIN32__
   '' set graphics driver to GDI (Win32 only), before calling ScreenRes
   ScreenControl FB.SET_DRIVER_NAME, "GDI"
   #endif

   ScreenRes 640, 480

   '' fetch graphics driver name and display it to user
   ScreenControl FB.GET_DRIVER_NAME, driver
   Print "Graphics driver name: " & driver

   '' wait for a keypress before closing the window
   Sleep

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Screencontrol.

Differences from QB
   * New to FreeBASIC

See also
   * Screen (Graphics)
   * ScreenEvent
   * ScreenInfo
   * WindowTitle
   * View (Graphics)



------------------------------------------------------ KeyPgScreenevent ----
ScreenEvent

Queries for and retrieves system events.

Syntax
   Declare Function ScreenEvent ( ByVal event As Any Ptr = 0 ) As Long

Usage
   result = ScreenEvent( [ event ] )

Parameters
   event
      Specifies the buffer where the function should store the event data.

Return Value
   Returns -1 if there are pending events to be retrieved, 0 otherwise.

Description
   This function returns the latest available system event from the 
   internal GfxLib events queue. By "event" we mean any mouse or keyboard 
   activity, for example.

   The event data (if available) will be copied into the buffer pointed 
   That should be declared as an  Event

   Querying for events
      The function returns -1 if there are pending events to be retrieved, 
      0 otherwise. If the event parameter is set to 0 (the default if 
      omitted) ScreenEvent will not be able to copy the event data and it 
      will not dequeue it from the internal events queue. Calling the 
      function this way can be useful to check if there are pending events 
      without actually fetching them.

   Note
      If you receive a KEY_PRESS, KEY_RELEASE or KEY_REPEAT event, it does 
      not clear the keyboard buffer.  If you need the buffer to be clear 
      after you receive the event, you will need to clear it manually.  See 
      Inkey.

Example
   '' include fbgfx.bi for some useful definitions
   #include "fbgfx.bi"
   #if __FB_LANG__ = "fb"
   Using fb '' constants and structures are stored in the FB namespace in lang fb
   #endif

   Dim e As Event

   ScreenRes 640, 480
   Do
      If (ScreenEvent(@e)) Then
         Select Case e.type
         Case EVENT_KEY_PRESS
            If (e.scancode = SC_ESCAPE) Then
               End
            End If
            If (e.ascii > 0) Then
               Print "'" & e.ascii & "'";
            Else
               Print "unknown key";
            End If
            Print " was pressed (scancode " & e.scancode & ")"
         Case EVENT_KEY_RELEASE
            If (e.ascii > 0) Then
               Print "'" & e.ascii & "'";
            Else
               Print "unknown key";
            End If
            Print " was released (scancode " & e.scancode & ")"
         Case EVENT_KEY_REPEAT
            If (e.ascii > 0) Then
               Print "'" & e.ascii & "'";
            Else
               Print "unknown key";
            End If
            Print " is being repeated (scancode " & e.scancode & ")"
         Case EVENT_MOUSE_MOVE
            Print "mouse moved to " & e.x & "," & e.y & " (delta " & e.dx & "," & e.dy & ")"
         Case EVENT_MOUSE_BUTTON_PRESS
            If (e.button = BUTTON_LEFT) Then
               Print "left";
            ElseIf (e.button = BUTTON_RIGHT) Then
               Print "right";
            Else
               Print "middle";
            End If
            Print " button pressed"
         Case EVENT_MOUSE_BUTTON_RELEASE
            If (e.button = BUTTON_LEFT) Then
               Print "left";
            ElseIf (e.button = BUTTON_RIGHT) Then
               Print "right";
            Else
               Print "middle";
            End If
            Print " button released"
         Case EVENT_MOUSE_DOUBLE_CLICK
            If (e.button = BUTTON_LEFT) Then
               Print "left";
            ElseIf (e.button = BUTTON_RIGHT) Then
               Print "right";
            Else
               Print "middle";
            End If
            Print " button double clicked"
         Case EVENT_MOUSE_WHEEL
            Print "mouse wheel moved to position " & e.z
         Case EVENT_MOUSE_ENTER
            Print "mouse moved into program window"
         Case EVENT_MOUSE_EXIT
            Print "mouse moved out of program window"
         Case EVENT_WINDOW_GOT_FOCUS
            Print "program window got focus"
         Case EVENT_WINDOW_LOST_FOCUS
            Print "program window lost focus"
         Case EVENT_WINDOW_CLOSE
            End
         Case EVENT_MOUSE_HWHEEL
            Print "horizontal mouse wheel moved to position " & e.w
         End Select
      End If

      Sleep 1
   Loop

Platform Differences
   * ScreenEvent does not return window related events in the DOS version, 
     but does return input events.

Dialect Differences
   * Not available in the -lang qb dialect.

Differences from QB
   * New to FreeBASIC

See also
   * Event
   * Screen (Graphics)
   * Inkey
   * MultiKey
   * GetMouse



----------------------------------------------------- KeyPgScreenglproc ----
ScreenGLProc

Gets the address of an OpenGL procedure

Syntax
   Declare Function ScreenGLProc ( ByRef procname As Const String ) As Any 
   Ptr

Parameters
   procname
      name of the procedure to retrieve the address of

Description
   This function can be used to get the address of any OpenGL procedure, to 
   be used to retrieve the pointers to new functions associated with OpenGL 
   extensions. If given procedure named procname cannot be found, 
   ScreenGLProc will return NULL (0).

Example
   '' include fbgfx.bi for some useful definitions
   #include "fbgfx.bi"

   Dim SwapInterval As Function(ByVal interval As Integer) As Integer
   Dim extensions As String

   '' Setup OpenGL and retrieve supported extensions
   ScreenRes 640, 480, 32,, FB.GFX_OPENGL
   ScreenControl FB.GET_GL_EXTENSIONS, extensions

   If (InStr(extensions, "WGL_EXT_swap_control") <> 0) Then
      '' extension supported, retrieve proc address
      SwapInterval = ScreenGLProc("wglSwapIntervalEXT")
      If (SwapInterval <> 0) Then
         '' Ok, we got it. Set OpenGL to wait for vertical sync on buffer swaps
         SwapInterval(1)
      End If
   End If

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Screenglproc.

Platform Differences
   * Not available for DOS target.

Differences from QB
   * New to FreeBASIC

See also
   * Screen (Graphics)
   * ScreenControl



------------------------------------------------------- KeyPgScreeninfo ----
ScreenInfo

Retrieves information about current video mode or the desktop.

Syntax
   Declare Sub ScreenInfo ( ByRef w As Integer = 0, ByRef h As Integer = 0, 
   ByRef depth As Integer = 0, ByRef bpp As Integer = 0, ByRef pitch As 
   Integer = 0, ByRef rate As Integer = 0, ByRef driver As String = "" )

Usage
   ScreenInfo [ w ] [, [ h ] [, [ depth ] [ , [ bpp ] [ , [ pitch ] [ , [ 
   rate ] [, driver ]]]]]

Parameters
   w
      Width.
   h
      Height.
   depth
      Color depth in bits.
   bpp
      Bytes per pixel.
   pitch
      Bytes per scan line.
   rate
      Refresh rate.
   driver
      Driver name.

Description
   This function can be useful to get current mode informations like 
   graphics driver name, color depth, screen size and more.

   If ScreenInfo is called when no graphics mode is set, it returns the 
   information about the desktop.

   Here's a description of available fields:

      +------+----------------------------------------------------------------------+
      |w     |Width of the screen in pixels                                         |
      |h     |Height of the screen in pixels                                        |
      |depth |Current pixel format bits per pixel: this can be 1, 2, 4, 8, 16, or 32|
      |bpp   |Bytes per pixel                                                       |
      |pitch |Size of a framebuffer row in bytes                                    |
      |rate  |Current refresh rate, or 0 if unknown                                 |
      |driver|Name of current graphics driver in use, like DirectX or X11           |
      +------+----------------------------------------------------------------------+

Example
   Dim w As Integer, h As Integer
   Dim depth As Integer
   Dim driver_name As String

   Screen 15, 32 
   ' Obtain info about current mode 
   ScreenInfo w, h, depth,,,,driver_name
   Print Str(w) + "x" + Str(h) + "x" + Str(depth); 
   Print " using " + driver_name + " driver" 
   Sleep 
   ' Quit graphics mode and obtain info about desktop 
   Screen 0 
   ScreenInfo w, h, depth 
   Print "Desktop running at " + Str(w) + "x" + Str(h) + "x" + Str(depth); 

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Screeninfo.

Differences from QB
   * New to FreeBASIC

See also
   * Screen (Graphics)



------------------------------------------------------- KeyPgScreenlist ----
ScreenList

Finds available fullscreen video modes

Syntax
   Declare Function ScreenList ( ByVal depth As Long = 0 ) As Long

Usage
   result = ScreenList( [ depth ] )

Parameters
   depth
      the color depth for which the list of modes is requested  (supported 
      depths are 8, 15, 16, 24 and 32)

Return Value
   returns 0, when there are no more resolutions to read.

Description
   It works like the Dir function: the first call to the function requires 
   the depth parameter to be specified, it  returns the lowest supported 
   resolution for the requested depth. Further calls to ScreenList without 
   arguments returns the next resolutions. When no more resolutions are 
   available, ScreenList returns 0.

   The result of ScreenList is encoded as a 32 bit value, with the screen 
   width as the High Word and the height as the Low Word.

   Resolutions are returned from lowest to highest supported ones. 

   It is safe to call this function before any graphics mode has been set.

   Dim As Integer mode, w, h

   Print "Resolutions supported at 8 bits per pixel:"

   mode = ScreenList(8)
   While (mode <> 0)
      w = HiWord(mode)
      h = LoWord(mode)
      Print w & "x" & h
      mode = ScreenList()
   Wend

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Screenlist.

Differences from QB
   * New to FreeBASIC

See also
   * Screen
   * ScreenRes



------------------------------------------------------- KeyPgScreenlock ----
ScreenLock

Locks the working page's frame buffer

Syntax
   Declare Sub ScreenLock ( )

Usage
   ScreenLock

Description
   All of FreeBASIC's Graphics Library functions draw to a frame buffer and 
   an automatic routine copies the frame buffer to the actual screen memory 
   at each draw. If the user program does a lot of drawing, the automatic 
   refreshes may take a significant amount of time.

   The ScreenLock function locks the automatic refresh, so several drawing 
   operations may be done before the screen refresh is performed, thus 
   increasing the speed of execution, and preventing the user from seeing 
   partial results. 

   Frame buffer memory may be freely accessed by using pointers (see 
   ScreenPtr) ONLY while the screen is locked. Primitive graphics 
   statements (Line, PSet, Draw String, ...)  may be used at any time.

   The screen refresh remains locked until the use of ScreenUnlock 
   statement, which resumes it.  

   Calls to ScreenLock must be paired with a matching call to ScreenUnlock. 
   The graphics driver keeps track of how many times ScreenLock has been 
   called using a counter.  Only the first call to ScreenLock actually 
   performs a locking operation.  Subsequent calls to ScreenLock only 
   increment the counter.  Conversely, ScreenUnlock only decrements the 
   lock counter until it reaches zero at which time the actual unlock 
   operation will be performed.  Using Screen or ScreenRes will release all 
   locks and set the lock counter back to zero before changing screen 
   modes.

   It is strongly recommended that the lock on a page be held for as short 
   a time as possible. Only screen drawing should occur while the screen is 
   locked, input/output and waiting must be avoided. In Win32 and Linux the 
   screen is locked by stopping the thread that processes also the OS' 
   events. If the screen is kept locked for a long time the event queue 
   could overflow and make the system unstable. When the induced lock time 
   becomes too long, use preferably the method of double buffering (with 
   ScreenCopy).

   The automatic refresh takes place only in the visible page of the frame 
   buffer. ScreenLock has no effect when drawing to pages other than the 
   visible one. 	

Example

   '' Draws a circle on-screen at the mouse cursor
   Dim As Integer mx, my
   Dim As String key

   ScreenRes 640, 480, 32

   Do

     'process
     GetMouse(mx, my)
     key = Inkey()

     'draw
     ScreenLock()
     Cls()
     Circle (mx, my), 8, RGB(255, 255, 255)
     ScreenUnlock()

     'free up CPU time
     Sleep(18, 1)
     
   Loop Until key = Chr(27) Or key = Chr(255, 107)

Platform Differences
   * In DOS, the mouse arrow does not react to mouse movements while the 
     screen is locked

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Screenlock.

Differences from QB
   * New to FreeBASIC

See also
   * Screen (Graphics) - Setting mode
   * ScreenRes - Setting mode
   * ScreenUnlock
   * ScreenPtr



-------------------------------------------------------- KeyPgScreenptr ----
ScreenPtr

Returns a pointer to the current work page's frame buffer

Syntax
   Declare Function ScreenPtr ( ) As Any Ptr

Usage
   result = ScreenPtr

Return Value
   a pointer to the current work page frame buffer memory, or NULL (0) if 
   no graphics mode is set.

Description
   ScreenPtr provides a way to directly read/write the working page's frame 
   buffer. ScreenLock should be used before any read or writes are 
   attempted. The pointer returned is valid up until any subsequent call to 
   Screen or ScreenRes, which invalidates it.

   ScreenPtr can also be used to test if a call to Screen or ScreenRes was 
   successful, indicated by a non-NULL (<> 0) return value.

   In order to access a pixel in the screen buffer, you will need to know 
   the screen's bytes per pixel and pitch (bytes per row), and also the 
   width and height to avoid going out of bounds.  This information can be 
   found out using ScreenInfo.
   Each row in the frame buffer is pitch bytes long.  The frame buffer 
   consists of height rows, stored in order of their position on the 
   screen, running from top to bottom, left to right.

   Because of the design of FreeBASIC graphics library, ScreenPtr (if 
   non-NULL) will always point to the backbuffer, and never to actual video 
   RAM.

Example
   Const SCREEN_WIDTH = 640, SCREEN_HEIGHT = 480
   Dim As Integer w, h, bypp, pitch

   '' Make 8-bit screen.
   ScreenRes SCREEN_WIDTH, SCREEN_HEIGHT, 8

   '' Get screen info (w and h should match the constants above, bypp should be 1)
   ScreenInfo w, h, , bypp, pitch

   '' Get the address of the frame buffer. An Any Ptr 
   '' is used here to allow simple pointer arithmetic
   Dim buffer As Any Ptr = ScreenPtr()
   If (buffer = 0) Then
      Print "Error: graphics screen not initialized."
      Sleep
      End -1
   End If

   '' Lock the screen to allow direct frame buffer access
   ScreenLock()
      
      '' Find the address of the pixel in the centre of the screen
      '' It's an 8-bit pixel, so use a UByte Ptr.
      Dim As Integer x = w \ 2, y = h \ 2
      Dim As UByte Ptr pixel = buffer + (y * pitch) + (x * bypp)
      
      
      '' Set the pixel color to 10 (light green).
      *pixel = 10

   '' Unlock the screen.
   ScreenUnlock()

   '' Wait for the user to press a key before closing the program
   Sleep

   Const SCREEN_WIDTH = 256, SCREEN_HEIGHT = 256
   Dim As Integer w, h, bypp, pitch

   '' Make 32-bit screen.
   ScreenRes SCREEN_WIDTH, SCREEN_HEIGHT, 32

   '' Get screen info (w and h should match the constants above, bypp should be 4)
   ScreenInfo w, h, , bypp, pitch

   '' Get the address of the frame buffer. An Any Ptr 
   '' is used here to allow simple pointer arithmetic
   Dim buffer As Any Ptr = ScreenPtr()
   If (buffer = 0) Then
      Print "Error: graphics screen not initialized."
      Sleep
      End -1
   End If

   '' Lock the screen to allow direct frame buffer access
   ScreenLock()
      
      '' Set row address to the start of the buffer
      Dim As Any Ptr row = buffer
      
      '' Iterate over all the pixels in the screen:
      
      For y As Integer = 0 To h - 1
         
         '' Set pixel address to the start of the row
         '' It's a 32-bit pixel, so use a ULong Ptr
         Dim As ULong Ptr pixel = row
         
         For x As Integer = 0 To w - 1
            
            '' Set the pixel value
            *pixel = RGB(x, x Xor y, y) 
            
            '' Get the next pixel address 
            '' (ULong Ptr will increment by 4 bytes)
            pixel += 1
            
         Next x
         
         '' Go to the next row
         row += pitch
         
      Next y

   '' Unlock the screen.
   ScreenUnlock()

   '' Wait for the user to press a key before closing the program
   Sleep

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Screenptr.

Differences from QB
   * New to FreeBASIC

See also
   * Screen (Graphics)
   * ScreenRes
   * ScreenInfo
   * ScreenLock
   * ScreenUnlock



-------------------------------------------------------- KeyPgScreenres ----
ScreenRes

Initializes a graphics mode by specifying horizontal and vertical 
resolution

Syntax
   Declare Function ScreenRes ( ByVal width As Long, ByVal height As Long, 
   ByVal depth As Long = 8, ByVal num_pages As Long = 1, ByVal flags As Long
   = 0, ByVal refresh_rate As Long = 0 ) As Long
 
Usage
   ScreenRes width, height [, [depth] [, [num_pages] [, [flags] [, 
   refresh_rate ]]]]
   result = ScreenRes( width, height [, [depth] [, [num_pages] [, [flags] 
   [, refresh_rate ]]]] )

Parameters
   width, height
      The display width and height, respectively. For fullscreen mode, the 
      user should check the availability of the resolution using ScreenList
      .
   depth
      The color depth in bits per pixel. Valid color depths are: 1, 2, 4, 8
      , 16 and 32.  Values of 15 and 24 are also allowed as aliases for 16 
      and 32, respectively.  If omitted, the default is 8 bits per pixel.  
      8 bits and below will give a palette image.  The default palette will 
      be the first 2 ^ depth colors of the 256-color palette used in Screen 
      13.
   num_pages
      The number of video pages to create, defaults to 1. (see below)
   flags
      Used to set various properties of the screen, including fullscreen 
      mode and graphics driver priority. (see below or the standard header 
      "fbgfx.bi" for available flags)
   refresh_rate
      The desired refresh rate of the screen, only has an effect for 
      fullscreen modes, and some systems and drivers only. Defaults to an 
      appropriate value, invalid refresh rates will be ignored.

Return Value
   Returns zero (0) if successful, or a non-zero error code to indicate a 
   failure. (throws a runtime error) (???)

Description
   ScreenRes tells the compiler to link the GfxLib and initializes a 
   QB-only, QB-on-GUI or OpenGL graphics mode, depending on the flags 
   setting.

   ScreenRes  clears the created window or the full screen. In 
   non-fullscreen modes, the resolution does not have to match any 
   resolution of the graphics card. Resolutions like 555x111 are possible, 
   GfxLib will create a window of such size. See the page GfxLib overview 
   for DOS issues.

   The font size in ScreenRes modes is set to 8x8 by default.  This can be 
   changed by setting the number of text rows/columns, using the Width 
   function.

   In QB-only modes a dumb window or fullscreen resolution is set, one or 
   more buffers in standard memory are created,  console commands are 
   redirected to their graphic versions, a default palette is set and an 
   automatic screen refresh thread is started. QB-like graphics and console 
   statements can be used.  

    In QB-on-GUI modes one or more buffers in standard memory are created,  
   console commands are redirected to their graphic versions and a 
   default palette is set. QB-like  graphics and console statements can be 
   used.  It is up to the user to create a window and to refresh it with 
   the contents of the graphics buffers.

   In OpenGL modes a dumb window or fullscreen resolution is set, one or 
   more buffers in standard memory are created, and the system's OpenGL 
   library is initialized. From here only OpenGL commands can be used to 
   write to the graphics buffer. QB-like and console commands are 
   forbidden. This mode allows to initialize OpenGL in a portable way.

   The error code returned by ScreenRes can be checked using Err in the 
   next line. The function version of  ScreenRes returns directly the error 
   code as a 32 bit Long.

flags details:

   If flags are omitted, FreeBASIC uses QB-compatible graphics in windowed 
   (except in DOS) mode.  These constants are defined in fbgfx.bi.  In the 
   -lang fb dialect, these constants are part of the FB Namespace. Their 
   values can be combined to form a mask using Operator Or. Note that most 
   of the flags are not supported in DOS.

   Available flags:

   graphic mode flags
      GFX_NULL: Starts a QB-on-GUI graphics mode.  It creates a graphics 
      buffer but not a window.  User must implement the window, the events 
      manager and refresh the screen as needed.  This mode allows to mix 
      FreeBASIC drawing functions with API-driven windows.  Alternatively, 
      it allows to process graphics (for example files) without making it 
      visible on the screen, even in a purely console application.  This 
      flag overrides all other mode flags.  See an Example of GFX_NULL in 
      Windows.
      GFX_OPENGL: Initializes OpenGL to draw in a dumb window. FreeBASIC 
      graphic functions can't be used.  The screen is not automatically 
      updated, Flip must be used.  This option provides a portable way to 
      initialize the OpenGL Library.
      If none of the above options is specified, FreeBASIC enters the 
      QB-only graphics mode: it creates a buffer and a dumb window and sets 
      a thread that automatically updates the screen and manages keyboard 
      and mouse.  The FreeBASIC drawing functions can be used.

   window mode flags
      Window mode flags are meaningless if  GFX_NULL mode is used
      GFX_WINDOWED: If windowed mode is supported, FreeBASIC opens a window 
      of the requested size in the present desktop
      GFX_FULLSCREEN: The graphics card switch mode is switched to the 
      requested mode and color depth and OS fullscreen mode is used.  If 
      the mode is not available in the present card FreeBASIC switches to 
      windowed mode.
      If GFX_FULLSCREEN is not specified, the behavior for GFX_WINDOWED is 
      assumed.
      GFX_NO_SWITCH: Prevents the user from changing to fullscreen or to 
      windowed mode by pressing Alt-Enter.
      GFX_NO_FRAME: Creates a window without a border.
      GFX_SHAPED_WINDOW: Creates transparent regions wherever RGBA(255, 0, 
      255, 0) is drawn on the screen.
      GFX_ALWAYS_ON_TOP: Creates a window that stays always on top.

   option flags
      Flags working in any mode, they activate special behaviors
      GFX_ALPHA_PRIMITIVES: Tells the graphics library to enable alpha 
      channel support for all drawing primitives. This means the alpha 
      specified in a color value (via either the RGBA macro or direct color 
      in the form &hAARRGGBB) will always be used by all primitives.
      GFX_HIGH_PRIORITY: Tells the graphics library to enable a higher 
      priority for graphics processing.  Only has an effect on gdi and 
      DirectX drivers on Win32 platform.

   OpenGL Buffer flags
      These flags work only in OpenGL graphics mode, must be combined with 
      GFX_OPENGL
      GFX_STENCIL_BUFFER: Forces OpenGL to use Stencil buffer 
      GFX_ACCUMULATION_BUFFER: Forces OpenGL to use Accumulation buffer
      GFX_MULTISAMPLE: Requests fullscreen anti-aliasing through the 
      ARB_multisample extension

   Depending on whether the GFX_FULLSCREEN parameter is present or not, 
   Screen will try to set the specified video mode in fullscreen or 
   windowed mode, respectively.  If fullscreen mode is set and the system 
   cannot set specified mode in fullscreen, it will try in windowed mode. 
   If windowed mode is set and the system fails to open a window for 
   specified mode, it will try fullscreen.  If everything fails, Screen 
   will have no effect and execution will resume from the statement 
   following the Screen call.  You should take care of checking if a 
   graphics mode has been set or not, and behave accordingly; a way to 
   check if Screen is successful is to test the return value of the 
   ScreenPtr function; see its page for details.

Graphics mode console
   Console commands (Locate, Print), input can be used both with standard 
   QB Screen modes and with the extended ones too, provided the standard 
   color depth is not modified by using the second argument of Screen. 
   Where the table says more than one text resolution is available for the 
   text mode, the required text resolution can be requested by using Width. 
   Any characters Printed will erase the background around them; it does 
   not use a transparent background.

Example
   ' Set the screen mode to 320*200, with 8 bits per pixel
   ScreenRes 320, 200, 8

   ' Draw color bands in a diagonal pattern over the whole screen
   For y As Integer = 0 To 200-1
      For x As Integer = 0 To 320-1
         PSet (x,y),(x + y) And 255
      Next x
   Next y

   ' Display the text "Hello World!!" over the lines we've drawn, in the top-left hand corner
   Print "Hello world!!"

   ' Keep the window open until the user presses a key
   Sleep

Platform Differences
   * In DOS, Windowing and OpenGL related switches are not available, and 
     other issues, see GfxLib overview

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Screenres.

Differences from QB
   * New to FreeBASIC

See also
   * Screen The QB-like way to set graphics mode
   * ScreenList Check display modes available for FB GfxLib to use
   * ScreenControl Select driver and more 
   * ScreenLock
   * ScreenUnlock
   * ScreenPtr Semi-low level access
   * ScreenSet
   * ScreenCopy
   * ScreenInfo
   * ScreenGLProc
   * Internal pixel formats
   * FaqPggfxlib2



-------------------------------------------------------- KeyPgScreenset ----
ScreenSet

Sets current work and visible pages

Syntax
   Declare Sub ScreenSet ( ByVal work_page As Long = -1, ByVal visible_page 
   As Long = -1 )

Usage
   ScreenSet [ work_page ] [, visible_page ]

Parameters
   work_page
      index to working page
   visible_page
      index to visible page

Description
   ScreenSet allows to set the current working page and the current visible 
   page. Page numbers range from 0 to num_pages - 1, where num_pages is the 
   number of pages specified when setting the graphics mode with ScreenRes 
   or Screen.  You can use this function to achieve page-flipping or 
   double-buffering.

   If you provide visible_page but omit work_page, only the visible page is 
   changed. If you provide work_page but omit visible_page, only the work 
   page is changed. If you omit both arguments, both work page and visible 
   page are reset to page 0.

   ScreenSet provides one method of writing to the screen without instantly 
   displaying changes to the user.  See also ScreenLock / ScreenUnlock for 
   an alternative method of doing this.

   Note: The current cursor position is not handled independently for each 
   video page. Therefore, when another working page is selected, the 
   starting cursor position corresponds to the last cursor position on the 
   previous working page (same behavior for the text cursor and the 
   graphics cursor).

Example
   ' Open graphics screen (320*200, 8bpp) with 2 pages
   ScreenRes 320, 200, 8, 2

   ' Work on page 1 while displaying page 0
   ScreenSet 1, 0

   Dim As Integer x = -40

   Do
      '' Clear the screen, draw a box, update x
      Cls
      Line (x, 80)-Step(39, 39), 4, BF
      x += 1: If (x > 319) Then x = -40
      
      ' Wait for vertical sync: only used to control refresh rate, can be put anywhere in the Do loop
      ScreenSync
      
      ' Copy work page to visible page
      ScreenCopy
      
   Loop While Inkey = ""

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Screenset.

Differences from QB
   * New to FreeBASIC

See also
   * Screen (Graphics)
   * ScreenRes
   * ScreenCopy
   * ScreenLock
   * ScreenUnlock



------------------------------------------------------- KeyPgScreensync ----
ScreenSync

Synchronizes display updates with hardware

Syntax
   Declare Function ScreenSync ( ) As Long

Usage
   result = ScreenSync

Return Value
   Zero if successful, or non-zero if a graphics mode was not previously 
   set.

Description
   This GfxLib statement stops the execution of the program until the 
   graphics card signals it has ended tracing a frame and is going to start 
   the new one.

   If the program uses this small interval of time between frames to redraw 
   the image, the flickering is greatly reduced. In that use, ScreenSync is 
   a reminiscence of QB where there was only that equivalent method (Wait 
   &H3DA, 8) to improve the flickering. It is an empirical method because 
   it only allows to synchronize the beginning of the drawing with the 
   fixed dead time between two frames. To be used occasionally to avoid 
   flickering when only very short time of drawing.

   Except the purpose to reduce the flickering, ScreenSync can be also used 
   simply as a method of synchronization of graphic drawing with the screen 
   frame tracing (similarly to statement Sleep).

   The error code returned by ScreenSync can be checked using Err in the 
   next line. The function version of  ScreenSync returns directly the 
   error code as a 32 bit Long.

   The use of the QB-compatible form Wait &H3DA, 8 is deprecated.

Example
   'main loop
   Do
     
     ' do user input
     ' calculate_a_frame
      
     ScreenSync
     
     ' draw_ a_ frame  
     
   Loop Until Inkey <> ""

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Screensync.

Differences from QB
   * New to FreeBASIC. 
   * QBasic used Wait &H3DA, 8 for this purpose.

See also
   * Wait



----------------------------------------------------- KeyPgScreenunlock ----
ScreenUnlock

Unlocks work page's framebuffer

Syntax
   Declare Sub ScreenUnlock ( ByVal startline As Long = -1, ByVal endline As
   Long = -1 )

Usage
   ScreenUnlock [ start_line ] [, end_line ]

Parameters
   startline
      optional argument specifying first screen line to be updated. If 
      omitted, top screen line is assumed.
   endline
      optional argument specifying last screen line to be updated. If 
      omitted, bottom screen line is assumed.

Description
   ScreenUnlock unlocks the current work page assuming it was previously 
   locked by calling ScreenLock and lets the system restart updating the 
   screen regularly. When called with start_line and end_line , only the 
   screen area between those lines is assumed to have changed, and will be 
   updated. 

   An internal counter exists that remembers the screen lock state, thus 
   ScreenUnlock has an effect only on a screen that is locked.  A screen 
   that has not been locked with ScreenLock cannot get unlocked, however 
   ScreenUnlock still will force an update of given area or full screen.   

   Calls to ScreenUnlock must be paired with matching calls to ScreenLock.  
   Only the first call to ScreenLock actually performs a locking operation. 
   Subsequent calls to ScreenLock only increment the lock counter.  
   Conversely, ScreenUnlock only decrements the lock counter until it 
   reaches zero at which time the actual unlock operation will be 
   performed.  Using Screen or ScreenRes will release all locks and set the 
   lock counter back to zero before changing screen modes.

   All graphic statements automatically lock the screen before the function 
   call, and unlock the screen afterwards, so you do not need to do this 
   explicitly using ScreenLock and ScreenUnlock. You only need to lock the 
   screen when you wish to access the screen (framebuffer) directly using 
   ScreenPtr  or when you wish to group several graphic statements together 
   so their effects appear simultaneously on screen, thus avoiding 
   potential screen flicker during screen updates.

   Warning (Win32, Linux) : The screen is locked by stopping the thread 
   that processes also the OS' events. This means the screen should be 
   locked only for the short time required to redraw it, and no user input 
   will be received while the screen is locked. When the induced lock time 
   becomes too long, use preferably the method of double buffering (with 
   ScreenCopy).

Example
   See ScreenPtr example.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Screenunlock.

Differences from QB
   * New to FreeBASIC

See also
   * Screen (Graphics)
   * ScreenLock
   * ScreenPtr



----------------------------------------------------------- KeyPgSecond ----
Second

Gets the seconds from a Date Serial 

Syntax
   Declare Function Second ( ByVal date_serial As Double ) As Long

Usage
   #include "vbcompat.bi"
   result = Second( date_serial )

Parameters
   date_serial
      the date serial

Return Value
   Returns the seconds from a  variable containing a date in  Date Serial  
   format.

Description
    
   The compiler will not recognize this function unless vbcompat.bi is 
   included.

Example
   #include "vbcompat.bi"

   Dim ds As Double = DateSerial(2005, 11, 28) + TimeSerial(7, 30, 50)

   Print Format(ds, "yyyy/mm/dd hh:mm:ss "); Second(ds)

Differences from QB
   * Did not exist in QB. This function appeared in PDS and VBDOS

See also
   * Date Serials



---------------------------------------------------------- KeyPgSeekset ----
Seek (Statement)

Sets the position of the next read/write operation on a file

Syntax
   Seek [#]filenum, position

Parameters
   filenum
      file number of an opened a file
   position
      the new position for i/o operations

Description
   Sets the position at which the next read or write operation on a file 
   will occur.

   The position is given in records if the file was opened in Random access 
   mode, in bytes in any other case. The position is 1 based -- the first 
   record of a file is at position 1.

   The Seek function is used to get the position of the next read or write 
   operation.

Example
   ' e.g. if you want to skip to the 100th byte in the file for reading/writing:

   Dim f As Integer

   f = FreeFile
   Open "file.ext" For Binary As #f

   Seek f, 100

   Close #f

Differences from QB
   * None

See also
   * Seek (Function)
   * Open



------------------------------------------------------- KeyPgSeekreturn ----
Seek (Function)

Gets the position of the next read/write operation for a file or device

Syntax
   Declare Function Seek ( ByVal filenum As Long ) As LongInt

Parameters
   filenum
      file number of an open file

Return Value
   The file position where the next read or write operation will take 
   place.

Description
   The position is given in records if the file was opened in Random access 
   mode, in bytes in any other case. The file position returned is 1-based, 
   so the first record of a file is 1.

   The Seek statement is used to set the position of the next read or write 
   operation.

Example
   Dim f As Integer, position As Integer

   f = FreeFile
   Open "file.ext" For Binary As #f

   position = Seek(f)

   Close #f

Differences from QB
   * None

See also
   * Seek (Statement)
   * LOC
   * Open



------------------------------------------------------- KeyPgSelectcase ----
Select Case

Conditional statement block

Syntax
   Select Case expression
   [ Case expressionlist] 
      [statements]
   [ Case Else ]
      [statements]
   End Select
or
   Select Case As Const integer_expression
   [ Case constant | enumeration ]
      [ statements ]
   [ Case Else ]
      [ statements ]
   End Select

Description
   Select Case executes specific code depending on the value of an 
   expression. The expression is evaluated once, and compared against each 
   Case, in order, until a matching expression is found. The code inside 
   the matching Case branch is executed, and the program skips down to the 
   end of the Select Case block. Case Else matches any case not already 
   matched, so if there is a Case Else, at least one Case is guaranteed to 
   be executed. If no Cases match, the whole Select Case block will be 
   skipped.

   End Select is used to close the Select Case...End Select block.

   Note for C users: In FreeBASIC, Select Case works like a switch block 
   where all cases have a break at the end. As there is no fall-through, 
   multiple options must be put in an expression list in a single Case.

   Besides integer types, floating point and string expressions are also 
   supported with the first syntax.  

   Syntax of an expression list:
   { expression | expression To expression | Is relational operator 
   expression }[, ...]

   * expr: evaluates expr, and compares for equality with the original 
     expression.  If they are equal, then a match has been found.  This 
     could be considered as a shorthand for "Is = expr" (see below).
   * expr1 To expr2: evaluates expr1 and checks to see if it is less than 
     or equal to the original expression.  If so, it evaluates expr2, and 
     checks to see if it is greater than or equal to the original 
     expression.  If so, then a match has been found.
   * Is relational_operator expr: evaluates expr, and compares the 
     original operation against it, using the supplied relational_operator 
     (=, >, <, <>, <=, >=).  If the comparison is true, then a match has 
     been found.

   Multiple checks can be made in each Case, by separating them by a comma 
   (,).  Once a match is found, the program finishes its checks, and goes 
   on to execute the code statements for that Case block.  No further 
   expressions are evaluated or checked.

   example of expression lists:
      +--------------------+-----------------------------+
      |Case 1              |constant                     |
      |Case 5.4 To 10.1    |range                        |
      |Case Is > 3         |bigger than-smaller than     |
      |Case 1, 3, 5, 7 to 9|match against a set of values|
      |Case x              |value of a variable          |
      +--------------------+-----------------------------+

   If As Const is used, only integer constants (all numeric constants 
   excluding the two floating-point constants: single and double) can be 
   evaluated and the expression list supports simple constants and 
   enumerations only. "To" ranges are supported, but "Is" relational 
   operators are not.

   With As Const, a jump table is created to contain the full range of 
   integer Cases handled.  This allows Select Case As Const to be faster 
   than Select Case.
   However, the size of the range of values is limited, and after 
   converting the values to the uinteger type, the largest value in the 
   range may be no higher than the smallest value + 8191 (current 
   implementation).

Example

   Dim choice As Integer

   Input "Choose a number between 1 and 10: "; choice

   Select Case As Const choice
   Case 1
      Print "number is 1"
   Case 2
      Print "number is 2"
   Case 3, 4
      Print "number is 3 or 4"
   Case 5 To 10
      Print "number is in the range of 5 to 10"
   Case Else
      Print "number is outside the 1-10 range"
   End Select

   '' SELECT CASE vs. SELECT CASE AS CONST speed test

   Const N = 50000000

   Dim As Integer dummy = 0
   Dim As Double t = Timer()

   For i As Integer = 1 To N
      Select Case i
      Case 1, 3, 5, 7, 9
         dummy += 1
      Case 2, 4, 6, 8, 10
         dummy += 1
      Case 11 To 20
         dummy += 1
      Case 21 To 30
         dummy += 1
      Case 31
         dummy += 1
      Case 32
         dummy += 1
      Case 33
         dummy += 1
      Case Is >= 34
         dummy += 1
      Case Else
         Print "can't happen"
      End Select
   Next

   Print Using "SELECT CASE: ##.### seconds"; Timer() - t
   t = Timer()

   For i As Integer = 1 To N
      Select Case As Const i
      Case 1, 3, 5, 7, 9
         dummy += 1
      Case 2, 4, 6, 8, 10
         dummy += 1
      Case 11 To 20
         dummy += 1
      Case 21 To 30
         dummy += 1
      Case 31
         dummy += 1
      Case 32
         dummy += 1
      Case 33
         dummy += 1
      Case Else
         If( i >= 34 ) Then
            dummy += 1
         Else
            Print "can't happen"
         End If
      End Select
   Next

   Print Using "SELECT CASE AS CONST: ##.### seconds"; Timer() - t
   Sleep

Differences from QB
   * Select Case As Const did not exist in QB
   * in an "expr1 TO expr2" case, QB would always evaluate both 
     expressions, even if expr1 was higher than the original expression.
   * In the -lang qb and -lang fblite dialects, variables declared inside 
     a Select..End Select block have a function-wide scope as in QB.
   * In the -lang fb and -lang deprecated dialects, variables declared 
     inside a Select..End Select block are visible only inside the block, 
     and can't be accessed outside it.

See also
   * If...Then



---------------------------------------------------------- KeyPgSetdate ----
SetDate

Sets the current system date

Syntax
   Declare Function SetDate ( ByRef newdate As Const String ) As Long

Usage
   result = SetDate( newdate )

Parameters
   newdate
      the new date to set

Return Value
   Returns zero on success or non-zero on failure on all ports except DOS.

Description
   To set the date you just format newdate and send to SetDate in a valid 
   format following one of the following: "mm-dd-yy", "mm-dd-yyyy", 
   "mm/dd/yy", or "mm/dd/yyyy" (mm is the month, dd is the day, yy or yyyy 
   is the year). Two-digit year numbers are based on the year 1900.

   The error code returned by SetDate can be checked using Err in the next 
   line. The function version of  SetDate returns directly the error code 
   as a 32 bit Long.

Example
   Dim m As String, d As String, y As String
   m = "03" 'march
   d = "13" 'the 13th
   y = "1994" 'good ol' days
   SetDate m + "/" + d + "/" + y

Platform Differences
   * On Windows the privilege SE_SYSTEMTIME_NAME is required, which 
     typically means that the calling process has to be run with 
     administrator privileges.
   * On Linux the capability CAP_SYS_TIME is required, which typically 
     means that the calling process has to run as root/superuser.

Differences from QB
   * The DATE statement was used in QB and the syntax was "DATE = string"

See also
   * Date
   * SetTime



------------------------------------------------------- KeyPgSetenviron ----
SetEnviron

Sets a system environment variable

Syntax
   Declare Function SetEnviron ( ByRef varexpression As String ) As Long

Usage
   result = SetEnviron( varexpression )

Parameters
   varexpression
      Name and setting of an environment variable in the following (or 
      equivalent) form: varname=varstring.
      (varname being the name of the environment variable, and varstring 
      being its text value to set)

Return Value
   Return zero (0) if successful, non-zero otherwise.

Description
   Modifies system environment variables.  There are several variables 
   available for editing other than the default ones on your system.  An 
   example of this would be fbgfx, where you can choose the form of 
   graphics driver the FreeBASIC graphics library will use.

Example
   'e.g. to set the system variable "path" to "c:":

   Shell "set path" 'shows the value of path
   SetEnviron "path=c:"
   Shell "set path" 'shows the new value of path

     '' WINDOWS ONLY EXAMPLE! - We just set the graphics method to use
     '' GDI rather than DirectX.
     '' You may note a difference in FPS.
   SetEnviron("fbgfx=GDI")

     '' Desktop width/height
   Dim As Integer ScrW, ScrH, BPP
   ScreenInfo ScrW, ScrH, BPP

     '' Create a screen at the width/height of your monitor.
     '' Normally this would be slow, but GDI is fairly fast for this kind
     '' of thing.
   ScreenRes ScrW, ScrH, BPP

     '' Start our timer/
   Dim As Double T = Timer

     '' Lock our page
   ScreenLock
   Do
     
      '' Print time since last frame
     Locate 1, 1
     Print "FPS: " & 1 / ( Timer - T )
     T = Timer
     
      '' Flip our screen
     ScreenUnlock
     ScreenLock
      '' Commit a graphical change to our screen.
     Cls
     
   Loop Until Len(Inkey)

     '' unlock our page.
   ScreenUnlock

Differences from QB
   * In QB, SetEnviron was called Environ.

See also
   * Environ
   * Shell



--------------------------------------------------------- KeyPgSetmouse ----
SetMouse

Sets the position and visibility of the mouse cursor

Syntax
   Declare Function SetMouse ( ByVal x As Long = -1, ByVal y As Long = -1, 
   ByVal visibility As Long = -1, ByVal clip As Long = -1 ) As Long

Usage
   result = SetMouse([ x ] [, [ y ] [, [ visibility ] [, [ clip ]]]])

Parameters
   (For each parameter, -1 is a special value indicating "no changes.")
   x
      optional - set x coordinate
   y
      optional - set y coordinate
   visibility
      optional - set visibility: 1 indicates visible, 0 indicates hidden
   clip
      optional - set clipping: 1 indicates mouse is clipped to graphics 
      window, 0 indicates no clipping

Return Value
   Zero (0) on success, non-zero to indicate failure.

Description
   SetMouse will set the (x, y) coordinates of the mouse pointer, as well 
   as setting its visibility.  The mouse position is set using the x and y 
   parameters.  The mouse will be visible if visibility is set to 1, and 
   invisible if visibility is set to 0.  SetMouse is intended for graphics 
   modes initiated using the Screen (Graphics) statement only.

   The error code returned by SetMouse can be checked using Err in the next 
   line. The function version of  SetMouse returns directly the error code 
   as a 32 bit Long.

Example
   Dim As Integer x, y, buttons

   ' create a screen 640*480
   ScreenRes 640, 480
   Print "Click the mouse button to center the mouse"

   Do
      ' get mouse x, y and button state (wait until mouse is onscreen)
      Do: Sleep 1: Loop While GetMouse( x, y , , buttons) <> 0

      If buttons And 1 Then
         ' on left mouse click, center mouse
         SetMouse 320, 240
      End If

      ' run loop until a key is pressed or the window is closed
   Loop While Inkey = ""

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Setmouse.

Differences from QB
   * New to FreeBASIC

See also
   * GetMouse
   * Screen
   * MultiKey
   * GetKey



---------------------------------------------------------- KeyPgSettime ----
SetTime

Sets the current system time

Syntax
   Declare Function SetTime ( ByRef newtime As Const String ) As Long

Usage
   result = SetTime( newtime )

Parameters
   newtime
      the new time to set

Return Value
   Returns zero on success or non-zero on failure on all ports except DOS.

Description
   To set the time, format the date and send to Settime in one of the 
   following formats: "hh:mm:ss", "hh:mm", or "hh" (hh is the hour, mm is 
   the minute, and ss is the second).

   The error code returned by SetTime can be checked using Err in the next 
   line. The function version of  SetTime returns directly the error code 
   as a 32 bit Long.

Example
   SetTime "1:20:30"

Platform Differences
   * On Windows the privilege SE_SYSTEMTIME_NAME is required, which 
     typically means that the calling process has to be run with 
     administrator privileges.
   * On Linux the capability CAP_SYS_TIME is required, which typically 
     means that the calling process has to be run as root/superuser.

Differences from QB
   * The Time statement was used QB and the syntax was TIME = newtime.

See also
   * Time
   * SetDate



-------------------------------------------------------------- KeyPgSgn ----
Sgn

Returns the sign part of a number

Syntax
   Declare Function Sgn ( ByVal number As Integer ) As Integer
   Declare Function Sgn ( ByVal number As LongInt ) As LongInt
   Declare Function Sgn ( ByVal number As Double ) As Double

Usage
   result = Sgn( number )

Parameters
   number
      the number to find the sign of

Return Value
   Returns the sign part of number.
   * If number is greater than zero, then Sgn returns 1.
   * If number is equal to zero, then Sgn returns 0.
   * If number is less than zero, then Sgn returns -1.

Description
   The required number argument can be any valid numeric expression.  
   Unsigned numbers will be treated as if they were signed, i.e. if the 
   highest bit is set the number will be treated as negative, and -1 will 
   be returned.

   The Sgn unary Operator can be overloaded with user defined types.

Example
   Dim N As Integer = 0

   Print Sgn ( -1.87 )
   Print Sgn ( 0 )
   Print Sgn ( 42.658 )
   Print Sgn ( N )

The output would look like:

   -1
   0
   1
   0

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * None

See also
   * Abs
   * Operator



----------------------------------------------------------- KeyPgShared ----
Shared

Variable declaration modifier specifying visibility throughout a module

Syntax
   Dim Shared ...
   ReDim Shared ...
   Common Shared ...
   Static Shared ...
   Var Shared ...

Description
   Shared makes module-level variables visible inside Subs and Functions.
   If Shared is not used on a module-level variable's declaration, the 
   variable is only visible to the module-level code in that file 
   (furthermore, only a variable declared with Dim without Shared modifier, 
   and not inside a Namespace block, is stored on the stack).

   NOTES (for Shared variables excluding Common variables):
      * Generally a Shared variable may only be initialized with a 
        constant value (its starting value is set at the start of the 
        program in the .data section before any code is run, and so it 
        cannot depend on any variables or functions in it).
      * A first exception is a Shared variable of var-len string type, 
        that never can be initialized, even with a constant string (because 
        of its structure with a descriptor in the .data section, but to 
        point to a dynamic memory block).
      * A second exception is a Shared variable of user-defined type 
        having a constructor even implicit, that can be initialized with a 
        non-constant value (because it's the constructor code, called when 
        the program starts, which writes the "initial" values into the 
        .data section).

Example
   '' Compile with -lang qb or fblite

   '$lang: "qb"

   Declare Sub MySub
   Dim Shared x As Integer
   Dim y As Integer

   x = 10
   y = 5

   MySub

   Sub MySub
      Print "x is "; x 'this will report 10 as it is shared
      Print "y is "; y 'this will not report 5 because it is not shared
   End Sub

Differences from QB
   * The Shared statement inside scope blocks -- functions, subs, 
     if/thens, and loops -- is not supported. Use Dim|Redim|Common|Static 
     Shared in the main program instead.  Or if you're inside a scope block 
     and Redimming a variable or array previously set up with Shared, just 
     do a Redim without Shared; it will work fine and won't ruin anything.

See also
   * Common
   * Dim
   * Erase
   * Extern
   * LBound
   * ReDim
   * Preserve
   * Static
   * UBound
   * Var
   * Byref (Variables)



------------------------------------------------------------ KeyPgShell ----
Shell

Sends a command to the system command interpreter

Syntax
   Declare Function Shell ( ByRef command As Const String ) As Long

Usage
   result = Shell( command )

Parameters
   command
      A string specifying the command to send to the command interpreter.

Return Value
   If the command could not be executed, -1 is returned. Otherwise, the 
   command is executed and its exit code is returned.

Description
   Program execution will be suspended until the command interpreter exits.

Example
   'e.g. for windows:
   Shell "dir c:*.*"

   'e.g. for linux:
   Shell "ls"

Platform Differences
   * Linux requires the command case matches the real name of the command. 
     Windows and DOS are case insensitive. The program being shelled may be 
     case sensitive for its command line parameters. 
   * Path separators in Linux are forward slashes / . Windows uses 
     backward slashes \ but it allows for forward slashes.  DOS uses 
     backward  \ slashes.
   * If an empty command string is passed, DOS will open an interactive 
     command prompt.  On Windows, an error may be returned.

Differences from QB
   * QB allowed SHELL on its own without a "command" argument which caused 
     a default command shell to be started.  Execution in the main program 
     would suspend until exit from the command shell.  The behaviour in FB 
     is platform-dependent.

See also
   * Exec
   * Run



------------------------------------------------------ KeyPgOpShiftLeft ----
Operator Shl (Shift Left)

Shifts the bits of a numeric expression to the left

Syntax
   Declare Operator Shl ( ByRef lhs As Integer, ByRef rhs As Integer ) As 
   Integer
   Declare Operator Shl ( ByRef lhs As UInteger, ByRef rhs As UInteger ) As 
   UInteger

Usage
   result = lhs Shl rhs

Parameters
   lhs
      The left-hand side expression.
   rhs
      The right-hand side shift expression.

Return Value
   Returns the result of lhs being shifted left rhs number of times.

Description
   Operator Shl (Shift left) shifts all of the bits in the left-hand side 
   expression (lhs) left a number of times specified by the right-hand side 
   expression (rhs). Numerically, the result is the same as "CInt( lhs * 2 ^
   rhs )". For example, "&b0101 Shl 1" returns the binary number &b01010, 
   and "5 Shl 1" returns 10.

   Neither of the operands are modified in any way.

   If the result is too large to fit inside the result's data type, the 
   leftmost bits are discarded ("shifted out").
   The results of this operation are undefined for values of rhs less than 
   zero, or greater than or equal to the number of bits in the result's 
   data type.

   This operator can be overloaded for user-defined types.

Example
   'Double a number
   For i As Integer = 0 To 10
      
      Print 5 Shl i, Bin(5 Shl i, 16)
      
   Next i

Output:

    5            0000000000000101
    10           0000000000001010
    20           0000000000010100
    40           0000000000101000
    80           0000000001010000
    160          0000000010100000
    320          0000000101000000
    640          0000001010000000
    1280         0000010100000000
    2560         0000101000000000
    5120         0001010000000000

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Shl.

Differences from QB
   * New to FreeBASIC

See also
   * Operator Shl= (Shift Left And Assign)
   * Operator Shr (Shift Right)
   * Bin
   * Mathematical Functions



------------------------------------------------------------ KeyPgShort ----
Short

Standard data type: 16 bit signed

Syntax
   Dim variable As Short

Description
   16-bit signed whole-number data type. Can hold values from -32768 to 
   32767.

Example
     Dim x As Short = CShort(&H8000)
     Dim y As Short = CShort(&H7FFF)
     Print "Short Range = "; x; " to "; y

   Output:
   Short Range = -32768 To  32767

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Short.

Differences from QB
   * The name "short" is new to FreeBASIC, however they are the same as 
     integers in QB

See also
   * UShort
   * CShort



----------------------------------------------------- KeyPgOpShiftRight ----
Operator Shr (Shift Right)

Shifts the bits of a numeric expression to the right

Syntax
   Declare Operator Shr ( ByRef lhs As Integer, ByRef rhs As Integer ) As 
   Integer
   Declare Operator Shr ( ByRef lhs As UInteger, ByRef rhs As UInteger ) As 
   UInteger

Usage
   result = lhs Shr rhs

Parameters
   lhs
      The left-hand side expression.
   rhs
      The right-hand side shift expression.

Return Value
   Returns the result of lhs being shifted right rhs number of times.

Description
   Operator Shr (Shift right) shifts all of the bits in the left-hand side 
   expression (lhs) right a number of times specified by the right-hand 
   side expression (rhs). Numerically, the result is the same as "Int(lhs / 
   2 ^ rhs)". For example, "&b0101 Shr 1" returns the binary number &b010, 
   and "5 Shr 1" returns 2.

   If the left-hand side expression is signed and negative, the sign bit is 
   copied in the newly created bits on the left after the shift.  For 
   example, "-5 Shr 2" returns -2.

   Neither of the operands are modified in any way.

   The results of this operation are undefined for values of rhs less than 
   zero, or greater than or equal to the number of bits in the result's 
   data type.

   This operator can be overloaded for user-defined types.

Example
   'Halve a number
   For i As Integer = 0 To 10
      
      Print 1000 Shr i, Bin(1000 Shr i, 16)
      
   Next i

Output:

    1000         0000001111101000
    500          0000000111110100
    250          0000000011111010
    125          0000000001111101
    62           0000000000111110
    31           0000000000011111
    15           0000000000001111
    7            0000000000000111
    3            0000000000000011
    1            0000000000000001
    0            0000000000000000

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Shr.

Differences from QB
   * New to FreeBASIC

See also
   * Operator Shr= (Shift Right And Assign)
   * Operator Shl (Shift Left)
   * Bin
   * Mathematical Functions



-------------------------------------------------------------- KeyPgSin ----
Sin

Returns the sine of an angle

Syntax
   Declare Function Sin ( ByVal angle As Double ) As Double

Usage
   result = Sin( angle )

Parameters
   angle
      the angle (in radians)

Return Value
   Returns the sine of the argument angle as a Double within the range of 
   -1.0 to 1.0.

Description
   The argument angle is measured in radians (not degrees).

   The value returned by this function is undefined for values of angle 
   with an absolute value of 2 ^ 63 or greater.

   Sin can be overloaded as operator to accept user-defined types.

Example
   Const PI As Double = 3.1415926535897932
   Dim a As Double
   Dim r As Double
   Input "Please enter an angle in degrees: ", a
   r = a * PI / 180   'Convert the degrees to Radians
   Print ""
   Print "The sine of a" ; a; " degree angle is"; Sin ( r ) 
   Sleep

The output would look like:

   Please enter an angle in degrees: 30
   The sine of a 30 degree angle Is 0.5

Differences from QB
   * None

See also
   * Asin
   * Cos
   * Tan
   * A Brief Introduction To Trigonometry



----------------------------------------------------------- KeyPgSingle ----
Single

Standard data type: 32 bit floating point

Syntax
   Dim variable As Single

Description
   Single is a 32-bit, floating point data type used to store decimal 
   numbers. They can hold positive values in the range 1.401298e-45 to 
   3.402823e+38, or negative values in the range -1.401298e-45 to 
   -3.402823e+38, or zero (0).  They contain at most 24 bits of precision, 
   or about 6 decimal digits.

   They are similar to Double data types, but less precise. 

Example
   'Example of using a single variable.

   Dim a As Single
   a = 1.9857665
   Print a

   Sleep

Differences from QB
   * None

See also
   * Double More precise float type
   * CSng
   * Table with variable types overview, limits and suffixes



----------------------------------------------------------- KeyPgSizeof ----
SizeOf

Returns the size of a variable or type in bytes.

Syntax
   SizeOf ( variable | DataType )

Description
   The SizeOf operator returns an Integer value: the number of bytes taken 
   up by a variable or DataType.

   Different from Len, when used with fixed-length strings (including 
   fixed-length ZStrings and WStrings) it will return the number of bytes 
   they use, and when used with variable-length strings, it will return the 
   size of the string descriptor.

   When a variable from a given namespace is accessed with the namespace's 
   name prefix, wrap the argument to SizeOf with parentheses to force it to 
   be seen as an expression. For example Sizeof((namespace_name.variable)).

   If there is both a user defined type and a variable visible with the 
   same name in the current scope, the user defined type takes precedence 
   over the variable.  To ensure that the SizeOf takes the variable instead 
   of the user defined type, wrap the argument to SizeOf with parentheses 
   to force it to be seen as an expression.  For example Sizeof((variable))
   .

   Note: When used with arrays, SizeOf returns the size of a single element 
   of the array.  This differs from its behavior in C, where arrays could 
   only be a fixed size, and sizeof() would return the number of it used.
   For clarity, it is recommended that you avoid this potential confusion, 
   and use SizeOf directly on an array element or the array datatype doing 
   SizeOf(array(i)) or SizeOf(Typeof(array)), rather than the whole array 
   doing SizeOf(array).

   Remark: When used with a dereferenced z/wstring pointer, SizeOf always 
   returns the number of bytes taken up by one z/wstring character.

Example
   Print SizeOf(Byte) ' returns 1

   Type bar
      a As Integer
      b As Double
   End Type
   Dim foo As bar
   Print SizeOf(foo)

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Sizeof.

Differences from QB
   * New to FreeBASIC

See also
   * Len



------------------------------------------------------------ KeyPgSleep ----
Sleep

Waits until a specified time has elapsed, or a key is pressed.

Syntax
   Declare Sub Sleep ( ByVal amount As Long = -1 )
   Declare Function Sleep ( ByVal amount As Long , ByVal keyflag As Long ) 
   As Long

Usage
   Sleep [ amount [, keyflag ]]
   result = Sleep ( amount, keyflag )

Parameters
   amount
      Optional number of milliseconds to wait (default is to wait for a key 
      press).
   keyflag
      Optional flag; give it a value of 0 for a normal sleep, or 1 to 
      specify that the wait cannot be interrupted by a key press.

Return Value
   Returns 1 if keyflag was not a valid value (i.e. something other than 0 
   or 1) to indicate failure, or 0 otherwise.

Description
   Sleep will wait until amount milliseconds (can be seconds in -lang qb, 
   see below) given elapsed (if any value was passed) or until the user 
   presses a key. If amount is below 100 ms then Sleep will always wait the 
   full requested amount (key presses are ignored).

   Include the second parameter, 1, for a "deep" sleep, which cannot be 
   interrupted by pressing a key.

   The accuracy of Sleep is variable depending on the OS cycle time 
   (Windows NT/2K/XP: 15 ms, 9x/Me: 50 ms, Linux 10ms, DOS 55 ms).

   Call Sleep with 25ms or less to release time-slice when waiting for user 
   input or looping inside a thread.  This will prevent the program from 
   unnecessarily hogging the CPU.

   Sleep does not clear the keyboard buffer and any keys pressed during a 
   call to Sleep are retained and can be read using Inkey.  In order to 
   wait for a key press, and remove the key from the buffer, GetKey can be 
   used instead.

Example
   Print "press a key"
   Sleep
   GetKey 'clear the keyboard buffer
   Print "waiting half second"
   Sleep 500

Dialect Differences
   * In the -lang fb and -lang fblite dialects, the amount value is in 
     milliseconds.
   * In the -lang qb dialect, the amount value is in seconds as in QB. If 
     the second parameter keyflag is given, or the keyword is written as 
     __Sleep  the value is expected to be in milliseconds.

Differences from QB
   * None in the -lang qb dialect.
   * In QB, the delay was given in whole seconds only and did not support 
     the keyflag parameter.

See also
   * Timer
   * Inkey



------------------------------------------------------------ KeyPgSpace ----
Space

Creates a string of a given length filled with spaces (" ")

Syntax
   Declare Function Space( ByVal count As Integer ) As String

Usage
   result = Space[$]( count )

Parameters
   count
      An integer type specifying the length of the string to be created.

Return Value
   The created string. An empty string will be returned if count <= 0.

Description
   Space creates a string with the specified number of spaces.

Example
   Dim a As String
   a = "x" + Space(3) + "x"
   Print a ' prints: x   x

Dialect Differences
   * The string type suffix "$" is obligatory in the -lang qb dialect.
   * The string type suffix "$" is optional in the -lang fblite dialect.
   * The string type suffix "$" is forbidden in the -lang fb dialect.

Differences from QB
   * None

See also
   * WSpace
   * Spc
   * String (Function)



-------------------------------------------------------------- KeyPgSpc ----
Spc

Output function to skip spaces when writing to screen or file

Syntax
   Spc( columns )

Usage
   Print Spc( spaces ) [(, | ;)] ...

Parameters
   spaces
      number of spaces to skip

Description
   Spc skips over the given number of spaces when Printing to screen or to 
   a file.  The character cells skipped over are left unchanged.

Example
   Print "foo"; Spc(5); "bar"
   Print "hello"; Spc(4); "world"

   '' Uses Spc to justify text instead of Tab

   Dim As String A1, B1, A2, B2

   A1 = "Jane"
   B1 = "Doe"
   A2 = "Bob"
   B2 = "Smith"

   Print "FIRST NAME"; Spc(35 - 10); "LAST NAME"
   Print "----------"; Spc(35 - 10); "----------"
   Print A1; Spc(35 - Len(A1)); B1
   Print A2; Spc(35 - Len(A2)); B2

The output would look like:

   FIRST Name                         LAST Name
   ----------                         ----------
   Jane                               Doe
   Bob                                Smith

Differences from QB
   * In QBASIC, spaces were printed in the gap, while in FreeBASIC, the 
     characters are just skipped over and left untouched.  The Space 
     function can still be used to achieve this effect.

See also
   * Tab
   * Space
   * Print
   * ?



-------------------------------------------------------------- KeyPgSqr ----
Sqr

Returns a square root of a number

Syntax
   Declare Function Sqr ( ByVal number As Double ) As Double

Usage
   result = Sqr( number )

Parameters
   number
      the number (greater than or equal to zero)

Return Value
   Returns the square root of the argument number.

   If number equals zero, Sqr returns zero (0.0).

   If number is less than zero, Sqr returns a special value representing 
   "not defined", printing like "NaN" or "IND", exact text is platform 
   dependent.

Description
   This is the same as raising the argument number to the one-half power: y 
   = x ^ (1/2) . The required number argument can be any valid numeric 
   expression greater than or equal zero.

   If a LongInt or ULongInt is passed to Sqr, it may be converted to Double 
   precision first.  For numbers over 2^52, this will cause a very small 
   loss of precision.  Without making any assumptions about the rounding 
   method, the maximum error due to this will be Sqr(2^64) - Sqr(2^64-2^12)
   , which is about 4.8e-7. However this may cause erroneous results if the 
   floor or ceiling of this value is taken, and the result of this may be 
   out by 1, particularly for square numbers and numbers that are close by.

   Sqr can be overloaded as operator to accept user-defined types.

Example
   '' Example of Sqr function: Pythagorean theorem 
   Dim As Single a, b

   Print "Pythagorean theorem, right-angled triangle"
   Print
   Input "Please enter one leg side length: ", a
   Input "Please enter the other leg side length: ", b
   Print 
   Print "The hypotenuse has a length of: " & Sqr( a * a + b * b )

The output would look like:

   Pythagorean theorem, Right-angled triangle

   Please enter one leg side length: 1.5
   Please enter the other leg side length: 2

   The hypotenuse has a length of: 2.5

Differences from QB
   * None

See also
   * Operator ^ (Exponentiate)
   * Arithmetic Operators



----------------------------------------------------------- KeyPgStatic ----
Static

Defines variables, objects and arrays having static storage

Syntax
   Static symbol1 [ (array-dimensions) ] As DataType [ = expression] [, 
   symbol2 [ (array-dimensions) ] As DataType [ = expression], ...]
      or
   Static As DataType symbol1 [ (array-dimensions) ] [ = expression] [, 
   symbol2 [ (array-dimensions) ] [ = expression], ...]

      or

   Sub|Function procedurename ( parameters ) [[ ByRef ] As DataType] Static
      ...
   End Sub|Function

Parameters
   symbol
      variable or array symbol name.
   array-dimensions
      lower-bound To upper-bound [, ...]
      or
      Any [, Any...]
      or empty.
   expression
      An constant expression, or an array of constant expressions

Description
   Specifies static storage for variables, objects and arrays; they are 
   allocated at program startup and deallocated upon exit. Objects are 
   constructed once when they are defined, and destructed upon program 
   exit.

   When declaring static arrays, only numeric literals, Constants or 
   Enumerations may be used as subscript range values. Static 
   variable-length arrays must be declared empty (no subscript range list) 
   and resized using ReDim before used.

   In both iterative and recursive blocks, like looping 
   control flow statements or procedures, static variables, objects and 
   arrays local to the block are guaranteed to occupy the same storage 
   across all instantiations of the block. For example, procedures that 
   call themselves - either directly or indirectly - share the same 
   instances of their local static variables.

   A static variable may only be initialised with a constant value: its 
   starting value is set at the start of the program before any code is 
   run, and so it cannot depend on any variables or functions in it.

   When used at procedure definition level (forbidden at declaration line 
   level), Static specifies static storage for all local variables, objects 
   and arrays, except temporary types and internal variables (objects not 
   explicitly declared).

   At module-level variable declaration only, the modifier Shared may be 
   used with the keyword Static to make module-level static variables 
   visible inside procedures.

   When used with in a user-defined type, Static creates 
   Static Member Procedures Or Variables.

Example
   Sub f
      '' times called is initially 0
      Static timesCalled As Integer = 0
      timesCalled += 1
      Print "Number of times called: " & timesCalled
   End Sub

   '' the static variable in f() retains its value between
   '' multiple procedure calls.
   f()
   f()

   Will output:


   Number of times called: 1
   Number of times called: 2

Dialect Differences
   * Variables cannot be initialised in the -lang qb dialect.

Differences from QB
   * QuickBASIC allows variables and arrays to be declared using the 
     Static keyword within procedures and DEF FN routines only.
   * Static forces local visibility of variables and arrays in QuickBASIC 
     DEF FN routines. FreeBASIC supports neither DEF FN routines nor this 
     usage of Static.

See also
   * Static (Member)
   * Dim, ReDim
   * Shared
   * Byref (Variables)
   * Sub (Module), Function (Module)
   * Sub (Member), Function (Member)
   * Option Static
   * Storage Classes
   * Pointers to Procedures



----------------------------------------------------- KeyPgStaticMember ----
Static (Member)

Declare a static member procedure or variable

Syntax
   Type typename
      Static variablename As DataType [, ...]
      Declare Static Sub|Function procedurename ...
      ...
   End Type

   Dim typename.variablename As DataType [= initializer] [, ...]

   [Static] Sub|Function typename.procedurename ...
      ...
   End Sub|Function

Description
   * Static member procedures
      Static methods do not have an implicit This instance argument passed 
      to them. This allows them to be used like normal non-member 
      procedures (for example with callback procedure pointers).  An 
      advantage of Static methods are that they are encapsulated in the 
      typename namespace, and therefore have the ability to access the 
      Private or Protected members or methods of instances of typename.

      Static methods can be called directly anywhere in code, like normal 
      non-member procedures, or on objects of type typename, similar to 
      non-static methods, however either way there is no implicit or 
      explicit This (or explicit Base) access possible from within a static 
      method.

      For member procedures with a Static declaration, Static may also be 
      specified on the corresponding procedure bodies, for improved code 
      readability.

   * Static member variables
      Static member variables are created and initialized only once 
      independently of any object construction, in contrast to non-static 
      ("instance") member variables which are created again and again for 
      each separate object. Static members are always Shared, even if Shared
      was not specified in the declaration. Thus, Static member variables 
      are similar to global variables, except that they are declared in a 
      Type namespace.

      Each Static member variable declared in a Type must be explicitly 
      allocated somewhere outside the type by using a Dim statement. The 
      declaration inside the Type is the prototype that is visible to every 
      module seeing the Type declaration. The definition outside the Type 
      allocates and optionally initializes the Static member variable. 
      There can only be one definition per Static member variable: it can 
      only be allocated in a single module, not in multiple ones. This is 
      the same as for Extern variables.

      A Static member variable is subject to member access control except 
      for its definition outside the Type. If a private Static member 
      variable is to be explicitly initialized outside the Type's member 
      procedures, an initializer must be provided with the definition.

Example
   '' Example showing how the actual procedure invoked by a member can be set at runtime.
   '' using static member procedures.
   Type _Object

     Enum handlertype
      ht_default
      ht_A
      ht_B
     End Enum

     Declare Constructor( ByVal ht As handlertype = ht_default)

     Declare Sub handler()

   Private:
     Declare Static Sub handler_default( ByRef obj As _Object )
     Declare Static Sub handler_A( ByRef obj As _Object )
     Declare Static Sub handler_B( ByRef obj As _Object )
     handler_func As Sub( ByRef obj As _Object )

   End Type

   Constructor _Object( ByVal ht As handlertype )
     Select Case ht
     Case ht_A
      handler_func = @_Object.handler_A
     Case ht_B
      handler_func = @_Object.handler_B
     Case Else
      handler_func = @_Object.handler_default
     End Select
   End Constructor

   Sub _Object.handler()
     handler_func(This)
   End Sub

   Sub _Object.handler_default( ByRef obj As _Object )
     Print "Handling using default method"
   End Sub

   Sub _Object.handler_A( ByRef obj As _Object )
     Print "Handling using method A"
   End Sub

   Sub _Object.handler_B( ByRef obj As _Object )
     Print "Handling using method B"
   End Sub

   Dim objects(1 To 4) As _Object => _
     { _
      _Object.handlertype.ht_B, _
      _Object.handlertype.ht_default, _
      _Object.handlertype.ht_A _
     }
     '' 4th array item will be _Object.handlertype.ht_default

   For i As Integer = 1 To 4
     Print i,
     objects(i).handler()
   Next i

   '' Assign an unique ID to every instance of a Type (ID incremented in order of creation)

   Type UDT
     Public:
      Declare Property getID () As Integer
      Declare Constructor ()
     Private:
      Dim As Integer ID
      Static As Integer countID
   End Type
   Dim As Integer UDT.countID = 0

   Property UDT.getID () As Integer
     Property = This.ID
   End Property

   Constructor UDT ()
     This.ID = UDT.countID
     UDT.countID += 1
   End Constructor

   Dim As UDT uFirst
   Dim As UDT uSecond
   Dim As UDT uThird

   Print uFirst.getID
   Print uSecond.getID
   Print uThird.getID

Differences from QB
   * New to FreeBASIC

See also
   * Class
   * Declare
   * Type
   * Static



---------------------------------------------------------- KeyPgStdcall ----
stdcall

Specifies a stdcall-style calling convention in a procedure declaration

Syntax
   Sub name stdcall [Overload] [Alias "alias"] ( parameters )
   Function name stdcall [Overload] [Alias "alias"] ( parameters ) [ ByRef 
   ] As return_type

Description
   In procedure declarations, stdcall specifies that a procedure will use 
   the stdcall calling convention. In the stdcall calling convention, any 
   parameters are to be passed (pushed onto the stack) in the reverse order 
   in which they are listed, that is, from right to left. The procedures 
   need not preserve the EAX, ECX or EDX registers, and must clean up the 
   stack (pop any parameters) before it returns.

   stdcall is not allowed to be used with variadic procedure declarations 
   (those with the last parameter listed as "...").

   stdcall is the default calling convention on Windows, unless another 
   calling convention is explicitly specified or implied by one of the 
   Extern Blocks. stdcall is also the standard (or most common) calling 
   convention used in BASIC languages, and the Windows API.

Example
   Declare Function Example stdcall (param1 As Integer, param2 As Integer) As Integer
   Declare Function Example2 cdecl (param1 As Integer, param2 As Integer) As Integer

   Function Example stdcall (param1 As Integer, param2 As Integer) As Integer
      ' This is an STDCALL function, the first parameter on the stack is param2, since it was pushed last.
      Print param1, param2
      Return param1 Mod param2
   End Function

   Function Example2 cdecl (param1 As Integer, param2 As Integer) As Integer
      ' This is a CDECL function, the first parameter on the stack is param1, since it was pushed last.
      Print param1, param2
      Return param1 Mod param2
   End Function

Platform Differences
   * On Windows systems, stdcall procedures have an "@N" decoration added 
     to their internal/external name, where N is the size of the parameter 
     list, in bytes.

Differences from QB
   * New to FreeBASIC

See also
   * pascal, cdecl
   * Declare
   * Sub, Function



------------------------------------------------------------- KeyPgStep ----
Step

Statement modifier.

Syntax
   For iterator = initial_value To end_value Step increment

   Line [ buffer, ] Step ( x1, y1 ) - Step ( x2, y2 ) [, [ color ][, [ B|BF 
   ][, style ] ] ]

   Circle [ target, ] Step ( x, y ), radius [, [ color ][, [ start ][, [ 
   end ][, [ aspect ][, F] ] ] ] ]

   Paint [ target, ] STEP ( x, y ) [, [ paint ][, [ border_color ] ] ]

Description
   In a For statement, Step specifies the increment of the loop iterator 
   with each loop.

   In a Line, Circle or Paint statement, Step indicates that the following 
   coordinate has values relative to the graphics cursor.

Example
   Dim i As Integer
   For I=10 To 1 Step -1
   Next

   Line -Step(10,10),13

See also
   * For...Next
   * Line
   * Circle
   * Paint



------------------------------------------------------------ KeyPgStick ----
Stick

Reads axis position from attached gaming devices

Syntax
   Declare Function Stick ( ByVal axis As Long ) As Long

Usage
   result = Stick( axis )

Parameters
   axis
      the axis number to query for position

Return Value
   Returns a number between 1 and 200 for specified axis, otherwise zero 
   (0), if the device is not attached.

Description
   Stick will retrieve the axis position for the first and second axes on 
   the first and second gaming devices.  axis must be a number between 0 
   and 3 having the following meaning:

      +----+------------------------------------------------------+
      |Axis|Returns                                               |
      |0   |X position of gaming device A                         |
      |1   |Y position of gaming device A when STICK(0) was called|
      |2   |X position of gaming device B when STICK(0) was called|
      |3   |Y position of gaming device B when STICK(0) was called|
      +----+------------------------------------------------------+

   Stick(0) must first be called to obtain the positions for the other 
   axes.

Example
   '' Compile with -lang qb

   '$lang: "qb"

   Screen 12

   Do
      Locate 1, 1
      Print "Joystick A-X position : "; Stick(0); "   "
      Print "Joystick A-Y position : "; Stick(1); "   "
      Print "Joystick B-X position : "; Stick(2); "   "
      Print "Joystick B-Y position : "; Stick(3); "   "
      Print
      Print "Button A1 was pressed : "; Strig(0); "  "
      Print "Button A1 is pressed  : "; Strig(1); "  "
      Print "Button B1 was pressed : "; Strig(2); "  "
      Print "Button B1 is pressed  : "; Strig(3); "  "
      Print "Button A2 was pressed : "; Strig(4); "  "
      Print "Button A2 is pressed  : "; Strig(5); "  "
      Print "Button B2 was pressed : "; Strig(6); "  "
      Print "Button B2 is pressed  : "; Strig(7); "  "
      Print
      Print "Press ESC to Quit"

      If Inkey$ = Chr$(27) Then
         Exit Do
      End If

      Sleep 1

   Loop

Dialect Differences
   * Only available in the -lang qb dialect.

Differences from QB
   * None

See also
   * GetJoystick
   * Strig



------------------------------------------------------------- KeyPgStop ----
Stop

Halts program execution, and waits for a key press before ending the 
program.

Syntax
   Declare Sub Stop ( ByVal retval As Long = 0 )

Usage
   Stop

Parameters
   retval
      Error code returned to system.

Description
   Halts the execution of the program and stands by. It's  provided as a 
   help to debugging, as it preserves the memory and doesn't close files. 
   For normal program termination the End keyword should be used. An 
   optional return value, an integer, can be specified to return an error 
   code to the system. If no return value is given, a value of 0 is 
   automatically returned.

   Note: STOP is not implemented properly yet; currently it is the same as 
   System.

Example
   Print "this text is shown"
   Sleep
   Stop
   Print "this text will never be shown"

Differences from QB
   * None

See also
   * End



-------------------------------------------------------------- KeyPgStr ----
Str

Returns a string representation of a number, boolean or Unicode character 
string

Syntax
   Declare Function Str ( ByVal n As Byte ) As String
   Declare Function Str ( ByVal n As UByte ) As String
   Declare Function Str ( ByVal n As Short ) As String
   Declare Function Str ( ByVal n As UShort ) As String
   Declare Function Str ( ByVal n As Long ) As String
   Declare Function Str ( ByVal n As ULong ) As String
   Declare Function Str ( ByVal n As LongInt ) As String
   Declare Function Str ( ByVal n As ULongInt ) As String
   Declare Function Str ( ByVal n As Single ) As String
   Declare Function Str ( ByVal n As Double ) As String
   Declare Function Str ( ByVal b As Boolean ) As String
   Declare Function Str ( ByRef str As Const String ) As String
   Declare Function Str ( ByVal str As Const WString ) As String

Usage
   result = Str[$]( number )
      or
   result = Str( string )

Parameters
   number
      Numeric expression to convert to a string.
   string
      String expression to convert to a string.

Description
   Str converts numeric variables to their string representation. Used this 
   way it is the String equivalent to WStr applied to numeric variables, 
   and the opposite of the Val function, which converts a string into a 
   number.

   Str converts boolean variables to their string representation "false" / 
   "true".

   Str also converts Unicode character strings to ASCII character strings. 
   Used this way it does the opposite of WStr. If an ASCII character string 
   is given, that string is returned unmodified.

Example
   Dim a As Integer
   Dim b As String
   a = 8421
   b = Str(a)
   Print a, b

Dialect Differences
   * In the -lang qb dialect, Str will left pad a positive number with a 
     space.
   * The string type suffix "$" is obligatory in the -lang qb dialect.
   * The string type suffix "$" is optional in the -lang fblite dialect.
   * The string type suffix "$" is forbidden in the -lang fb dialect.

Platform Differences
   * DOS version/target of FreeBASIC does not support the wide-character 
     string version of Str.

Differences from QB
   * QB does not support the wide-character string version of Str.

See also
   * Val
   * CBool
   * Chr
   * Asc



------------------------------------------------------------ KeyPgStrig ----
Strig

Reads button state from attached gaming devices

Syntax
   Declare Function Strig ( ByVal button As Long ) As Long

Usage
   result = Strig( button )

Parameters
   button
      the button to query for state

Return Value
   Returns -1 (pressed) or 0 (not-pressed) to indicate the state of the 
   button requested.

Description
   Strig will retrieve the button state for the first and second buttons on 
   the first and second gaming devices.  button must be a number between 0 
   and 7 and has the following meaning:

      +------+------------------------------------------------------------------+
      |Button|State to return                                                   |
      |0     |First button on gaming device A pressed since STICK(0) was called |
      |1     |First button on gaming device A is pressed                        |
      |2     |First button on gaming device B pressed since STICK(0) was called |
      |3     |First button on gaming device B is pressed                        |
      |4     |Second button on gaming device A pressed since STICK(0) was called|
      |5     |Second button on gaming device A is pressed                       |
      |6     |Second button on gaming device B pressed since STICK(0) was called|
      |7     |Second button on gaming device B is pressed                       |
      +------+------------------------------------------------------------------+

   Calling Stick(0) will reset the state returned where button is equal to 
   0, 2, 4, or 6.

Example
   '' Compile with -lang qb

   '$lang: "qb"

   Screen 12

   Do
      Locate 1, 1
      Print "Joystick A-X position : "; Stick(0); "   "
      Print "Joystick A-Y position : "; Stick(1); "   "
      Print "Joystick B-X position : "; Stick(2); "   "
      Print "Joystick B-Y position : "; Stick(3); "   "
      Print
      Print "Button A1 was pressed : "; Strig(0); "  "
      Print "Button A1 is pressed  : "; Strig(1); "  "
      Print "Button B1 was pressed : "; Strig(2); "  "
      Print "Button B1 is pressed  : "; Strig(3); "  "
      Print "Button A2 was pressed : "; Strig(4); "  "
      Print "Button A2 is pressed  : "; Strig(5); "  "
      Print "Button B2 was pressed : "; Strig(6); "  "
      Print "Button B2 is pressed  : "; Strig(7); "  "
      Print
      Print "Press ESC to Quit"

      If Inkey$ = Chr$(27) Then
         Exit Do
      End If

      Sleep 1

   Loop

Dialect Differences
   * Only available in the -lang qb dialect.

Differences from QB
   * None

See also
   * GetJoystick
   * Stick



--------------------------------------------------- KeyPgStringFunction ----
String (Function)

Creates and fills a string of a certain length with a certain character

Syntax
   Declare Function String ( ByVal count As Integer, ByVal ch_code As Long 
   ) As String
   Declare Function String ( ByVal count As Integer, ByRef ch As Const 
   String ) As String

Usage
   result = String[$]( count, ch_code )
      or
   result = String[$]( count, ch )

Parameters
   count
      An integer specifying the length of the string to be created.
   ch_code
      A long specifying the ASCII character code to be used to fill the 
      string.
   ch
      A string whose first character is to be used to fill the string.

Return Value
   The created string. An empty string will be returned if either ch is an 
   empty string, or count <= 0.

Description
   The String function returns a string with a length of count, filled with 
   a given ch_code or ch.

Example
   Print String( 4, 69 )         '' prints "EEEE"
   Print String( 5, "Indeed" )   '' prints "IIIII"
   End 0

Dialect Differences
   * The string type suffix "$" is obligatory in the -lang qb dialect.
   * The string type suffix "$" is optional in the -lang fblite dialect.
   * The string type suffix "$" is forbidden in the -lang fb dialect.

Differences from QB
   * None 

See also
   * String (data type)
   * Space

   


----------------------------------------------------------- KeyPgString ----
String

Standard data type: 8 bit character string

Syntax
   Dim variable As String [ * size]

Description
   A String is an array of characters.

   A String declared without the size parameter is dynamically resized 
   depending on the length of the string. The length can range from 0 bytes 
   to 2 gigabytes. A descriptor contains a pointer to the actual string, 
   the length of the string, and the amount of space allocated for it. 
   VarPtr will return a pointer to the descriptor, while StrPtr will point 
   to the actual string.

   Because of the hidden descriptor with a String, manual allocation of 
   space, for example using the memory allocation function CAllocate 
   (preferentially), for a String is not encouraged. The common way to 
   ensure a certain amount of space is reserved for a String, to prevent 
   unnecessary allocations inside a loop for instance, is to use the Space 
   or String functions.

   Nevertheless if necessary, dynamic allocation may be carefully used by 
   means of the memory allocation functions Allocate, CAllocate, Reallocate 
   (see precautions for use) and string pointer (which is a pointer to a 
   string descriptor, not string data). When memory is allocated to hold 
   string descriptors, the string must always be destroyed (setting to "") 
   before deallocate each string descriptor (allowing to deallocate the 
   memory taken up by the string data), otherwise, it is not possible to 
   deallocate it later, and it may induce memory leak in the program 
   continuation. 

   Despite the use of the descriptor, an implicit NULL character (Chr(0)) 
   is added to the end of the string, to allow passing them to functions in 
   external libraries without making slow copies.  FreeBASIC's internal 
   functions will ignore this character, and not treat it as part of the 
   string.

   A String declared with a fixed size is a QB-style fixed length string, 
   with the exception that unused characters are set to 0, regardless of 
   what "-lang" compiler option is used. It has no descriptor and it is not 
   resized to fit its contents. As in QB, if data overflows the size of the 
   string, it is truncated on the right side.
   Fixed length strings are also terminated with a NULL character, and so 
   they use size + 1 bytes of space.  This NULL terminator may be removed 
   in future, to prevent the redundant character complicating data layout 
   in user-defined Types.

   String variable names need not end in a dollar sign $ as in other 
   dialects of BASIC.  In lang fb variable suffixes, including the dollar 
   sign, are disallowed entirely.

Example

   '' Variable length
   Dim a As String

   a = "Hello"
   Print a

   a += ", world!"
   Print a

   Var b = "Welcome to FreeBASIC"
   Print b + "! " + a

   '' QB-like $ suffixes
   #lang "qb"

   '' DIM based on $ suffix
   Dim a$
   a$ = "Hello"

   '' Implicit declaration based on $ suffix
   b$ = ", world!"

   Print a$ + b$

   '' Variable-length strings as buffers

   '' Reserving space for a string,
   '' using Space() to produce lots of space characters (ASCII 32)
   Var mybigstring = Space(1024)
   Print "buffer address: &h" & Hex( StrPtr( mybigstring ), 8 ) & ", length: " & Len( mybigstring )

   '' Explicitly destroying a string
   mybigstring = ""
   Print "buffer address: &h" & Hex( StrPtr( mybigstring ), 8 ) & ", length: " & Len( mybigstring )

   '' Variable-length string as Const parameter

   '' Const qualifier preventing string from being modified
   Sub silly_print( ByRef printme As Const String )
      Print ".o0( " & printme & " )0o."
      'next line will cause error if uncommented
      'printme = "silly printed"
   End Sub

   Var status = "OK"

   silly_print( "Hello FreeBASIC!" )
   silly_print( "Status: " + status )

Differences from QB
   * In QB the strings were limited to 32767 characters.
   * In QB, the unused characters of a fixed-length string were 
     initialized with 32 (space, or " ", in ASCII).
   * In QB static or fixed-size strings were often used in records to 
     represent a number of bytes of data;  for example, a string of 1 
     length to represent 1 byte in a UDT read from a file.  This is not 
     possible in FreeBASIC since strings always have an NULL character 
     following.  When converting QBasic code that reads UDTs from files, 
     make sure all instances of "As String * n" are replaced with "As uByte 
     (0 to n - 1)" or your files will be incompatible.

See also
   * String (Function)
   * Space
   * ZString
   * WString
   * Str
   * StrPtr
   * VarPtr
   * Standard Data Type Limits
   * Operator [] (String Index)
   * String Operators



--------------------------------------------------------- KeyPgOpStrptr ----
Operator Strptr (String Pointer)

Returns the address of a string's character data.

Syntax
   Declare Operator StrPtr ( ByRef lhs As String ) As ZString Ptr
   Declare Operator StrPtr ( ByRef lhs As WString ) As ZString Ptr

Usage
   result = StrPtr ( lhs )

Parameters
   lhs
      A string.

Return Value
   Returns a ZString Ptr to a string's character data (null value in case 
   of empty string).

Description
   This operator returns a ZString Ptr that points to the beginning of a 
   string's character data. Operator Strptr is the proper method for 
   acquiring the address of a string's character data.
   In case of empty String (only for variable length strings), Operator 
   Strptr returns a null pointer.

   Note that when passed a WString, Operator Strptr still returns a ZString 
   Ptr, which may not be the desired result.

   The related Operator Varptr (Variable Pointer) and 
   Operator @ (Address Of), when used with a String, return the address of 
   the internal string descriptor.
   When a variable length string is modified, the address of its descriptor 
   remains always the same, but the the string's character data address 
   (returned by Operator Strptr) may change (like any allocated memory that 
   must be reallocated).
   When a fixed length string is modified, the string's character data 
   address (returned by Operator Strptr) is unchanged.

   Note: For a variable length string, the operator returns a ZString Const 
   Ptr (because returning by reference the string's characters pointer set 
   in the string descriptor, this one is to be considered as read only). If 
   the keyword Var is used to declare/initialize a user pointer from 
   Operator Strptr, this user pointer is also defined as read only (it can 
   not be modified further).

Example
   '' This example uses Strptr to demonstrate using pointers with strings
   Dim myString As String
   Dim toMyStringDesc As Any Ptr
   Dim toMyString As ZString Ptr

   '' Note that using standard VARPTR notation will return a pointer to the
   '' descriptor, not the string data itself
   myString = "Improper method for Strings"
   toMyStringDesc = @myString
   Print myString
   Print Hex( toMyStringDesc )
   Print

   '' However, using Strptr returns the proper pointer
   myString = "Hello World Examples Are Silly"
   toMyString = StrPtr(myString)
   Print myString
   Print *toMyString
   Print

   '' And the pointer acts like pointers to other types
   myString = "MyString has now changed"
   Print myString
   Print *toMyString
   Print

Differences from QB
   * New to FreeBASIC, but does exactly the same thing as SAdd

See also
   * SAdd
   * VarPtr
   * ProcPtr
   * Pointers



-------------------------------------------------------------- KeyPgSub ----
Sub

Defines a procedure

Syntax
   [Public|Private] Sub identifier [cdecl|pascal|stdcall] [Overload] [Alias 
   external_identifier] [( [parameter_list] )] [Static] [Export]
      statements
      ...
      [Return]
      ...
   End Sub

   [Public] Sub identifier [cdecl|pascal|stdcall] [Overload] [Alias 
   external_identifier] [()] [Constructor|Destructor] [Static]
      statements
      ...
      [Return]
      ...
   End Sub

Parameters
      identifier: the name of the subroutine
      external_identifier: externally visible (to the linker) name enclosed 
      in quotes
      parameter_list: parameter[, parameter[, ...]]
      parameter: [ByRef|ByVal] identifier [As type] [= default_value]
         identifier: the name of the variable referenced in the subroutine
         type: the type of variable
         default_value: the value of the argument if none is specified in 
         the call
      statements: one or more statements that make up the subroutine body

Description
   A subroutine is a block of code which may be called at any time from a 
   program. This code may need to be executed multiple times, and 
   subroutines provide an invaluable means to simplify code by replacing 
   these blocks of code with a single subroutine call. A subroutine also 
   serves to allow a user to extend the FreeBASIC language to provide 
   custom commands. Many of the functions built into FreeBASIC are merely 
   subroutines part of a "runtime library" linked to by default.

   The Sub keyword marks the beginning of a subroutine, and its end is 
   marked by End Sub. The "name" parameter is the name by which this 
   subroutine is called. For instance, if the declaration is "Sub...End Sub
   ", the user can execute the code in between "Sub foo" and "End Sub" by 
   using "foo" as a statement. This code is executed separate from the code 
   which calls the subroutine, so any variable names, unless they are 
   shared, are not available to the subroutine. Values can, however, be 
   passed using parameters.

   Parameters are the arguments passed to any statement. For instance, if a 
   user executes a statement as "Print 4", the value "4" is passed to the 
   function "Print". Parameters that need to be passed to a subroutine are 
   supplied by one or more parameter arguments in the "Sub" keyword. 
   Creating a subroutine with "Sub mysub(foo, bar)...End Sub", allows the 
   code in between "Sub" and "End Sub" to refer to the first passed 
   argument as "foo" and the second passed argument as "bar". If a 
   parameter is given a default value, that parameter is optional.

   In the default dialect -lang fb, parameters must also have a supplied 
   type, in the form "parameter as type". Type suffixes are not allowed.

   In the -lang qb and -lang fblite dialects only, it will be given a 
   default type if the type is not explicitly given either by name or by 
   type suffix. The default type is Single in the -lang qb dialect and 
   Integer in the -lang fblite dialect.

   A subroutine can also specify how parameters are passed, either as "ByRef
   " or "ByVal", as shown in the syntax definition. If a parameter is "ByRef
   ", the parameter name literally becomes a reference to the original 
   variable passed to the subroutine. Any changes made to that variable 
   will be reflected outside of the subroutine. If a parameter is passed "
   ByVal", however, the value of any passed variable is copied into a new 
   variable, and any changes made to it will not affect the original.

   The Static specifier indicates that the values of all local variables 
   defined in the sub should be preserved between calls. To specify 
   individual local variables as static see the Static keyword.

   Sub is the same as Function, except it does not allow a value to be 
   returned.

   When calling a subroutine, parentheses after the subroutine name 
   (surrounding the argument list if any) are optional.

   The second syntax defines either a constructor or destructor using the 
   Constructor and Destructor keywords, respectively. Constructor 
   subroutines are executed before the first line of code in the module, 
   while destructors execute on module exit. Note the public access 
   specifier and empty parameter list for both constructors and 
   destructors.

Example
   '' Example of writing colored text using a sub:

   Sub PrintColoredText( ByVal colour As Integer, ByRef text As String )
      Color colour
      Print text
   End Sub

      PrintColoredText( 1, "blue" )        '' a few colors
      PrintColoredText( 2, "green" )
      PrintColoredText( 4, "red" )
      Print
      
      Dim i As Integer
      For i = 0 To 15                        '' all 16 colors
        PrintColoredText( i, ("color " & i) )
      Next i

   ' The following demonstrates optional parameters.

   Sub TestSub(P As String = "Default")
      Print P
   End Sub

   TestSub "Testing:"
   TestSub

Dialect Differences
   * The -lang qb and -lang fblite dialects keep the QB convention: 
     parameters are ByRef by default.
   * In the -lang fb dialect, numeric parameters are passed ByVal by 
     default.  Strings and UDTs are passed ByRef by default.

Differences from QB
   * Public and Private access specifiers are new to FreeBASIC.
   * Constructor subroutines are new to FreeBASIC.

See also
   * Declare
   * Function
   * Exit
   * Public
   * Private
   * Static

   


-------------------------------------------------------- KeyPgMemberSub ----
Sub (Member)

Declares or defines a member procedure.

Syntax
   { Type | Class | Union } typename
      Declare [ Static | Const ] Sub fieldname [calling convention 
      specifier] [ Alias external_name ] ( [ parameters ] ) [ Static ] 
   End { Type | Class | Union }

   Sub typename.fieldname ( [ parameters ] ) [ Export ]
      statements
   End Sub

Parameters
   typename 
      name of the Type, Class, or Union
   fieldname 
      name of the procedure
   external_name
      name of field as seen when externally linked
   parameters 
      the parameters to be passed to the procedure
   calling convention specifier	
      can be one of: cdecl, stdcall or pascal

Description
   Sub members are accessed with Operator . (Member Access) or 
   Operator -> (Pointer To Member Access) to call a member procedure and 
   may optionally accept parameters either ByVal or ByRef.  typename be 
   overloaded  without explicit use of the Overload keyword.

   typename is the name of the type for which the Sub method is declared 
   and defined.  Name resolution for typename follows the same rules as 
   procedures when used in a Namespace.

   A hidden This parameter having the same type as typename is passed to 
   non-static member procedures.  This is used to access the fields of the 
   Type, Class, or Union.
   To access duplicated symbols defined outside the Type, add one (or two) 
   dot(s) as prefix: .SomeSymbol (or ..SomeSymbol if inside a With..End With
   block).

   A Static (Member) may be declared using the Static specifier.  A 
   Const (Member) may be declared using the Const specifier.

Example
   Type Statistics
     count As Single
     sum As Single
     Declare Sub AddValue( ByVal x As Single )
     Declare Sub ShowResults( )
   End Type

   Sub Statistics.AddValue( ByVal x As Single )
     count += 1
     sum += x
   End Sub

   Sub Statistics.ShowResults( )
     Print "Number of Values = "; count
     Print "Average          = ";
     If( count > 0 ) Then
      Print sum / count
     Else
      Print "N/A"
     End If
   End Sub

   Dim stats As Statistics

   stats.AddValue 17.5
   stats.AddValue 20.1
   stats.AddValue 22.3
   stats.AddValue 16.9

   stats.ShowResults

Output:

   Number of Values =  4
   Average          =  19.2

Dialect Differences
   * Only available in the -lang fb dialect.

See also
   * Class
   * Function (Member)
   * Sub
   * Type



----------------------------------------------------------- KeyPgSubPtr ----
Sub Pointer

Data type that stores a pointer to a Sub procedure

Syntax
   Dim variable As Sub [cdecl|pascal|stdcall] [( [parameter_list] )] [= 
   initializer]

Parameters
      parameter_list: parameter[, parameter[, ...]]
      parameter: [ByRef|ByVal] identifier [As type] [= default_value]
         identifier: the name of the variable referenced in the subroutine
         type: the type of variable
         default_value: the value of the argument if none is specified in 
         the call
      intializer: address of a subroutine to set as the intial value

Description
   A Sub pointer is a procedure pointer that stores the memory location of 
   compiled code.  If no intializer is given the default initial value is 
   zero (0).

   The memory address for the Sub procedure can be assigned to the variable 
   by taking the address of a subroutine with ProcPtr or 
   Operator @ (Address Of).

   The procedure must match the same Sub declaration as the declared Sub 
   pointer.

   To call the subroutine assigned, use the variable name as if it were a 
   normal declared Sub.

   One of the primary uses for procedure pointers is to create callback 
   procedures. A callback procedure is a procedure created in the user 
   program that is called by another procedure either from the user own 
   code space or from an external library.

Example
      Sub Hello()
         Print "Hello"
      End Sub

      Sub Goodbye()
         Print "Goodbye"
      End Sub

      Dim x As Sub() = ProcPtr( Hello )

      x()

      x = @Goodbye  '' or procptr(Goodbye)

      x()

   Sub s0 ()
     Print "'s0 ()'"
   End Sub

   Sub s1 (ByVal I As Integer)
     Print "'s1 (Byval As Integer)'", I
   End Sub

   Sub s2 (ByRef S As String, ByVal D As Double)
     Print "'s2 (Byref As String, Byval As Double)'", S, D
   End Sub

   Dim s0_ptr As Sub () = @s0
   Dim s1_ptr As Sub (ByVal I As Integer) = @s1
   Dim s2_ptr As Sub (ByRef S As String, ByVal D As Double) = @s2

   s0_ptr()
   s1_ptr(3)
   s2_ptr("PI", 3.14)

   ' Example of advanced callback Sub mechanism to implement a key pressed event:
   ' (the user callback Sub address can be modified while the event thread is running)
   '   - An asynchronous thread tests the keyboard in a loop, and calls a user callback Sub each time a key is pressed.
   '   - An UDT groups the common variables used (callback Sub pointer, character of key pressed, thread end flag),
   '       and the static thread Sub plus the thread handle.
   '   - An UDT instance pointer is passed to the thread, which then transmits it to the callback Sub each time.
   '   - The callback Sub prints the character of the key pressed character,
   '       but if the key pressed is <escape> it orders the thread to finish.
   '   - As the user callback pointer is a member field of the UDT, it can be modified while the thread is running.

   '' UDT for thread environment
     Type threadUDT
      Dim As Sub (ByVal As ThreadUDT Ptr) callback             '' callback Sub pointer
      Dim As Integer threadEnd                                 '' thread end flag
      Dim As String s                                          '' character of the key pressed
      Declare Static Sub threadInkey (ByVal p As Any Ptr)      '' static thread Sub
      Dim As Any Ptr threadHandle                              '' handle to the thread
     End Type

   '' thread Sub definition
     Sub threadUDT.threadInkey (ByVal p As Any Ptr)
      Dim As threadUDT Ptr pt = p                              '' convert the any ptr to a threadUDT pointer
      Do
        pt->s = Inkey
        If pt->s <> "" AndAlso pt->callback > 0 Then           '' test condition key pressed & callback Sub defined
         pt->callback(p)
        End If
        Sleep 50
      Loop Until pt->threadEnd                                 '' test condition to finish thread
     End Sub

   '' user callback Sub definition
     Sub printInkey (ByVal pt As threadUDT Ptr)
      If Asc(pt->s) = 27 Then                                  '' test condition key pressed = <escape>
        pt->threadEnd = -1                                     '' order thread to finish
        Print
      Else
        Print pt->s;
      End If
     End Sub

   '' user main code
     Dim As ThreadUDT t                                         '' create an instance of threadUDT
     t.threadHandle = ThreadCreate(@threadUDT.threadInkey, @t)  '' launch the thread, passing the instance address
     t.callback = @printInkey                                   '' initialize the callback Sub pointer
     ThreadWait(t.threadHandle)                                 '' wait for the thread finish

Differences from QB
   * New to FreeBASIC

See also
   * Sub
   * ProcPtr
   * Operator @ (Address Of)



------------------------------------------------------------- KeyPgSwap ----
Swap

Exchanges the values of two variables

Syntax
   Declare Sub Swap  ( ByRef a As Any, ByRef b As Any )

Parameters
   a
      A variable to swap.
   b
      A variable to swap.

Description
   Swaps the value of two variables, including UDT instances (swaps all 
   data members).

   Note: When the data are referenced by a pointer, alone or within a 
   descriptive structure (a UDT, for example), Swap only exchanges the 
   values of the pointers or the contents of the descriptive structures 
   without accessing data themselves.
   For var-len strings, Swap only exchanges the descriptors of the strings 
   rather than reallocate memory for exchange all strings data characters.
   For UDTs, Swap simply exchanges the contents of the structures, without 
   any operators or methods being called.

Example
   ' using swap to order 2 numbers:
   Dim a As Integer, b As Integer

   Input "input a number: "; a
   Input "input another number: "; b
   If a > b Then Swap a, b
   Print "the numbers, in ascending order are:"
   Print a, b

Differences from QB
   * None

See also
   * Operator = (Assignment)



----------------------------------------------------------- KeyPgSystem ----
System

Closes all open files and ends the program

Syntax
   Declare Sub System ( ByVal retval As Long = 0 )

Usage
   System( [ retval ] )

Parameters
   retval
      Error code returned to system.

Description
   Closes all open files, exits the program, and returns to the operating 
   system. An optional return value, an integer, can be specified to return 
   an error code to the system. If no return value is given, a value of 0 
   is automatically returned. This is the same as End and is here for 
   compatibility between older BASIC dialects. It is recommended to use End 
   instead.

   Usage of this statement does not cleanly close scope. Local variables 
   will not have their destructors called automatically, because FreeBASIC 
   does not do stack unwinding. Only the destructors of global variables 
   will be called in this case.

   For this reason, it is discouraged to use System simply to mark the end 
   of a program; the program will come to an end automatically, and in a 
   cleaner fashion, when the last line of module-level code has executed.

Example
   Print "this text is shown"
   System
   Print "this text will never be shown"

Differences from QB
   * None

See also
   * End




============================================================================
    T

-------------------------------------------------------------- KeyPgTab ----
Tab

Sets the column when writing to screen or file

Syntax
   Tab( col_num )

Usage
   Print Tab( column ) [(, | ;)] ...

Parameters
   column
      1-based column number to move to

Description
   Tab will move the cursor to given column number when Printing to screen 
   or to a file.  Character cells skipped over between the old and new 
   cursor positions are left unchanged.
   If the current column is greater than column, then Tab will move the 
   cursor to the requested column number on the next line.  If the current 
   column is equal to column, then the cursor will not move anywhere.

Example
   '' Using Print with Tab to justify text in a table

   Dim As String A1, B1, A2, B2

   A1 = "Jane"
   B1 = "Doe"
   A2 = "Bob"
   B2 = "Smith"

   Print "FIRST NAME"; Tab(35); "LAST NAME"
   Print "----------"; Tab(35); "----------"
   Print A1; Tab(35); B1
   Print A2; Tab(35); B2

The output would look like:

   FIRST Name                         LAST Name
   ----------                         ----------
   Jane                               Doe
   Bob                                Smith

Differences from QB
   * In QBASIC, spaces were printed in the gap, while in FreeBASIC, the 
     characters are just skipped over and left untouched.

See also
   * Spc
   * Locate
   * Pos
   * Print
   * ?



-------------------------------------------------------------- KeyPgTan ----
Tan

Returns the tangent of an angle

Syntax
   Declare Function Tan ( ByVal angle As Double ) As Double

Usage
   result = Tan( angle )

Parameters
   angle
      the angle (in radians)

Return Value
   Returns the tangent of the argument angle as a Double within the range 
   of -infinity to infinity.

Description
   The argument angle is measured in radians (not degrees).

   The value returned by this function is undefined for values of angle 
   with an absolute value of 2 ^ 63 or greater.

   Tan can be overloaded as operator to accept user-defined types.

Example
   Const PI As Double = 3.1415926535897932
   Dim a As Double
   Dim r As Double
   Input "Please enter an angle in degrees: ", a
   r = a * PI / 180   'Convert the degrees to Radians
   Print ""
   Print "The tangent of a" ; a; " degree angle is"; Tan ( r ) 
   Sleep

The output would look like:

   Please enter an angle in degrees: 75
   The tangent of a 75 degree angle Is 3.732050807568878

Differences from QB
   * None

See also
   * Atn
   * Atan2
   * Sin
   * Cos
   * A Brief Introduction To Trigonometry



------------------------------------------------------------- KeyPgThen ----
Then

Control flow statement for conditional branching.

Syntax
   If expression Then [statement(s)] [Else [statement(s)]] [End If]
or
   If expression Then : [statement(s)] [Else [statement(s)]] : End If
or
   If expression Then
      [statement(s)]
   [ ElseIf expression Then ]
      [statement(s)]
   [ Else ]
      [statement(s)]
   End If

   Remark: EndIf (without blank) is also supported like in QB for backward 
   compatibility.

Differences from QB
   * None

See also
   * If...Then

   


------------------------------------------------------------- KeyPgThis ----
This

Hidden instance parameter passed to non-static member functions in a Type 
or Class

Syntax
   This.fieldname
or
   With This
      .fieldname
   End With

Description
   This is a reference to an instance of a Type or Class that is passed 
   (through a hidden Byref Parameter) to all non-static member functions of 
   that type or class. Non-static member functions are procedures declared 
   inside the body of a Type or Class and include Sub, Function, Constructor
   , Destructor, assignment or Cast Operator, and Property procedures.

   The This additional parameter has the same data type as the Type or Class
   in which the procedure is declared.

   The This parameter can be used just like any other variable, ie., pass 
   it to procedures taking an object of the same type, call other member 
   procedures and access member data using Operator . (Member Access), etc.

   Most of the time, using This explicitly for member access is 
   unnecessary; member procedures can refer to other members of the 
   instance which they are passed directly by name, without having to 
   qualify it with This and Operator . (Member Access). The only times when 
   you need to qualify member names with This is when the member is 
   shadowed, for example by duplicating its name for a local variable or 
   parameter. In these situations, qualifying the member name is the only 
   way to refer to these masked member names.

Example
   Type sometype
      Declare Sub MyCall()
      value As Integer
   End Type

   Dim example As sometype

   '' Set element test to 0
   example.value = 0
   Print example.value

   example.MyCall()

   '' Output should now be 10
   Print example.value

   End 0

   Sub sometype.MyCall()
      This.value = 10
   End Sub

Differences from QB
   * New to FreeBASIC

See also
   * Base
   * Class
   * Type



------------------------------------------------------- KeyPgThreadCall ----
ThreadCall

Starts a user-defined procedure with parameters in a separate execution 
thread

   Threadcall uses LibFFI internally: people who write programs using this 
   functionality should be careful to follow LibFFI's license, which can be 
   found at http://github.com/atgreen/libffi/blob/master/LICENSE.

Syntax
   Function ThreadCall subname([paramlist]) As Any Ptr

Usage
   threadid = ThreadCall subname([paramlist])

Parameters
   subname
      The name of a subroutine
   paramlist
      A list of parameters to pass to the subroutine, as with a normal sub 
      call.	

Return Value
   Threadcall returns an Any Ptr handle to the thread created, or the null 
   pointer (0) on failure.

Description
   Like ThreadCreate, Threadcall creates a thread which runs at the same 
   time as the code calling it.  By placing "Threadcall" before almost any 
   normal call to sub, the sub is called inside of a new thread and returns 
   a pointer to that thread.

   Using Threadcall is simpler method of creating threads, and allows data 
   to be passed to the thread without global variables or pointers which 
   are not type safe.  However, ThreadCreate is more efficient and should 
   be used for programs creating a large number of threads.

   While most subroutines are supported, the following types of subroutines 
   may not be called:
      * Subroutines using Variable Arguments.
      * Subroutines with unions which are passed as arguments.
      * Subroutines with user types containing unions, arrays, strings, or 
        bitfields which are passed as arguments.

   When using Threadcall, parenthesis around the parameter list are 
   required unless the subroutine has no parameters.

   WARNING: Presently when Threadcall involves to pass parameters to the 
   thread, there is no guarantee that the corresponding data are still 
   maintained after the end of the Threadcall statement and this until the 
   thread is launched. That can cause bad behavior.
   Therefore it is more advisable for the moment to use ThreadCreate (100% 
   safe) instead.	

Example
   '' Threading using "ThreadCall"

   Sub thread( id As String, tlock As Any Ptr, count As Integer )
      For i As Integer = 1 To count
         MutexLock tlock
         Print "thread " & id;
         Locate , 20
         Print i & "/" & count
         MutexUnlock tlock
      Next
   End Sub

   Dim tlock As Any Ptr = MutexCreate()
   Dim a As Any Ptr = ThreadCall thread("A", tlock, 6)
   Dim b As Any Ptr = ThreadCall thread("B", tlock, 4)
   ThreadWait a
   ThreadWait b
   MutexDestroy tlock
   Print "All done (and without Dim Shared!)"

Dialect Differences
   * Threading is not allowed in the -lang qb dialect.

Platform Differences
   * Threadcall is not available with the DOS version / target of 
     FreeBASIC, because multithreading is not supported by DOS kernel nor 
     the used extender.
   * In Linux the threads are always started in the order they are 
     created, this can't be assumed in Win32. It's an OS, not a FreeBASIC 
     issue. 
   * In Linux, the stdcall and pascal calling conventions are not 
     supported
   * In Windows, the pascal calling convention is not supported.

Differences from QB
   * New to FreeBASIC

See also
   * ThreadCreate
   * ThreadWait
   * MutexCreate
   * MutexLock
   * MutexUnlock
   * MutexDestroy



----------------------------------------------------- KeyPgThreadCreate ----
ThreadCreate

Starts a user-defined procedure in a separate execution thread

Syntax
   Declare Function ThreadCreate _
      ( _
         ByVal procptr As Sub ( ByVal userdata As Any Ptr ), _
         ByVal param As Any Ptr = 0, _
         ByVal stack_size As Integer = 0 _
      ) As Any Ptr

Usage
   result = ThreadCreate ( procptr [, [ param ] [, stack_size ] ] )

Parameters
   procptr
      A pointer to the Sub intended to work as a thread. The sub must have 
      the following signature (same parameters, same calling convention) to 
      be compatible to procptr:
      Declare Sub myThread ( ByVal userdata As Any Ptr )
   userdata
      The Any Ptr parameter of the Sub intended to work as a thread. 
      FreeBASIC expects this parameter to be present, it must not be 
      omitted! 
   param
      Any Ptr argument that will be passed to the thread Sub pointed to by 
      procptr through its userdata parameter. For example, this can be a 
      pointer to a structure or an array containing various information for 
      the thread sub to work with. If param is not given, 0 (zero) will be 
      passed to the thread sub's userdata parameter instead.
   stack_size
      Optional number of bytes to reserve for this thread's stack.

Return Value
   ThreadCreate returns an Any Ptr handle to the thread created, or a null 
   pointer (0) on failure.

Description
   The sub pointed to by procptr is started as a thread. It will be passed 
   the content of param, or 0 (zero) if not specified, in its userdata 
   parameter.

   The sub that was started as a thread will execute in parallel with the 
   main part of the program. The OS achieves this by assigning it to a 
   different processor if it exists, or by alternating between execution 
   threads on a single processor. There is no guarantee about the order in 
   which different threads execute, and no assumptions can be made about 
   the order in which multiple create threads actually start executing.

   Before closing, programs should wait for the termination of all launched 
   threads by using ThreadWait. Alternatively, if it's not necessary to 
   safely wait for a thread to finish execution, ThreadDetach can be used. 
   However, if a program exits while some threads are still active, those 
   threads will be aborted by the system. For every thread created, 
   programs should call either ThreadWait or ThreadDetach to ensure that 
   the system resources associated with the thread handles are released. 
   Otherwise, there may be memory or system resource leaks.

   Due to the nature of threads, no assumptions about execution order can 
   be made. In order to exchange data between multiple threads, including a 
   thread and the main part of the program, mutexes must be used. These 
   mutual exclusion locks can be "owned" by a single thread while doing 
   critical work, causing other threads to wait for their turn. See 
   MutexCreate, MutexLock, MutexUnlock, MutexDestroy.

   stack_size can be used to change the thread's stack size from the 
   system's default. This can be useful when the program requires a big 
   stack, for example due to lots of procedure recursion or when allocating 
   huge strings/arrays on the stack. On some systems (Linux), the stack 
   automatically grows beyond stack_size if more space is needed; on others 
   (Win32), this is the fixed maximum allowed. Behavior is undefined when 
   more stack is used than the reserved size on systems where stacks are 
   not able to grow.

Example
   '' Threading synchronization using Mutexes
   '' If you comment out the lines containing "MutexLock" and "MutexUnlock",
   '' the threads will not be in sync and some of the data may be printed
   '' out of place.

   Const MAX_THREADS = 10

   Dim Shared As Any Ptr ttylock

   '' Teletype unfurls some text across the screen at a given location
   Sub teletype( ByRef text As String, ByVal x As Integer, ByVal y As Integer )
      ''
      '' This MutexLock makes simultaneously running threads wait for each
      '' other, so only one at a time can continue and print output.
      '' Otherwise, their Locates would interfere, since there is only one
      '' cursor.
      ''
      '' It's impossible to predict the order in which threads will arrive
      '' here and which one will be the first to acquire the lock thus
      '' causing the rest to wait.
      ''
      MutexLock ttylock

      For i As Integer = 0 To (Len(text) - 1)
         Locate x, y + i
         Print Chr(text[i])
         Sleep 25
      Next

      '' MutexUnlock releases the lock and lets other threads acquire it.
      MutexUnlock ttylock
   End Sub

   Sub thread( ByVal userdata As Any Ptr )
      Dim As Integer id = CInt(userdata)
      teletype "Thread (" & id & ").........", 1 + id, 1
   End Sub

      '' Create a mutex to syncronize the threads
      ttylock = MutexCreate()

      '' Create child threads
      Dim As Any Ptr handles(0 To MAX_THREADS-1)
      For i As Integer = 0 To MAX_THREADS-1
         handles(i) = ThreadCreate(@thread, CPtr(Any Ptr, i))
         If handles(i) = 0 Then
            Print "Error creating thread:"; i
            Exit For
         End If
      Next

      '' This is the main thread. Now wait until all child threads have finished.
      For i As Integer = 0 To MAX_THREADS-1
         If handles(i) <> 0 Then
            ThreadWait(handles(i))
         End If
      Next

      '' Clean up when finished
      MutexDestroy(ttylock)

   Sub print_dots(ByRef char As String)
      For i As Integer = 0 To 29
         Print char;
         Sleep CInt(Rnd() * 100), 1
      Next
   End Sub

   Sub mythread(param As Any Ptr)
      '' Work (other thread)
      print_dots("*")
   End Sub

      Randomize(Timer())

      Print " main thread: ."
      Print "other thread: *"

      '' Launch another thread
      Dim As Any Ptr thread = ThreadCreate(@mythread, 0)

      '' Work (main thread)
      print_dots(".")

      '' Wait until other thread has finished, if needed
      ThreadWait(thread)
      Print
      Sleep

   '' Threaded consumer/producer example using mutexes

   Dim Shared As Any Ptr produced, consumed 

   Sub consumer( ByVal param As Any Ptr )
      For i As Integer = 0 To 9
         MutexLock produced
         Print ", consumer gets:", i
         Sleep 500
         MutexUnlock consumed
      Next
   End Sub

   Sub producer( ByVal param As Any Ptr )
      For i As Integer = 0 To 9
         Print "Producer puts:", i;
         Sleep 500
         MutexUnlock produced
         MutexLock consumed
      Next i
   End Sub

      Dim As Any Ptr consumer_id, producer_id

      produced = MutexCreate
      consumed = MutexCreate
      If( ( produced = 0 ) Or ( consumed = 0 ) ) Then
         Print "Error creating mutexes! Exiting..."
         End 1
      End If

      MutexLock produced
      MutexLock consumed
      consumer_id = ThreadCreate(@consumer)
      producer_id = ThreadCreate(@producer)
      If( ( producer_id = 0 ) Or ( consumer_id = 0 ) ) Then
         Print "Error creating threads! Exiting..."
         End 1
      End If

      ThreadWait consumer_id
      ThreadWait producer_id

      MutexDestroy consumed
      MutexDestroy produced

      Sleep

Dialect Differences
   * Threading is not allowed in the -lang qb dialect.

Platform Differences
   * Threadcreate is not available with the DOS version / target of 
     FreeBASIC, because multithreading is not supported by DOS kernel nor 
     the used extender.
   * In Linux the threads are always started in the order they are 
     created, this can't be assumed in Win32. It's an OS, not a FreeBASIC 
     issue. 

Differences from QB
   * New to FreeBASIC

See also
   * ThreadWait
   * ThreadDetach
   * MutexCreate
   * MutexLock
   * MutexUnlock
   * MutexDestroy



----------------------------------------------------- KeyPgThreadDetach ----
ThreadDetach

Releases a thread handle without waiting for the thread to finish

Syntax
   Declare Sub ThreadDetach ( ByVal id As Any Ptr )

Usage
   #include "fbthread.bi"
   ThreadDetach( id )

Parameters
   id
      Any Ptr handle of a thread created by ThreadCreate or ThreadCall

Description
   ThreadDetach releases resources associated with a thread handle returned 
   by ThreadCreate or ThreadCall. The thread handle will be destroyed by 
   ThreadDetach and cannot be used anymore.
   Unlike ThreadWait, ThreadDetach does not wait for the thread to finish 
   and thread execution continues independently. Any allocated resources 
   will be freed once the thread exits.

   In order to avoid memory leaks, the safe way to end a thread is to 
   always signal to it that it must end, and then call ThreadWait on that 
   thread except if ThreadDetach has previously been called.

   Note: As ThreadDetach destroys the thread handle, ThreadWait can no 
   longer check for the thread ending, and even the use of ThreadWait 
   becomes unpredictable (may crash the program). The use between ThreadWait
   and ThreadDetach must be exclusive.
   But mutexes and conditional variables can also be used with detached 
   threads.

Example
   #include "fbthread.bi"

   Sub mythread( ByVal param As Any Ptr )
      Print "hi!"
   End Sub

   Var thread = ThreadCreate( @mythread )
   ThreadDetach( thread )

   ThreadDetach( ThreadCreate( @mythread ) )

   Sleep

Dialect Differences
   * Threading is not allowed in the -lang qb dialect.

Platform Differences
   * ThreadDetach is not available with the DOS version of FreeBASIC, 
     because multithreading is not supported by DOS kernel nor the used 
     extender.

Differences from QB
   * New to FreeBASIC

See also
   * ThreadWait
   * ThreadCreate



------------------------------------------------------- KeyPgThreadWait ----
ThreadWait

Waits for a thread to finish execution and releases the thread handle

Syntax
   Declare Sub ThreadWait ( ByVal id As Any Ptr )

Usage
   ThreadWait( id )

Parameters
   id
      Any Ptr handle of a thread created by ThreadCreate or ThreadCall

Description
   ThreadWait waits for a thread created by ThreadCreate or ThreadCall to 
   finish execution, and then releases the resources associated with the 
   thread handle. ThreadWait does not return until the thread designated by 
   id ends.
   During the wait, no CPU time is consumed by the caller.

   In order to release a thread handle without waiting for the thread to 
   finish, use ThreadDetach.

   ThreadWait does not force the thread to end; if a thread requires a 
   signal to force its end, a mechanism such as shared variables and 
   mutexes must be used.

   In order to avoid memory leaks, the safe way to end a thread is to 
   always signal to it that it must end, and then call ThreadWait on that 
   thread except if ThreadDetach has previously been called.

Example
   See the ThreadCreate examples.

Dialect Differences
   * Threading is not allowed in the -lang qb dialect.

Platform Differences
   * ThreadWait is not available with the DOS version of FreeBASIC, 
     because multithreading is not supported by DOS kernel nor the used 
     extender.

Differences from QB
   * New to FreeBASIC

See also
   * ThreadCreate
   * ThreadDetach



------------------------------------------------------------- KeyPgTime ----
Time

Returns the current system time as a string

Syntax
   Declare Function Time ( ) As String

Usage
   result = Time

Return Value
   Returns the current system.

Description
   Returns the current system time in the format hh:mm:ss.

Example
   Print "the current time is: "; Time

Differences from QB
   * The QB TIME statement (to set the system time) is now called SetTime.

See also
   * Date
   * Timer



------------------------------------------------------------ KeyPgTimer ----
Timer

Returns the amount of time that has passed since a static reference point.

Syntax
   Declare Function Timer ( ) As Double

Usage
   result = Timer

Return Value
   Returns a Double precision result with the time, in seconds, since a 
   static reference point.

Description
   The Timer function is useful for finding out how long a section of code 
   takes to run, or for control the timing of your code.  To find out how 
   much time has passed between two points in your program, you can record 
   the value of Timer at the start and end points, and then subtract the 
   start value from the end value.

   On some platforms, the value of Timer resets to zero at midnight (see 
   below), so if the start and end time are on either side of the reset 
   point, the difference will be negative.  This could cause unexpected 
   behavior in some programs.  In those cases, adding 86400 (the number of 
   seconds in 24 hours) to the difference should return the correct result. 
   If the time taken is longer than a day, then it will be also be 
   necessary to check the number of days that have elapsed.

   The value returned by Timer is NOT affected by the automatic changing of 
   the system clock, in Spring and Autumn, for DST (Daylight Savings Time).

Example
   '' Example of using TIMER function 
   '' Note: see text about correct waiting strategies
   Dim Start As Double
   Print "Wait 2.5 seconds."
   Start = Timer
   Do
      Sleep 1, 1
   Loop Until (Timer - Start) > 2.5
   Print "Done."

Platform Differences
   * On Win32 and Linux, if the program must wait for periods of 0.1 
     seconds or more, Sleep should be used, this allows other programs to 
     run during the waiting period. For shorter delays, a loop using TIMER 
     can be more precise.
   * The reference point chosen varies, depending on the platform.  On 
     Windows, the time is measured relative to the point the computer was 
     booted up.  On DOS, the time is measured relative to Jan 1 1970.

   Note for DOS users: today, the number of seconds since 1970 is in excess 
   of 10^9, and is therefore unsuitable for storing in Single-precision 
   variables, also it shouldn't be multiplied (to get 1/10 seconds or so) 
   and stored in 32-bit integer variables then

   * The precision of TIMER varies, depending on the computer used.  If 
     the processor has a precision timer (as the Performance Counter 
     Pentium processors from Intel have) and the OS uses it, the precision 
     is linked to the processor clock and microseconds can be expected. 
     With older processors (386, 486), and always in DOS, the resolution is 
     1/18 second.

   * Usage of TIMER can cause disk accesses in DOS, see forum for analysis 
     and solutions

Differences from QB
   * In QB, TIMER returned the number of seconds from last midnight, and 
     its accuracy was 1/18 secs

See also
   * Time
   * Sleep



------------------------------------------------------- KeyPgTimeserial ----
TimeSerial

Gets a Date Serial for the specified hours, minutes, and seconds

Syntax
   Declare Function TimeSerial ( ByVal hour As Long, ByVal minute As Long, 
   ByVal second As Long ) As Double

Usage
   #include "vbcompat.bi"
   result = TimeSerial( hours, minutes, seconds )

Parameters
   hour
      number of hours, in the range 0-23
   minute
      number of minutes
   second
      number of seconds

Return Value
   Returns a date serial containing the time formed by the values in the 
   hours, minutes and seconds parameters.The date serial returned has no 
   integer part.

Description
   hours must be specified in the range 0-23

   The compiler will not recognize this function unless vbcompat.bi or 
   datetime.bi is included.

Example
   #include "vbcompat.bi"

   Dim ds As Double = DateSerial(2005, 11, 28) + TimeSerial(7, 30, 50)

   Print Format(ds, "yyyy/mm/dd hh:mm:ss")

Differences from QB
   * Did not exist in QB. This function appeared in PDS and VBDOS

See also
   * Date Serials
   * DateSerial
   * TimeValue
   * DateValue



-------------------------------------------------------- KeyPgTimeValue ----
TimeValue

Gets a Date Serial from a time string

Syntax
   Declare Function TimeValue ( ByRef timestring As String ) As Double

Usage
   #include "vbcompat.bi"
   result = TimeValue( timestring )

Parameters
   timestring
      the string to convert

Return Value
   Returns a Date Serial from a time string.

Description
   The time string must be in the format "23:59:59" or  "11:59:59PM"

   The compiler will not recognize this function unless vbcompat.bi or 
   datetime.bi is included.

Example
   #include "vbcompat.bi"

   Dim ds As Double = TimeValue("07:12:28AM")

   Print Format(ds, "hh:mm:ss")

Differences from QB
   * Did not exist in QB. This function appeared in PDS and VBDOS

See also
   * Date Serials
   * DateSerial
   * TimeValue
   * DateValue



--------------------------------------------------------------- KeyPgTo ----
To

Statement modifier to specify a range.

Syntax
   For iterator intial_value To ending_value
      statement(s).
   Next [ iterator ]
or
   Select Case case_comparison_value
   Case lower_bound To upper_bound
      statement(s).
   End Select
or
   Dim variable_identifier( lower_bound To upper_bound ) As type_specifier

Description
   The To keyword is used to define a certain numerical range. This keyword 
   is valid only if used with For ... Next, Case and Dim statements.

   In the first syntax, the To keyword defines the initial and ending 
   values of the iterator in a For statement.

   In the second syntax, the To keyword defines lower and upper bounds for 
   Case comparisons.

   In the third syntax, the To keyword defines the array bounds in a Dim 
   statement

   For more information, see For...Next, Dim and Select Case.

Example
   '' this program uses bound variables along with the TO keyword to create an array, store random
   '' temperatures inside the array, and to determine output based upon the value of the temperatures
   Randomize Timer

   '' define minimum and maximum number of temperatures we will create
   Const minimum_temp_count As Integer = 1
   Const maximum_temp_count As Integer = 10

   '' define the range of temperatures zones in which bacteria breed rapidly (in degrees)
   Const min_low_danger As Integer = 40
   Const max_low_danger As Integer = 69
   Const min_medium_danger As Integer = 70
   Const max_medium_danger As Integer = 99
   Const min_high_danger As Integer = 100
   Const max_high_danger As Integer = 130

   '' define array to hold temperatures using our min/max temp count bounds
   Dim As Integer array( minimum_temp_count To maximum_temp_count )

   '' declare a for loop that iterates from minimum to maximum temp count
   Dim As Integer it
   For it = minimum_temp_count To maximum_temp_count

      array( it ) = Int( Rnd( 1 ) * 200 ) + 1

      '' display a message based on temperature using our min/max danger zone bounds
      Select Case array( it )
        Case min_low_danger To max_low_danger
          Color 11
          Print "Temperature" ; it ; " is in the low danger zone at" ; array( it ) ; " degrees!"
        Case min_medium_danger To max_medium_danger
          Color 14
          Print "Temperature" ; it ; " is in the medium danger zone at" ; array( it ) ; " degrees!"
        Case min_high_danger To max_high_danger
          Color 12
          Print "Temperature" ; it ; " is in the high danger zone at" ; array( it ) ; " degrees!"
        Case Else
          Color 3
          Print "Temperature" ; it ; " is safe at" ; array( it ) ; " degrees."
      End Select

   Next it

   Sleep

Differences from QB
   * none

See also
   * For...Next
   * Dim
   * Select Case



--------------------------------------------------------- KeyPgTransGfx ----
Trans

Parameter to the Put graphics statement which selects transparent 
background as the blitting method

Syntax
   Put [ target, ] [ STEP ] ( x,y ), source [ ,( x1,y1 )-( x2,y2 ) ], Trans

Parameters
   Trans
      Required.

Description
   Trans selects transparent background as the method for blitting an image 
   buffer.  This is similar to the PSET method, but pixels containing the 
   mask color are skipped.
   For 8-bit color images, the mask color is palette index 0.  For 
   16/32-bit color images, the mask color is Magenta, which is RGB(255, 0, 
   255).  The alpha value is ignored when checking for the mask color in 
   32-bit images.

   Note: for 32-bit images, the alpha value of pixels may be changed to 0.  
   This is for efficiency reasons.  To preserve the alpha values, a custom 
   blender may be used, as in the second example below.

Example
   '' set up a screen: 320 * 200, 16 bits per pixel
   ScreenRes 320, 200, 16

   '' set up an image with the mask color as the background.
   Dim img As Any Ptr = ImageCreate( 32, 32, RGB(255, 0, 255) )
   Circle img, (16, 16), 15, RGB(255, 255, 0),     ,     , 1, f
   Circle img, (10, 10), 3,  RGB(  0,   0, 0),     ,     , 2, f
   Circle img, (23, 10), 3,  RGB(  0,   0, 0),     ,     , 2, f
   Circle img, (16, 18), 10, RGB(  0,   0, 0), 3.14, 6.28

   '' Put the image with PSET (gives the exact contents of the image buffer)
   Draw String (110, 50 - 4), "Image put with PSET"
   Put (60 - 16, 50 - 16), img, PSet

   '' Put the image with TRANS
   Draw String (110, 150 - 4), "Image put with TRANS"
   Put (60 - 16, 150 - 16), img, Trans

   '' free the image memory
   ImageDestroy img

   '' wait for a keypress
   Sleep

   Function trans32 ( ByVal source_pixel As UInteger, ByVal destination_pixel As UInteger, ByVal parameter As Any Ptr ) As UInteger
      '' returns the source pixel
      '' unless it is &hff00ff (magenta), then return the destination pixel
      If (source_pixel And &hffffff) <> &hff00ff Then
         Return source_pixel
      Else
         Return destination_pixel
      End If
   End Function

   '' set up a screen: 320 * 200, 16 bits per pixel
   ScreenRes 320, 200, 32

   '' set up an image with the mask color as the background.
   Dim img As Any Ptr = ImageCreate( 32, 32, RGB(255, 0, 255) )
   Circle img, (16, 16), 15, RGB(255, 255, 0),     ,     , 1, f
   Circle img, (10, 10), 3,  RGB(  0,   0, 0),     ,     , 2, f
   Circle img, (23, 10), 3,  RGB(  0,   0, 0),     ,     , 2, f
   Circle img, (16, 18), 10, RGB(  0,   0, 0), 3.14, 6.28

   '' Put the image with PSET (gives the exact contents of the image buffer)
   Draw String (110, 50 - 4), "Image put with PSET"
   Put (60 - 16, 50 - 16), img, PSet

   '' Put the image with TRANS
   Draw String (110, 100 - 4), "Image put with TRANS"
   Put (60 - 16, 100 - 16), img, Trans

   '' Put the image with TRANS
   Draw String (110, 150 - 4), "Image put with trans32"
   Put (60 - 16, 150 - 16), img, Custom, @trans32

   '' free the image memory
   ImageDestroy img

   '' wait for a keypress
   Sleep

Differences from QB
   * New to FreeBASIC

See also
   * Put (Graphics)
   * Custom



------------------------------------------------------------- KeyPgTrim ----
Trim

Removes surrounding substrings or characters on the left and right side of 
a string

Syntax
   Declare Function Trim ( ByRef str As Const String, [ Any ] ByRef trimset 
   As Const String = " " ) As String
   Declare Function Trim ( ByRef str As Const WString, [ Any ] ByRef 
   trimset As Const WString = WStr(" ") ) As WString

Usage
   result = Trim[$]( str [, [ Any ] trimset ] )

Parameters
   str
      The source string.
   trimset
      The substring to trim.

Return Value
   Returns the trimmed string.

Description
   This procedure trims surrounding characters from the left (beginning) 
   and right (end) of a source string. Substrings matching trimset will be 
   trimmed if specified, otherwise spaces (ASCII code 32) are trimmed.

   If the Any keyword is used, any character matching a character in 
   trimset will be trimmed.

   All comparisons are case-sensitive.

Example
   Dim s1 As String = " ... Stuck in the middle ... "
   Print "'" + Trim(s1) + "'"
   Print "'" + Trim(s1, Any " .") + "'"

   Dim s2 As String = "BaaBaaaaB With You aaBBaaBaa"
   Print "'" + Trim(s2, "Baa") + "'"
   Print "'" + Trim(s2, Any "Ba") + "'"

   will produce the output:


   '... Stuck in the middle ...'
   'Stuck in the middle'
   'aaB With You aaB'
   ' With You '		

Platform Differences
   * DOS version/target of FreeBASIC does not support the wide-character 
     version of Trim.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Trim.
   * The string type suffix "$" is optional in the -lang fblite dialect.
   * The string type suffix "$" is forbidden in the -lang fb dialect.

Differences from QB
   * New to FreeBASIC

See also
   * LTrim 
   * RTrim



------------------------------------------------------------- KeyPgTrue ----
True

Intrinsic constant set by the compiler

Syntax
   Const True As Boolean

Description
   Gives the True Boolean value where used.

Example
   Dim b As Boolean = True
   If b Then
      Print "b is True"
   Else
      Print "b is False"
   End If


   b Is True

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __True.

Differences from QB
   * New to FreeBASIC

See also
   * False
   * Boolean



-------------------------------------------------------- KeyPgTypeAlias ----
Type (Alias)

Declares an alternative name for a type

Syntax
   Type typename As symbol

Parameters
   typename 
      new alternative name.
   symbol 
      symbol or data type declaration to associate with typename. 

Description
   symbol may refer to any declared data type including a built-in data 
   type, Sub or Function pointer, Type declaration, Union declaration, or 
   Enum declaration.

   A type alias can be used to allow forward declarations of parameters in 
   procedure declarations, but only used with pointers (whatever their 
   passing mode), or otherwise with parameters (excluding arrays) but 
   passed or returned only by reference. Generally the bodies of such 
   procedures need to be implemented further in the code once the actual 
   types are well defined.
   A type alias can also be used to allow forward declarations of data 
   fields in User Defined Types, but only used with pointers.

   A type alias must be used to allow declaration of pointer to a function 
   pointer, otherwise  ptr applies on return type and not on function.

Example
   Type ParentFwd As Parent
   Type Child
      Name As ZString * 32
      ParentRef As ParentFwd Ptr
      ''...
   End Type

   Type Parent
      Name As ZString * 32
      ChildList(0 To 9) As Child
      ''...
   End Type

   Dim p As Parent
   p.Name = "Foo"
   With p.ChildList(0)
      .Name = "Jr."
      .ParentRef = @p
      '' ...
   End With   

   With p.ChildList(0)
      Print .Name; " is child of "; .parentRef->Name
   End With

   Function triple (ByVal i As Integer) As Integer
      Return 3 * i
   End Function

   Type As Function (ByVal As Integer) As Integer function_alias

   'Dim As Function (Byval As Integer) As Integer f  ''this syntax works but is less readable than the next code line
   Dim As function_alias f
   f = @triple
   Print f(123)

   'Dim As Function (Byval As Integer) As Integer Ptr pf  ''this syntax does not work because Ptr applies on Integer and not on function
   Dim As function_alias Ptr pf                           ''this syntax works
   pf = @f
   Print (*pf)(123)  ''the dereferenced pointer to procedure pointer must be enclosed in parentheses

Differences from QB
   * New to FreeBASIC

See also
   * Type...End Type
   * Type (Temporary)



--------------------------------------------------------- KeyPgTypeTemp ----
Temporary Types

Creates a temporary copy of a user defined type

Syntax
   result = Type( initializers, ... )
      or
   result = Type<typename>( initializers, ... )

Parameters
   initializers
      Initial values for the type (or only the firsts)
   typename
      The name of the Type or Union

Return Value
   A temporary copy of the type.

Description
   Used to create a temporary type.  If typename is not explicitly given, 
   it will be inferred from its usage if possible.  Usage of the temporary 
   copy may include assigning it to a variable, passing it as a parameter 
   to a procedure, or returning it as a value from a procedure.

   For a type without own or inherited constructor (excluding also any type 
   that is directly or indirectly derived from Object), the temporary type 
   syntax is allowed if all type data-fields (including those inherited) 
   are numeric primitives only and without any default initializers.
   If at same time the type is without destructor, the compiler does a 
   direct assignment instead of using a temporary copy.

   The Constructor for the type, if there is one with parameters matching 
   with the initializers provided, will be called when the temporary copy 
   is created, and the Destructor for the type, if there is one, will be 
   called immediately after its use. But when there is a matching 
   constructor, the temporary type expression may be simply replaced by 
   typename( initializers, ... ).
   If there is a constructor at least but none which matches with the 
   initializers, the temporary type syntax is obviously disallowed.

   It can create not only a temporary copy of an user defined type, but 
   also a temporary copy of predefined data-type as a variable-length 
   string or any numeric data-type (all standard data-types excluding 
   fixed-length strings).

   It can also be used as an even shorter shortcut than With (see below) if 
   you are changing all the data-fields (or the n firsts only).

   A temporary object is destroyed at the end of execution of the statement 
   (where it's defined), but its corresponding allocated memory is not 
   released and remains available (unused) until going out the scope where 
   statement is.

   Note: Static qualifier used at procedure definition level does not apply 
   to temporary types.

Example
   Type Example
      As Integer field1
      As Integer field2
   End Type

   Dim ex As Example

   '' Filling the type by setting each field
   ex.field1 = 1
   ex.field2 = 2

   '' Filling the type by setting each field using WITH
   With ex
      .field1 = 1
      .field2 = 2
   End With

   '' Fill the variable's fields with a  temporary type
   ex = Type( 1, 2 )

   '' Passing a user-defined types to a procedure using a temporary type
   '' where the type can be inferred.

   Type S
     As Single x, y
   End Type

   Sub test ( v As S )
     Print "S", v.x, v.y
   End Sub

   test( Type( 1, 2 ) )

   '' Passing a user-defined type to a procedure using temporary types
   '' where the type is ambiguous and the name of the type must be specified.

   Type S
     As Single x, y
   End Type

   Type T
     As Integer x, y
   End Type

   Union U
     As Integer x, y
   End Union

   '' Overloaded procedure test()
   Sub test Overload ( v As S )
     Print "S", v.x, v.y
   End Sub

   Sub test ( v As T )
     Print "T", v.x, v.y
   End Sub

   Sub test ( v As U )
     Print "U", v.x, v.y
   End Sub

   '' Won't work: ambiguous
   '' test( type( 1, 2 ) )

   '' Specify name of type instead
   test( Type<S>( 1, 2 ) )
   test( Type<T>( 1, 2 ) )
   test( Type<U>( 1 ) )

Differences from QB
   * New to FreeBASIC

See also
   * Type...End Type
   * Type (Alias)



------------------------------------------------------------- KeyPgType ----
Type

Declares a user-defined type.

Syntax
   Type typename
      fieldname1 As DataType
      fieldname2 As DataType
      As DataType fieldname3, fieldname4
      ...
   End Type

   Type typename [Alias "alternatename"] [Extends base_typename] [Field = 
   alignment]
      [Private:|Public:|Protected:]

      Declare Sub|Function|Constructor|Destructor|Property|Operator ...
      Static variablename As DataType
      ReDim arrayname(array dimensions) As DataType

      fieldname As DataType [= initializer]
      fieldname(array dimensions) As DataType [= initializer]
      fieldname(Any [, Any...]) As DataType
      fieldname : bits As DataType [= initializer]

      As DataType fieldname [= initializer], ...
      As DataType fieldname(array dimensions) [= initializer], ...
      As DataType fieldname(Any [, Any...])
      As DataType fieldname : bits [= initializer], ...

      Union
         fieldname As DataType
         Type
            fieldname As DataType
            ...
         End Type
         ...
      End Union

      ...
   End Type

Description
   Type is used to declare custom data types containing one or more data 
   fields, including integer types, floating point types, fixed-size or 
   variable-length (dynamic) arrays, fixed-size or variable-length strings, 
   bitfields, or other user-defined types.

   Types support various functionality related to object-oriented 
   programming:
      * Inheritance through the use of the Extends keyword
      * Member procedures such as Subs or Functions, including Abstract or 
        Virtual ones
      * Member procedures with special semantic meaning such as 
        Constructors or a Destructor
      * Static member variables
      * Member visibility specifiers: Public:, Private:, Protected:

   Types may also contain nested types or unions, allowing data members to 
   be grouped as desired. Nested types/unions are not allowed to contain 
   member procedures or static member variables (same restriction for local 
   types/unions).

   Alias "alternatename" specifies that if typename must be encoded 
   (mangled) in to a public symbol (as in an object module or library), 
   then specifically use alternate name instead of the usual encoding 
   (mangling) of typename.

   Memory layout
   Types lay out their fields consecutively in memory, following the native 
   alignment and padding rules (described on the Field page). Special care 
   must be taken when using Types for file I/O or interacting with other 
   programs or programming languages, in case the alignment and padding 
   rules are different. The optional Field = number specifier can be used 
   to change the behavior on the FreeBASIC side.

   Variable-length data
   In FreeBASIC, Type data structures must ultimately be fixed-size, such 
   that the compiler knows how much memory to allocate for objects of that 
   Type. Nevertheless, Types may contain variable-length (dynamic) string 
   or array data members. However, the string's/array's data will not be 
   embedded in the Type directly. Instead, the Type will only contain a 
   String/array descriptor structure, which FreeBASIC uses behind the 
   scenes to manage the variable-length string/array data. For sizing the 
   structure of the array descriptor in the Type, a variable-length 
   (dynamic) array data member must be always declared by using Any(S) in 
   place of the array bounds, in order to fix the amount of dimensions 
   based on the number of Anys specified.
   Variable-length array fields are considered as pseudo-objects when they 
   are declared in a Type, just like variable-length strings (the implicit 
   copy constructor and the implicit let operator themselves support 
   [re]sizing and copying such arrays, or their erasing).

   Because of that, saving such a Type into a file will write out the 
   descriptor, not the actual string/array data. In order to embed 
   strings/arrays into Types directly, fixed-length strings/arrays must be 
   used.

   Similarly, when maintaining dynamic data manually through the use of 
   pointers within a Type, it does usually not make sense to save the Type 
   to a file, because the address stored in the pointer field will be 
   written to file, not the actual memory it points to. Addresses are 
   meaningful to a specific process only though, and cannot be shared that 
   way.

   Special note on fixed-length strings
   Currently, fixed-length string fields of String * N type have an extra 
   null terminator at their end, for compatibility with C strings, making 
   them incompatible with QB strings inside Types, because they actually 
   use up N+1 bytes, instead of just N bytes. A possible work-around is to 
   declare the field As String * (N-1), though this will not work in future 
   releases if the null terminator is removed.  Another alternative is to 
   use a Byte or UByte array with the proper size.

   Note on bitfields ( fieldname : bits )
   Bitfields can only be declared inside a type or a union, and allow to 
   specify some very small objects of a given number of bits in length. 
   Each field is accessed and manipulated as if it were an ordinary member 
   of the structure. Only integer data-types (up to 32-bit for 32-bit 
   development or 64-bit for 64-bit development) are valid. The sizes of 
   the declared data-types, large enough to contain the bit patterns, 
   affect how the bitfields are placed in memory.
   A bitfield does not have any address (one cannot get a pointer to it and 
   its offset inside the structure).

Example
This is an example of a QB-style type, not including procedure definitions
   Type clr
      red As UByte
      green As UByte
      blue As UByte
   End Type

   Dim c As clr
   c.red = 255
   c.green = 128
   c.blue = 64

And this is an example of a type working as an object:
   '' Example showing the problems with fixed length string fields in UDTs
   '' Suppose we have read a GIF header from a file
   ''                        signature         width        height
   Dim As ZString*(10+1) z => "GIF89a" + MKShort(10) + MKShort(11)

   Print "Using fixed-length string"

   Type hdr1 Field = 1
      As String*(6-1) sig /' We have to dimension the string with 1 char
   						'  less to avoid misalignments '/
      As UShort wid, hei
   End Type

   Dim As hdr1 Ptr h1 = CPtr(hdr1 Ptr, @z)
   Print h1->sig, h1->wid, h1->hei '' Prints GIF89 (misses a char!)  10  11

   '' We can do comparisons only with the 5 visible chars and creating a temporary string with LEFT

   If Left(h1->sig, 5) = "GIF89" Then Print "ok" Else Print "error"

   '' Using a ubyte array, we need an auxiliary function to convert it to a string
   Function ub2str( ub() As UByte ) As String
      Dim As String res = Space(UBound(ub) - LBound(ub) + 1)
      For i As Integer = LBound(ub) To UBound(ub)
         res[i - LBound(ub)] = ub(i)
      Next
      Function = res
   End Function

   Print
   Print "Using an array of ubytes"

   Type hdr2 Field = 1
      sig(0 To 6-1) As UByte '' Dimension 6
      As UShort wid, hei
   End Type

   Dim As hdr2 Ptr h2 = CPtr(hdr2 Ptr, @z)
   '' Viewing and comparing is correct but a conversion to string is required

   Print ub2str(h2->sig()), h2->wid, h2->hei '' Prints GIF89a  10  11 (ok)
   If ub2str(h2->sig()) = "GIF89a" Then Print "ok" Else Print "error" '' Prints ok

This is an example of conversion from an Ubyte to a digit string in base 8 
(octal string), by using bitfields in a local UDT (conversion equivalent to 
'Oct(x, 3)'):
   Function UbyteToOctalString (ByVal b As UByte) As String
    
      Union UbyteOctal
         number As UByte
         Type
            d0 : 3 As UByte
            d1 : 3 As UByte
            d2 : 2 As UByte
         End Type
      End Union
    
      Dim uo As UbyteOctal
      uo.number = b
      Return uo.d2 & uo.d1 & uo.d0
    
   End Function

   For I As Integer = 0 To 255
      Print Using "###: "; I;
   ''    Print Oct(I, 3),
      Print UbyteToOctalString(I),  '' this line is thus equivalent to the previous one
   Next I
   Print

   Sleep

Platform Differences
   * The default Field alignment parameter is 4 bytes for DOS and Linux 
     targets.
   * The default Field alignment parameter is 8 bytes for Windows targets 
     (this difference with regard to 4 bytes applies only to Longint and 
     Double members).

Dialect Differences
   * Object-related features such as functions declared inside Type blocks 
     are supported only with the -lang fb dialect since version 0.17b
   * In the -lang fb and -lang fblite dialects, the default Field 
     alignment parameter depends on the target platform.
   * With the -lang qb dialect the fields are aligned to byte boundaries 
     by default, unless otherwise specified.
   * To force byte alignment use FIELD=1.

Differences from QB
   * At present, fixed-length strings have an extra, redundant character 
     on the end, which means they take up one more byte than they do in QB. 
     For this reason, UDTs that use them are not compatible with QB when 
     used for file I/O.

See also
   * Type (Alias)
   * Type (Temporary)
   * Union
   * Enum
   * TypeOf
   * OffsetOf
   * Alias (Name)
   * Field
   * Extends
   * Extends Zstring
   * Extends Wstring
   * With
   * Coercion and Conversion



----------------------------------------------------------- KeyPgTypeof ----
TypeOf

Returns the type of a variable.

Syntax
   TypeOf ( variable | datatype )

Parameters
   variable
      A variable of any type.
   datatype
      A DataType.

Description
   TypeOf is a compiler intrinsic that replaces itself with the type of the 
   variable passed to it. It can either be used in a variable declaration 
   (Example 1) or it can be used in the preprocessor for comparison, 
   printing. (Example 2)

   TypeOf also supports passing any intrinsic data type, or user-defined 
   type, not only variables defined as those types. Also supported are 
   expressions, the type is inferred from the expression (much like Var).

   When a variable from a given namespace is accessed with the namespace's 
   name prefix, wrap the argument to TypeOf with parentheses to force it to 
   be seen as an expression. For example Typeof((namespace_name.variable)).

   If there is both a user defined type and a variable visible with the 
   same name in the current scope, the user defined type takes precedence 
   over the variable.  To ensure that the TypeOf takes the variable instead 
   of the user defined type, wrap the argument to TypeOf with parentheses 
   to force it to be seen as an expression.  For example Typeof((variable))
   .

Example
Example 1:
   Dim As Integer foo
   Dim As TypeOf(67.2) bar '' '67.2' is a literal double
   Dim As TypeOf( foo + bar ) teh_double '' double + integer results in double
   Print SizeOf(teh_double)

Example 2:
   Dim As String foo
   #print TypeOf(foo)
   #if TypeOf(foo) = TypeOf(Integer)
     #print "Never happened!"
   #endif

   #if TypeOf(foo) = TypeOf(String)
     #print "It's a String!"
   #endif

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Typeof.

Differences from QB
   * New to FreeBASIC

See also
   * SizeOf
   * Var
   * Type (Alias)
   * Type...End Type




============================================================================
    U

----------------------------------------------------------- KeyPgUbound ----
UBound

Returns the upper bound of an array's dimension

Syntax
   Declare Function UBound ( array() As Any, ByVal dimension As Integer = 1 
   ) As Integer

Usage
   result = UBound( array [, dimension ] )

Parameters
   array
      an array of any type
   dimension
      the dimension to get upper bound of

Return Value
   Returns the upper bound of an array's dimension.
 
Description
   UBound returns the largest value that can be used as an index into a 
   particular dimension of an array.

   Array dimensions are numbered from one (1) to n, where n is the total 
   number of dimensions. If dimension is not specified, UBound will return 
   the upper bound of the first dimension.

   If dimension is zero (0), UBound returns n, the number of dimensions in 
   the array. For any other dimension values outside of the valid range 1..
   n, the result is -1. This can be used to detect the number of dimensions 
   of variable-length arrays, and in combination with the result of 
   Lbound() for such cases, whether a given dimension exists, or whether 
   the array is empty (zero dimensions). See the LBound page for more 
   information.

Example

   Dim array(-10 To 10, 5 To 15, 1 To 2) As Integer

   Print UBound(array) 'returns 10
   Print UBound(array, 2) 'returns 15
   Print UBound(array, 3) 'returns 2

   '' determining the size of an array
   Dim As Short array(0 To 9)
   Dim As Integer arraylen, arraysize

   arraylen = UBound(array) - LBound(array) + 1
   arraysize = arraylen * SizeOf( Short )

   Print "Number of elements in array:", arraylen    '10
   Print "Number of bytes used in array:", arraysize '10 * 2 = 20 

   '' determining the size of a multi-dimensional array
   Dim As Long array4D(1 To 2, 1 To 3, 1 To 4, 1 To 5)
   Dim As Integer arraylen, arraysize

   arraylen = (UBound(array4D, 4) - LBound(array4D, 4) + 1) _
          * (UBound(array4D, 3) - LBound(array4D, 3) + 1) _
          * (UBound(array4D, 2) - LBound(array4D, 2) + 1) _
          * (UBound(array4D, 1) - LBound(array4D, 1) + 1)

   arraysize = arraylen * SizeOf( Long )

   Print "Number of elements in array:", arraylen    '2 * 3 * 4 * 5 = 120
   Print "Number of bytes used in array:", arraysize '120 * 4 = 480

   '' determining whether an array is empty
   Dim array() As Integer

   Print "lbound: "; LBound( array ), "ubound: "; UBound( array )  '' 1 and 0

   If LBound( array ) > UBound( array ) Then
      Print "array is empty"
   Else
      Print "array is not empty"
   End If

   Sub printArrayDimensions( array() As Integer )
      Print "dimensions: " & UBound( array, 0 )

      '' For each dimension...
      For d As Integer = LBound( array, 0 ) To UBound( array, 0 )
         Print "dimension " & d & ": " & LBound( array, d ) & " to " & UBound( array, d )
      Next
   End Sub

   Dim array() As Integer
   printArrayDimensions( array() )

   Print "---"

   ReDim array(10 To 11, 20 To 22)
   printArrayDimensions( array() )

See also
   * LBound
   * Static
   * Dim
   * ReDim
   * SizeOf



------------------------------------------------------------ KeyPgUbyte ----
UByte

Standard data type: 8 bit unsigned.
Equivalent to Unsigned Byte.

Syntax
   Dim variable As UByte

Description
   8-bit unsigned whole-number data type. Can hold a value in the range of 
   0 to 255.

Example
   Dim ubytevar As UByte
   ubytevar = 200
   Print "ubytevar= ", ubytevar

Example
     Dim x As UByte = 0
     Dim y As UByte = &HFF
     Print "UByte Range = "; x; " to "; y

   Output:
   UByte Range = 0 To 255

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Ubyte.

Differences from QB
   * New to FreeBASIC

See also
   * Byte
   * CUByte



------------------------------------------------------------ KeyPgUcase ----
UCase

Returns an upper case copy of a string

Syntax
   Declare Function UCase ( ByRef str As Const String, ByVal mode As Long = 
   0 ) As String
   Declare Function UCase ( ByRef str As Const WString, ByVal mode As Long 
   = 0 ) As WString

Usage
   result = UCase[$]( str [ , mode ] )

Parameters
   str
      String to convert to uppercase.
   mode
      The conversion mode: 0 = current locale, 1 = ASCII only

Return Value
   Uppercase copy of str.

Description
   Returns a copy of str with all of the letters converted to upper case.

   If str is empty, the null string ("") is returned.

Example
   Print UCase("AbCdEfG")

   will produce the output:

   ABCDEFG

Platform Differences
   * The wide-character string version of UCase is not supported for DOS 
     target.

Dialect Differences
   * The string type suffix "$" is obligatory in the -lang qb dialect.
   * The string type suffix "$" is optional in the -lang fblite dialect.
   * The string type suffix "$" is forbidden in the -lang fb dialect.

Differences from QB
   * QB does not support Unicode.

See also
   * LCase



--------------------------------------------------------- KeyPgUinteger ----
UInteger

Standard data type: 32-bit or 64-bit unsigned, same size as SizeOf(Any Ptr).
Equivalent to Unsigned Integer.

Syntax
   Dim variable As UInteger
   Dim variable As UInteger<bits>

Parameters
   bits
      A numeric constant expression indicating the size in bits of unsigned 
      integer desired.  The values allowed are 8, 16, 32 or 64.

Description
   32-bit or 64-bit unsigned whole-number data type, depending on the 
   platform.

   If an explicit bit size is given, a data type is provided that can hold 
   values from 0 up to (1ULL Shl (bits)) - 1. The selected data type is 
   UByte for UInteger<8>, UShort for UInteger<16>, ULong for UInteger<32> 
   and ULongInt for UInteger<64>.

Example
   #ifdef __FB_64BIT__
      Dim x As UInteger = 0
      Dim y As UInteger = &HFFFFFFFFFFFFFFFF
      Print "UInteger Range = "; x; " to "; y
   #else
      Dim x As UInteger = 0
      Dim y As UInteger = &HFFFFFFFF
      Print "UInteger Range = "; x; " to "; y
   #endif

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Uinteger.

Differences from QB
   * New to FreeBASIC

See also
   * Integer
   * Unsigned
   * CUInt



------------------------------------------------------------ KeyPgUlong ----
ULong

Standard data type: 32-bit unsigned integer.
Equivalent to Unsigned Long.

Syntax
   Dim variable As ULong

Description
   32-bit unsigned whole-number data type. Can hold values from 0 to 
   4294967295. Corresponds to an unsigned DWORD.

Example
     Dim x As ULong = 0
     Dim y As ULong = &HFFFFFFFF
     Print "ULong Range = "; x; " to "; y

   Output:
   ULong Range = 0 To 4294967295

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Ulong.

Differences from QB
   * New to FreeBASIC

See also
   * Long
   * UInteger
   * ULongInt



--------------------------------------------------------- KeyPgUlongint ----
ULongInt

Standard data type: 64 bit unsigned.
Equivalent to Unsigned LongInt.

Syntax
   Dim variable As ULongInt

Description
   A 64-bit unsigned whole-number data type. Can hold values from 0 to 18 
   446 744 073 709 551 615. Corresponds to an unsigned QWORD.

Example
   Dim x As ULongInt = 0
   Dim y As ULongInt = &HFFFFFFFFFFFFFFFFull
   Print "ULongInt Range = "; x; " to "; y

   Output:
   ULongInt Range = 0 To 18446744073709551615

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Ulongint.

Differences from QB
   * New to FreeBASIC

See also
   * LongInt
   * CULngInt



------------------------------------------------------------ KeyPgUnion ----
Union

Declares a union user defined type.

Syntax
   Union typename
      fieldname as datatype
      Declare member function declaration ...
      ...
   End Union

Parameters
   typename
      Name of the Union
   fieldname
      Name of a data field member
   member function declaration
      Any of the supported member functions

Description
   The data elements of a Union occupy a common space in memory (same 
   memory address for all data elements of the Union). A data element of a 
   Union can be a simple data field or an unnamed Type block of data 
   fields.
   The size of the Union is the size of the largest data element.
   Since they occupy a common memory space, only one data element can 
   usually be used at a given time (when a given data element is written, 
   the other data elements sharing the common union space may be 
   overwritten or mutilated).

   Like Type, Union can use the optional Field = number specifier for field 
   alignment, and supports also inheritance through the use of the Extends 
   keyword.
   Unlike Type, Union can not contain variable-length strings and arrays, 
   and more generally can not have object fields (or bases) with 
   constructors or destructors. Therefore, Union does not support to 
   inherit from the Object built-in type.

   A Union supports member procedures including Constructor, Destructor, 
   Function, Operator, Property and Sub. All members of a Union are public 
   and access modifiers are not supported. 

   Nested unnamed Type or Union can not have procedure members or static 
   data members (same restriction for local scope named Type/Union).

   A Union can be passed in a similar way of a User Defined Type to 
   overloaded operator procedures.

   Note: When Union extends a base, it can be confusing because no new 
   fields are added to the base, but instead the base is added to the 
   derived Union. This means that data elements in the derived Union can 
   share the same memory space like the base (here it doesn't matter 
   whether the base is a Union or not). Of course it can be dangerous, but 
   that is always the problem with Unions.
   If only the base is a Union, then it won't be affected by data elements 
   from the derived UDT.
   Since Union is not allowed to have complex data elements (i.e. UDTs with 
   constructor/destructor, or dynamic strings), a derived Union can not be 
   allowed to have (contain) a complex base.

Example
   ' Example 0: Little-endianness
   ' For larger integer values (as the following Ulong data type),
   '   bytes are arranged in memory in 'little-endian' byte order
   '   (the least significant byte gets stored first).

   Union UDU
      ul As ULong      ' 32-bit data type
      Type
        ub0 As UByte  ' 8-bit data type
        ub1 As UByte  ' 8-bit data type
        ub2 As UByte  ' 8-bit data type
        ub3 As UByte  ' 8-bit data type
      End Type
   End Union

   Dim As UDU u
   u.ul = &h12345678
   Print Hex(u.ul)                                       ' Result: 12345678
   Print Hex(u.ub3), Hex(u.ub2), Hex(u.ub1), Hex(u.ub0)  ' Result: 12   34   56   78

   Sleep

   ' Example 1: Only one union member can be relevantly accessed at a time
   Union member
     username As String * 32
     posts As ULong
   End Union

   Dim As member userX
   userX.username = "Samantha"
   userX.posts = 1234

   Print userX.username  ' value of username corrupted because final value assigned to posts occupies same memory location
   '                     ' (and this is reason that value of posts is displayed well)
   Print userX.posts
   Print

   Dim As member userY
   userY.posts = 4321
   userY.username = "Alexander"

   Print userY.username
   Print userY.posts  ' value of posts corrupted because final value assigned to username occupies same memory location
   '                  ' (and this is reason that value of username is displayed well)
   Print

   Sleep

   ' Example 2: Alternative to RGBA keyword and allowing to retrieve elementary colors values
   Union BGRA_UNION
      colour As ULong
      Type
        blue  As UByte
        green As UByte
        red   As UByte
        Alpha As UByte
      End Type
   End Union

   Dim ubgra As BGRA_UNION

   ' Setting the individual color values...
   ubgra.red = &h33
   ubgra.green = &hcc
   ubgra.blue = &h66
   ' We can get a ULONG value
   Print Hex(ubgra.colour)  ' Result: 33CC66
   Print

   ' Setting a ULONG value...
   ubgra.colour = &h228844
   ' We can get the individual color values
   Print Hex(ubgra.red)    ' Result: 22
   Print Hex(ubgra.green)  ' Result: 88
   Print Hex(ubgra.blue)   ' Result: 44
   Print

   Sleep

   ' Example 3.
   ' Define a simple union.
   Union AUnion
      a As UByte
      b As UInteger
   End Union
   ' Define a composite type with an unnamed union.
   Type CompType
      s As String * 20
      ui As UByte 'Flag to tell us what to use in union.
      Union
         au As UByte
         bu As UInteger
      End Union
   End Type

   ' Flags to let us know what to use in union,
   ' because it's relevant to only use a single element of a union at a given time.
   Const IsInteger = 1
   Const IsUByte = 2

   Dim MyUnion As AUnion
   Dim MyComposite As CompType

   ' Only one field within the union is set, without choice criterion.
   MyUnion.a = 128

   MyComposite.s = "Type + Union"
   MyComposite.ui = IsInteger ' Tells us this is an integer union.
   MyComposite.bu = 1500      ' Field set according to the above flag.

   Print "Simple Union: ";MyUnion.a

   Print MyComposite.s & ": ";
   If MyComposite.ui = IsInteger Then
      Print MyComposite.bu
   ElseIf MyComposite.ui = IsUByte Then
      Print MyComposite.au
   Else
      Print "Unknown Type."
   End If
   Print

   Sleep

Dialect Differences
   * Object-related features as functions defined inside the Union block 
     are supported only in the -lang fb dialect.
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Union.

Differences from QB
   * New to FreeBASIC

See also
   * Type
   * Coercion and Conversion



----------------------------------------------------------- KeyPgUnlock ----
Unlock

Removes a previous access restriction (lock) on a file

Syntax
   Unlock #filenum, record
   Unlock #filenum, start To end

Parameters
   filenum
      The file number used to Open the file.
   record
      The record (Random files) to unlock.
   start
      The first byte position (Binary files) in a range to unlock.
   end
      The last byte position (Binary files) in a range to unlock.

Description
   Unlock removes the temporary access restriction set by Lock.

   It is strongly recommended to use the same arguments used in the 
   previous Lock.

   Note: This command does not always work, neither as documented nor as 
   expected. It appears to be broken at the moment.

Example
       For an example see Lock.

Differences from QB
   * Currently, FB cannot implicitly unlock the entire file
   * In Random mode, FB cannot unlock a range of records

See also
   * Lock
   * Open
   * ScreenUnlock



--------------------------------------------------------- KeyPgUnsigned ----
Unsigned

Integer data type modifier

Syntax
   Dim variable As Unsigned {integer-based data type}

Description
   Forces an integer-based data type to be unsigned (cannot contain 
   negative numbers, but has its maximum value doubled).

Example
   'e.g. notice what is displayed:

   Dim x As Unsigned Integer
   x = -1
   Print x 

   'output is 4294967295

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Unsigned.

Differences from QB
   * New to FreeBASIC

See also
   * UInteger



------------------------------------------------------------ KeyPgUntil ----
Until

Conditional clause used in Do..Loop statements.

Syntax
   Do Until condition
      or
   Loop Until condition

Description
   Until is used with the Do...Loop structure.

Example
   Dim a As Integer

   a = 1
   Do
      Print "hello"
   a = a + 1
   Loop Until a > 10

   'This will continue to print "hello" on the screen until the condition (a > 10) is met. 

Differences from QB
   * None

See also
   * Do...Loop

   


----------------------------------------------------------- KeyPgUshort ----
UShort

Standard data type: 16 bit unsigned.
Equivalent to Unsigned Short.

Syntax
   Dim variable As UShort

Description
   16-bit unsigned whole-number data type. Can hold values from 0 to 65535.

Example
     Dim x As UShort = 0
     Dim y As UShort = &HFFFF
     Print "UShort Range = "; x; " to "; y

   Output:
   UShort Range = 0 To 65535

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Ushort.

Differences from QB
   * New to FreeBASIC

See also
   * Short
   * CUShort



------------------------------------------------------- KeyPgPrintusing ----
(Print | ?) Using

Outputs formatted text to the screen or output device

Syntax
   (Print | ?) [# filenum ,] [ printexpressionlist {,|;} ] Using 
   formatstring ; [ expressionlist [ ; ] ]

Parameters
   filenum
      The file number of a file or device opened for Output or Append.  
      (Alternatively LPrint may be used where appropriate, instead of 
      Print #)
   printexpressionlist
      Optional preceding list of items to print, separated by commas (,) or 
      semi-colons (;) (see Print for more details).
   formatstring
      Format string to use.
   expressionlist
      List of items to format, separated by semi-colons (;).

Description
   Print to screen various expressions using a format determined by the 
   formatstring parameter. Internally, Print Using uses a buffer size of 
   2048 bytes: while it is highly unlikely that this buffer would be 
   filled, it should be noted that output would be truncated should this 
   limit be reached.

   If no expression list is given, the format string will be printed up to 
   the first special marker.  Note that the semi-colon after formatstring 
   is still necessary, even if no expression list is given.

   The format string dictates how the expressions are to be formatted when 
   output to the screen, indicated by the use of special marker characters. 
   There are markers for formatting both string and numeric output:

   String formatting

         +------+----------------------------------------------------------------------+
         |Marker|Formatting                                                            |
         |!     |prints the first character of a string                                |
         |\   \ |prints as many characters of a string as occupied between the pair \ \|
         |&     |prints the entire string                                              |
         +------+----------------------------------------------------------------------+

   Numeric formatting

         +------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
         |Marker|Formatting                                                                                                                                                            |
         |#     |placeholder for either an integer digit, or a decimal digit if a decimal point precedes it                                                                            |
         |,     |placed after integer digit indicates groups of 3 digits should be separated by commas in fixed-point notation                                                         |
         |.     |placed near # indicates place for the decimal point                                                                                                                   |
         |^^^^  |uses exponential notation (E+/-###) when placed after the digit characters                                                                                            |
         |+     |placed before/after the format string, controls whether the sign of a number is prepended/appended, and causes an explicit '+' sign to be printed for positive numbers|
         |-     |placed after the format string, causes the sign of the number to be appended rather than prepended, appending a space/negative sign for positive/negative numbers     |
         |$$    |placed at the start of integer digits, causes a dollar sign to be prepended to the number (after the sign if one is prepended)                                        |
         |**    |placed at the start of integer digits, causes any padding on the left to be changed from spaces to asterisks                                                          |
         |**$   |placed at the start of integer digits, pads on the left with asterisks, and prepends a dollar sign after the asterisks                                                |
         |&     |prints a number intelligently, using the exact number of digits required (new to version 0.21.0b)                                                                     |
         +------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+

   All of the special marker characters can be escaped by preceding them 
   with the underscore character "_", allowing them to be printed directly. 
   For example, "_!" is printed as "!", and "__" is printed as "_".

   If a numerical value cannot fit in the number of digits indicated by the 
   format string, the formatting is adapted to fit the number, possibly 
   switching to scientific notation, and the number is printed preceded by 
   the percent "%" character. E.g., the number 1234 with a formatstring of 
   "##.##" would be printed as "%1234.00".

   All other characters within the format string are printed as they 
   appear.

   A new-line character is printed after the values in the expression list 
   unless the expression list is followed by a semicolon (;).

Example

   Print Using "The value is #.## seconds"; 1.019
   Print Using "The ASCII code for the pound sign (_#) is ###"; Asc("#")
   Print Using "The last day in the year is & \ \"; 31; "December"

   will produce the output:

   The value Is 1.02 seconds
   The ASCII code For the pound sign (#) Is  35
   The last Day in the Year Is 31 Dec

Differences from QB
   * QB didn't allow "&" to be used for printing numbers.

See also
   * Print
   * ?
   * Print #
   * ? #
   * Format
   * Using
   * Palette Using



------------------------------------------------------------ KeyPgUsing ----
Using (Namespaces)

Brings namespace symbols into the current scope

Syntax
   Using identifier [, identifier [, ...] ]

Parameters
   identifier: The name of the Namespace that you want to use.

Description
   The Using command allows all symbols from a given namespace to be 
   accessed without the namespace's name prefix. Unlike C++ but like C#, 
   the Namespace keyword is not needed after Using, because individual 
   symbols cannot be inherited from a namespace.
   Inheriting a whole namespace can save typing, but sometimes some meaning 
   of the code can be lost, and conflicts with other symbols could be 
   created. For example, if there is duplicated symbol in the global 
   namespace (unnamed namespace), access to local symbol is captured by 
   duplicated global symbol (in that case, full prefixing is required to 
   access local symbol).

Example
   Namespace Sample
      Type T
         x As Integer
      End Type
   End Namespace

   '' Just using the name T would not find the symbol,
   '' because it is inside a namespace.
   Dim SomeVariable As Sample.T

   '' Now the whole namespace has been inherited into
   '' the global namespace.
   Using Sample

   '' This statement is valid now, since T exists
   '' without the "Sample." prefix.
   Dim OtherVariable As T 

Differences from QB
   * QB had the Using keyword, but for other purposes. Namespaces did not 
     exist in QB.

See also
   * Print Using
   * ? Using
   * Palette Using
   * Namespace




============================================================================
    V

------------------------------------------------------------ KeyPgVaArg ----
va_arg

Returns the current argument from a variable argument list.

Syntax
   variable = va_arg ( argument_list, datatype )

Description
   The va_arg macro allows the use of a variable number of arguments within 
   a function:
      * 	va_arg returns the current argument in the list, argument_list, 
        with an expected data type of datatype.
      * 	Before first va_arg use, argument_list must be initialized with 
        the command va_first.
      * 	Unlike the C macro with the same name, va_arg does not 
        automatically increment argument_list to the next argument within 
        the list. Instead va_next must be used to find the next argument in 
        adjusting argument_list.

   Not supported when using -gen gcc.  Use Cva_List variadic argument list 
   type for cross platform compatibility.

Example
   See the Va_First() examples.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __va_arg.

Differences from QB
   * New to FreeBASIC

See also
   * ... (Ellipsis)
   * va_first
   * va_next



---------------------------------------------------------- KeyPgVaFirst ----
va_first

Returns a pointer to the first argument in a variable argument list

Syntax
   pointer_variable = va_first()

Description
   The va_first function provides an untyped pointer value that points to 
   the first variable argument passed to a function.

   Not supported when using -gen gcc.  Use Cva_List variadic argument list 
   type for cross platform compatibility.

Example
   Function average cdecl(count As Integer, ... ) As Double
      Dim arg As Any Ptr
      Dim sum As Double = 0
      Dim i As Integer
      
      arg = va_first()

      For i = 1 To count
         sum += va_arg(arg, Double)
         arg = va_next(arg, Double)
      Next
      
      Return sum / count
   End Function

   Print average(4, 3.4,5.0,3.2,4.1)  '' all passed variable arguments must be of type double
   Print average(2, 65.2,454.65481)   '' all passed variable arguments must be of type double
   Sleep

The output would look like:

   3.925
   259.927405

   '' Example of a simple custom printf
   Sub myprintf cdecl(ByRef formatstring As String, ...)
      '' Get the pointer to the first var-arg
      Dim As Any Ptr arg = va_first()

      '' For each char in format string...
      Dim As UByte Ptr p = StrPtr(formatstring)
      Dim As Integer todo = Len(formatstring)
      While (todo > 0)
         Dim As Integer char = *p
         p += 1
         todo -= 1

         '' Is it a format char?
         If (char = Asc("%")) Then
            If (todo = 0) Then
               '' % at the end
               Print "%";
               Exit While
            End If

            '' The next char should tell the type
            char = *p
            p += 1
            todo -= 1

            '' Print var-arg, depending on the type
            Select Case char
            '' integer?
            Case Asc("i")
               Print Str(va_arg(arg, Integer));
               '' Note, different from C: va_next() must be
               '' used as va_arg() won't update the pointer.
               arg = va_next(arg, Integer)

            '' long integer? (64-bit)
            Case Asc("l")
               Print Str(va_arg(arg, LongInt));
               arg = va_next(arg, LongInt)

            '' single or double?
            '' Note: because the C ABI, all singles passed on
            '' var-args are converted to doubles.
            Case Asc( "f" ), Asc( "d" )
               Print Str(va_arg(arg, Double));
               arg = va_next(arg, Double)

            '' string?
            Case Asc("s")
               '' Strings are passed byval, so the length is unknown
               Print *va_arg(arg, ZString Ptr);
               arg = va_next(arg, ZString Ptr)

            End Select

         '' Ordinary char, just print as-is
         Else
            Print Chr( char );
         End If
      Wend
   End Sub

      Dim As String s = "bar"

      myprintf(!"integer=%i, longint=%l single=%f, double=%d, string=%s, string=%s\n", _
             1, 1ll Shl 32, 2.2, 3.3, "foo", s)

      Sleep

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Va_first.

Differences from QB
   * New to FreeBASIC

See also
   * ... (Ellipsis)
   * va_arg
   * va_next



----------------------------------------------------------- KeyPgVaNext ----
va_next

Returns a pointer to the next argument in a variable argument list

Syntax
   Argument_Pointer = va_next ( Argument_List, datatype )

Description
   The va_next macro provides a datatype pointer value that points to the 
   next argument within the list Argument_List, datatype being the type of 
   the current argument being stepped over.

   Not supported when using -gen gcc.  Use Cva_List variadic argument list 
   type for cross platform compatibility.

Example
   See the Va_First() examples.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Va_next.

Differences from QB
   * New to FreeBASIC

See also
   * ... (Ellipsis)
   * va_arg
   * va_first



-------------------------------------------------------------- KeyPgVal ----
Val

Converts a string to a floating point number

Syntax
   Declare Function Val ( ByRef str As Const String ) As Double
   Declare Function Val ( ByRef str As Const WString ) As Double

Usage
   result = Val( strnum )

Parameters
   strnum
      the string containing a number to convert

Return Value
   Returns a converted Double precision number

   If the first character of the string is invalid, Val will return 0.

Description
   Val("10") will return 10.0, and Val("10.10") will return 10.1. The 
   function parses the string from the left, skipping any white space, and 
   returns the longest number it can read, stopping at the first 
   non-suitable character it finds.  Scientific notation is recognized, 
   with "D" or "E" used to specify the exponent.

   Val can be used to convert integer numbers in binary / octal / 
   hexadecimal format, if they have the relevant identifier ("&B" / "&O" / 
   "&H") prefixed, for example: Val("&HFF") returns 255.

   Note:
   If you want to get an integer value from a string, consider using ValInt 
   or ValLng instead.  They are faster, since they don't use floating-point 
   numbers, and only ValLng provides full 64-bit precision for LongInt 
   types.

   If you want to convert a number into string format, use the Str 
   function.

Example
   Dim a As String, b As Double
   a = "2.1E+30xa211"
   b = Val(a)
   Print a, b


   2.1E+30xa211   2.1e+030

Differences from QB
   * None

See also
   * CDbl
   * ValInt
   * ValUInt
   * ValLng
   * ValULng
   * Str
   * Chr
   * Asc



----------------------------------------------------------- KeyPgVallng ----
ValLng

Converts a string to a 64bit integer

Syntax
   Declare Function ValLng ( ByRef strnum As Const String ) As LongInt
   Declare Function ValLng ( ByRef strnum As Const WString ) As LongInt

Usage
   result = ValLng ( strnum )

Parameters
   strnum
      the string to convert

Return Value
   Returns a LongInt of the converted string

   If the first character of the string is invalid, ValLng will return 0.

Description
   For example, ValLng("10") will return 10, and ValLng("10.60") will 
   return 10 as well. The function parses the string from the left, 
   skipping any white space, and returns the longest number it can read, 
   stopping at the first non-suitable character it finds.  Any non-numeric 
   characters, including decimal points and exponent specifiers, are 
   considered non-suitable, for example, ValLng("23.1E+6") will just return 
   23.

   ValLng can be used to convert integer numbers in Binary / Octal / 
   Hexadecimal format, if they have the relevant identifier ("&B" / "&O" / 
   "&H") prefixed, for example: ValLng("&HFF") returns 255.

   If you want to convert a number into string format, use the Str 
   function.

Example
   Dim a As String, b As LongInt
   a = "20xa211"
   b = ValLng(a)
   Print a, b


   20xa211   20

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Vallng.

Differences from QB
   * New to FreeBASIC

See also
   * CLngInt
   * Val
   * ValInt
   * ValULng
   * Str
   * Chr
   * Asc



----------------------------------------------------------- KeyPgValint ----
ValInt

Converts a string to a 32bit integer

Syntax
   Declare Function ValInt ( ByRef strnum As Const String ) As Long
   Declare Function ValInt ( ByRef strnum As Const WString ) As Long

Usage
   result = ValInt ( strnum )

Parameters
   strnum
      the string to convert

Return Value
   Returns a Long value of the converted string

   If the first character of the string is invalid, ValInt will return 0.

Description
   For example, ValInt("10") will return 10, and ValInt("10.60") will 
   return 10 as well. The function parses the string from the left, 
   skipping any white space, and returns the longest number it can read, 
   stopping at the first non-suitable character it finds.  Any non-numeric 
   characters, including decimal points and exponent specifiers, are 
   considered non-suitable, for example, ValInt("23.1E+6") will just return 
   23.

   ValInt can be used to convert integer numbers in Binary / Octal / 
   Hexadecimal format, if they have the relevant identifier ("&B" / "&O" / 
   "&H") prefixed, for example: ValInt("&HFF") returns 255.

   If you want to convert a number into string format, use the Str 
   function.

Example
   Dim a As String, b As Integer
   a = "20xa211"
   b = ValInt(a)
   Print a, b


   20xa211   20

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Valint.

Differences from QB
   * New to FreeBASIC

See also
   * CLng
   * Val
   * ValUInt
   * ValLng
   * Str
   * Chr
   * Asc



---------------------------------------------------------- KeyPgValuint ----
ValUInt

Converts a string to an unsigned 32bit integer

Syntax
   Declare Function ValUInt ( ByRef strnum As Const String ) As ULong
   Declare Function ValUInt ( ByRef strnum As Const WString ) As ULong

Usage
   result = ValUInt ( strnum )

Parameters
   strnum
      the string to convert

Return Value
   Returns a ULong value of the converted string

   If the first character of the string is invalid, ValUInt will return 0.

Description
   For example, ValUInt("10") will return 10, and ValUInt("10.60") will 
   return 10 as well. The function parses the string from the left, 
   skipping any white space, and returns the longest number it can read, 
   stopping at the first non-suitable character it finds.  Any non-numeric 
   characters, including decimal points and exponent specifiers, are 
   considered non-suitable, for example, ValUInt("23.1E+6") will just 
   return 23.

   ValUInt can be used to convert integer numbers in Binary / Octal / 
   Hexadecimal format, if they have the relevant identifier ("&B" / "&O" / 
   "&H") prefixed, for example: ValUInt("&HFF") returns 255.

   If you want to convert a number into string format, use the Str 
   function.

Example
   Dim a As String, b As UInteger
   a = "20xa211"
   b = ValUInt(a)
   Print a, b


   20xa211   20

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Valuint.

Differences from QB
   * New to FreeBASIC

See also
   * Val
   * ValInt
   * ValULng
   * CULng
   * Str
   * Chr
   * Asc



---------------------------------------------------------- KeyPgValulng ----
ValULng

Converts a string to a unsigned 64bit integer

Syntax
   Declare Function ValULng ( ByRef strnum As Const String ) As ULongInt
   Declare Function ValULng ( ByRef strnum As Const WString ) As ULongInt

Usage
   result = ValULng ( strnum )

Parameters
   strnum
      the string to convert

Return Value
   Returns a ULongInt of the converted string

   If the first character of the string is invalid, ValULng will return 0.

Description
   For example, ValULng("10") will return 10, and ValULng("10.60") will 
   return 10 as well. The function parses the string from the left, 
   skipping any white space, and returns the longest number it can read, 
   stopping at the first non-suitable character it finds.  Any non-numeric 
   characters, including decimal points and exponent specifiers, are 
   considered non-suitable, for example, ValULng("23.1E+6") will just 
   return 23.

   ValULng can be used to convert integer numbers in Binary / Octal / 
   Hexadecimal format, if they have the relevant identifier ("&B" / "&O" / 
   "&H") prefixed, for example: ValULng("&HFF") returns 255.

   If you want to convert a number into string format, use the Str 
   function.

Example
   Dim a As String, b As ULongInt
   a = "20xa211"
   b = ValULng(a)
   Print a, b


   20xa211   20

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Valulng.

Differences from QB
   * New to FreeBASIC

See also
   * CULngInt
   * Val
   * ValUInt
   * ValLng
   * Str
   * Chr
   * Asc



-------------------------------------------------------------- KeyPgVar ----
Var

Declares a variable whose type is implied from the initializer expression

Syntax
   Var [Shared] symbolname = expression[, symbolname = expression]

Description
   Var declares a variable whose type is implied from the initializer 
   expression. It is illegal to specify an explicit type in a Var 
   declaration. The initializer expression can be either a constant or any 
   variable of any type.

   Note: WString is not supported with Var, due to the fact that there is 
   no var-len WString type. This isn't likely to change, due to the 
   complexities involved with handling Unicode.

   Since the type of the variable is inferred from what you assign into it, 
   it's helpful to know how literals work. Any literal number without a 
   decimal point defaults to Integer. A literal number with a decimal point 
   defaults to Double.  See ProPgLiterals for further information.

   All ZString expressions, including string literals and dereferenced 
   ZString Ptrs, will be given the String variable type.

   Explicit suffixes may be used on literal variables, to change/clarify 
   their type. See Literals and Variable Types for some more information 
   about suffixes that can be used on literals.

   Note: Suffixes must appear on the initializer, not on the variable. 
   Trying to use Var with a variable that has a suffix will throw a compile 
   error.

Example
   Var a  = Cast(Byte, 0)
   Var b  = Cast(Short, 0)
   Var c  = Cast(Integer, 0)
   Var d  = Cast(LongInt, 0)
   Var au = Cast(UByte, 0)   
   Var bu = Cast(UShort, 0)  
   Var cu = Cast(UInteger, 0)
   Var du = Cast(ULongInt, 0)
   Var e  = Cast(Single, 0.0)
   Var f  = Cast(Double, 0.0)
   Var g  = @c      '' integer ptr
   Var h  = @a      '' byte ptr
   Var s2 = "hello" '' var-len string

   Var ii = 6728   '' implicit integer
   Var id = 6728.0 '' implicit double

   Print "Byte: ";Len(a)
   Print "Short: ";Len(b)
   Print "Integer: ";Len(c)
   Print "Longint: ";Len(d)
   Print "UByte: ";Len(au)
   Print "UShort: ";Len(bu)
   Print "UInteger: ";Len(cu)
   Print "ULongint: ";Len(du)
   Print "Single: ";Len(e)
   Print "Double: ";Len(f)
   Print "Integer Pointer: ";Len(g)
   Print "Byte Pointer: ";Len(h)
   Print "Variable String: ";Len(s2)
   Print
   Print "Integer: ";Len(ii)
   Print "Double: ";Len(id)

   Sleep

Differences from QB
   * New to FreeBASIC

Dialect Differences
   * Only valid in the -lang fb dialect.

See also
   * Common
   * Dim
   * Erase
   * Extern
   * LBound
   * ReDim
   * Preserve
   * Shared
   * Static
   * Byref (Variables)
   * UBound
   * Pointers to Procedures



--------------------------------------------------------- KeyPgOpVarptr ----
Operator Varptr (Variable Pointer)

Returns the address of a variable or object

Syntax
   Declare Operator VarPtr ( ByRef lhs As T ) As T Ptr

Syntax
   result = VarPtr ( lhs )

Parameters
   lhs
      A variable or object.
   T
      Any data type.

Return Value
   Returns the address of a variable or object.

Description
   This operator returns the address of its operand.

   When the operand is of type String, the address of the internal string 
   descriptor is returned. Use Operator Strptr (String Pointer) to retrieve 
   the address of the string data.

   The operand cannot be an array, but may be an array element. For 
   example, "VarPtr(myarray(0))" returns the address of "myarray(0)".

   Operator @ (Address Of), when used with variables or objects, has 
   identical behavior.

Example
   Dim a As Integer, addr As Integer
   a = 10

   '' place the address of a in addr
   addr = CInt( VarPtr(a) )

   '' change all 4 bytes (size of INTEGER) of a
   Poke Integer, addr, -1000 
   Print a

   '' place the address of a in addr (same as above)
   addr = CInt( @a )

   '' print the least or most significant byte, depending on the CPU endianess
   Print Peek( addr ) 

Differences from QB
   * None

See also
   * Pointers
   * Peek
   * Poke



--------------------------------------------------------- KeyPgViewtext ----
View Print

Sets the printable text area of the screen

Syntax
   View Print [ firstrow To lastrow ]

Parameters
   firstrow
      first row of print area
   lastrow
      last row of print area

Description
   Sets the boundaries of the text printing area on the screen (in console 
   mode or in graphics mode) to the lines starting at first up to and 
   including last (the number of the available text lines on the screen 
   depends on the screen mode). Text lines are counted starting with 1. The 
   text cursor is moved to the beginning of the first line specified.
   If the row numbers are omitted, the entire screen is used as the text 
   printing area.

Example
   Cls
   View Print 5 To 6
   Color , 1 
   '' clear only View Print area
   Cls 

View Print can be used in graphics mode to avoid the text output 
overwriting graphics:
   Screen 12
   Dim As Integer R,Y,x,y1
   Dim As Single y2
   View Print 20 To 27
   Line (0,0)-(639,300),1,BF
   Line (100,50)-(540,200),0,BF
   Do
    r = (r + 1) And 15
    For y = 1 To 99
      y1 = ((1190 \ y + r) And 15)
      y2 = 6 / y
      For x = 100 To 540
      PSet (x, y + 100), CInt((319 - x) * y2) And 15 Xor y1 
     Next x,y
    If r=0 Then Color Int(Rnd*16): Print "blah"
   Loop Until Len(Inkey)

Differences from QB
   * None.

See also
   * Cls
   * Print
   * ?
   * Color



----------------------------------------------------- KeyPgViewgraphics ----
View (Graphics)

Sets new physical coordinate mapping and clipping region for graphics 
keywords

Syntax
   View
   View ( x1, y1 )-( x2, y2 ) [ [, fill_color ] [, border_color ] ]
   View Screen ( x1, y1 )-( x2, y2 ) [ [, fill_color ] [, border_color ] ]

Parameters
   x1 As Integer, y1 As Integer
      The horizontal and vertical offsets, in pixels, of one corner of the 
      viewport relative to the top-left corner of the screen.
   x2 As Integer, y2 As Integer
      The horizontal and vertical offsets, in pixels, of the opposite 
      corner of the viewport relative to the top-left corner of the screen.
   fill_color As UInteger
      The color to fill the new viewport.
   border_color As UInteger
      The color of the border to draw around the new viewport.

Description
   The viewport, or clipping region, is a rectangular area of the graphics 
   screen, outside of which no graphics drawing will be done. That is, only 
   graphics drawing done within this area will be shown. A graphics screen 
   must be created with Screen or ScreenRes before calling View or View 
   Screen.

   The first statement (View) sets the viewport to encompass the entire 
   screen, which is the default viewport for a new graphics screen.

   The second and third statements (View parameters and View Screen 
   parameters) both allow a new viewport to be defined. The indicated 
   effects for each parameter only occur if that parameter is specified:
      * The corners of the viewport are specified by the x1, y1, x2 and y2 
        parameters.
      * fill_color and border_color are both in the format accepted by 
        Color.
      * The second statement (View parameters) modifies the coordinate 
        mapping of the graphics screen such that coordinates specified for 
        graphics drawing statements and procedures are relative to the 
        top-left corner of the viewport.
      * The third statement (View Screen parameters) modifies the 
        coordinate mapping of the graphics screen such that coordinates 
        specified for graphics drawing statements and procedures are 
        relative to the top-left corner of the screen.
      * In both cases no new scale factor is applied (see Window for 
        that).

Example
   Screen 12
   Dim ip As Any Ptr
   Dim As Integer x, y

   'simple sprite
   ip = ImageCreate(64,64)
   For y = 0 To 63
     For x = 0 To 63
      PSet ip, (x, y), (x\4) Xor (y\4)
     Next x
   Next y

   'viewport with blue border
   Line (215,135)-(425,345), 1, bf
   View (220,140)-(420,340)

   'move sprite around the viewport
   Do

     x = 100*Sin(Timer*2.0)+50
     y = 100*Sin(Timer*2.7)+50
     
     ScreenSync
     ScreenLock
     
     'clear viewport and put image
     Cls 1
     Put (x, y), ip, PSet
      
     ScreenUnlock

   Loop While Inkey = ""

   ImageDestroy(ip)

Differences from QB
   * QBASIC preserves the WINDOW coordinate mapping after subsequent calls 
     to VIEW.
   * FreeBASIC's current behavior is to preserve the WINDOW coordinates 
     after calls to VIEW, or when working on images, meaning that the 
     coordinate mapping may undergo scaling/translations if the viewport 
     changes. (If a WINDOW hasn't been set, there is no coordinate mapping, 
     and so it doesn't change after calls to VIEW.)  The behavior may 
     change in future, but consistent behavior can be assured over 
     inconstent viewport coordinates by re-calling WINDOW whenever you 
     change the VIEW.

See also
   * View Print
   * Screen (Graphics)
   * Window
   * PMap



---------------------------------------------------------- KeyPgVirtual ----
Virtual

Declare virtual methods

Syntax
   Type typename Extends base_typename
      Declare Virtual Sub|Function|Property|Operator|Destructor ...
   End Type

Description
   Virtual methods are methods that can be overridden by data types derived 
   from the type they were declared in, allowing for dynamic polymorphism. 
   In contrast to Abstract methods, virtual methods must have an 
   implementation, which is used when the virtual is not overridden.

   A derived type can override virtual methods declared in its base type by 
   declaring a non-static method with the same identifier and signature, 
   meaning same number and type of parameters (invariant parameters), same 
   calling convention, and if any, same return type (or a covariant return 
   type for return by reference or by pointer):
      * if that differs only in parameter passing mode or calling 
        convention or return type, then an overriding error is returned at 
        compile time,
      * otherwise, only shadowing is allowed for any other signature 
        difference, corresponding to case where both methods would be 
        overloadable (if within the same type).
   The property of being a virtual method is not implicitly inherited by 
   the overriding method in the derived type. If this overriding method 
   must be overridden in turn in a lower level derived type, it must also 
   be declared as virtual.
   On the other hand, since a derived static method can never override a 
   base virtual/abstract method, it can therefore shadow any base method 
   (including virtual/abstract) with same identifier and regardless of the 
   signature.

   When calling virtual methods, the compiler may need to do a vtable 
   lookup in order to find out which method must be called for a given 
   object. This requires an extra hidden vtable pointer field to be added 
   at the top of each type with virtual methods. This hidden vptr is 
   provided by the built-in Object type. Because of that, virtual methods 
   can only be declared in a type that directly or indirectly Extends Object
   .

   Dynamic polymorphism by using override procedures:
      * Normally only a typename procedure (or upper in hierarchy) is 
        accessible through a base-typename reference/pointer even if this 
        one refers to an object derived from typename.
      * But when the procedure is virtual, this tells the running program 
        to resolve the override procedure the most derived relating to the 
        real object type by vtable lookup (dynamic binding at runtime), 
        rather than procedure normally accessible from the raw base-type of 
        the reference/pointer (static binding at compile time).

   Constructors cannot be virtual because they create objects, while 
   virtual methods require an already-existing object with a specific type. 
   The type of the constructor to call is determined at compile-time from 
   the code.
   In addition, when calling a virtual method inside a constructor, only 
   the version of the method corresponding to an object of type of this 
   constructor is used. That is because the vptr has not yet been set up by 
   the derived type constructor, but only by the local type constructor.

   Destructors often must be virtual when deleting an object manipulated 
   through a pointer to its base type, so that the destruction starts at 
   the most derived type and works its way down to the base type. To do 
   this, it may be necessary to add virtual destructors with an empty body 
   anywhere an explicit destruction was not yet required, in order to 
   supersede each non-virtual implicit destructor induced by the destructor 
   in its base.
   On the other hand, when calling a virtual (or abstract) method inside a 
   destructor (virtual or not), only the version of the method 
   corresponding to an object of type of this destructor is used because 
   the vptr is reset at the top of the destructor according to its own 
   type's vtable. This avoids to access child methods and so to refer to 
   child members previously destroyed by the child destructor execution.

   For member methods with Virtual in their declaration, Virtual can also 
   be specified on the corresponding method bodies, for improved code 
   readability.

   Note: In a multi-level inheritance, a same named method (same identifier 
   and signature) can be declared Abstract, Virtual or normal (without 
   specifier) at each inheritance hierarchy level. When there is mixing of  
   specifiers, the usual order is abstract -> virtual -> normal, from top 
   to bottom of the inheritance hierarchy.
   The access control (Public/Protected/Private) of an overriding method is 
   not taken into account by the internal polymorphism process, but only 
   for the initial call at compile-time.
   Base.method() calls always the base's own method, never the overriding 
   method.

Example

   '' Example with overriding subroutines

   Type Hello Extends Object
      Declare Virtual Sub hi( )
   End Type

   Type HelloEnglish Extends Hello
      Declare Sub hi( )            '' overriding subroutine
   End Type

   Type HelloFrench Extends Hello
      Declare Sub hi( )            '' overriding subroutine
   End Type

   Type HelloGerman Extends Hello
      Declare Sub hi( )            '' overriding subroutine
   End Type

   Sub Hello.hi( )
      Print "hi!"
   End Sub

   Sub HelloEnglish.hi( )           '' overriding subroutine
      Print "hello!"
   End Sub

   Sub HelloFrench.hi( )            '' overriding subroutine
      Print "Salut!"
   End Sub

   Sub HelloGerman.hi( )            '' overriding subroutine
      Print "Hallo!"
   End Sub

   Randomize( Timer( ) )

   Dim As Hello Ptr h

   For i As Integer = 0 To 9
      Select Case( Int( Rnd( ) * 4 ) + 1 )
      Case 1
         h = New HelloEnglish
      Case 2
         h = New HelloFrench
      Case 3
         h = New HelloGerman
      Case Else
         h = New Hello
      End Select

      h->hi( )
      Delete h
   Next

   Sleep

   '' Example with overriding destructor and
   ''              overriding function with covariant return

   Type myBase Extends Object
     Declare Virtual Function clone () As myBase Ptr
     Declare Virtual Sub Destroy ()
   End Type

   Function myBase.clone () As myBase Ptr
     Dim As myBase Ptr pp = New myBase(This)
     Print "myBase.clone() As myBase Ptr", pp
     Function = pp
   End Function

   Sub myBase.Destroy ()
     Print "myBase.Destroy()", , @This
     Delete @This
   End Sub

   Type myDerived Extends myBase
     Declare Function clone () As myDerived Ptr     '' overriding member function with covariant return
     Declare Sub Destroy ()                         '' overriding member subroutine
   End Type

   Function myDerived.clone () As myDerived Ptr     '' overriding member function with covariant return
     Dim As myDerived Ptr pc = New myDerived(This)
     Print "myDerived.clone() As myDerived Ptr", pc
     Function = pc
   End Function

   Sub myDerived.Destroy ()                         '' overriding member subroutine
     Print "myDerived.Destroy()", , @This
     Delete @This
   End Sub

   Dim As myDerived c

   Dim As myBase Ptr ppc = @c
   Dim As myDerived Ptr pcc = @c

   Dim As myBase Ptr ppc1 = ppc->clone()            '' using base pointers and polymorphism
   Dim As myDerived Ptr pcc1 = pcc->clone()         '' using derived pointers and covariance of return value
   Print
   ppc1->Destroy()                                  '' using base pointer and polymorphism
   pcc1->Destroy()                                  '' using derived pointer

   Sleep

Dialect Differences
   * Only available in the -lang fb dialect.

Differences from QB
   * New to FreeBASIC

See also
   * Type
   * Object
   * Extends
   * Extends Zstring
   * Extends Wstring
   * Abstract
   * Override




============================================================================
    W

------------------------------------------------------------- KeyPgWait ----
Wait

Reads from a hardware port with a mask.

Syntax
   Declare Function Wait ( ByVal port As UShort, ByVal and_mask As Long, 
   ByVal xor_mask As Long = 0 ) As Long

Usage
   Wait port, and_value [, xor_value]

Parameters
   port
      Port to read.
   and_mask
      Mask value to And the port value with.
   xor_mask
      Mask value to Xor the port value with.

Return Value
   0 if successful, -1 on failure.

Description
   Wait keeps reading port until the reading ANDed with and_mask and 
   optionally XORed with xor_mask gives a non-zero result.

   Example
   Wait &h3da, &h8 'Old Qbasic way of waiting for the monitor's vsync
   ScreenSync 'FreeBASIC way of accomplishing the same thing

Platform Differences
   * In the Windows and Linux versions three port numbers (&H3C7, &H3C8, 
     &H3C9) are hooked by the graphics library when a graphics mode is in 
     use to emulate VGA palette handling as in QB. This use is deprecated; 
     use Palette to retrieve and set palette colors.

   * Using true port access in the Windows version requires the program to 
     install a device driver for the present session. For that reason, 
     Windows executables using hardware port access should be run with 
     administrator permits each time the computer is restarted. Further 
     runs don't require admin rights as they just use the already installed 
     driver. The driver is only 3K in size and is embedded in the 
     executable.

See also
   * Inp
   * Out

   


------------------------------------------------------------- KeyPgWbin ----
WBin

Returns the binary WString (Unicode) representation of a number

Syntax
   Declare Function WBin ( ByVal number As UByte ) As WString
   Declare Function WBin ( ByVal number As UShort ) As WString
   Declare Function WBin ( ByVal number As ULong ) As WString
   Declare Function WBin ( ByVal number As ULongInt ) As WString
   Declare Function WBin ( ByVal number As Const Any Ptr ) As WString

   Declare Function WBin ( ByVal number As UByte, ByVal digits As Long ) As 
   WString
   Declare Function WBin ( ByVal number As UShort, ByVal digits As Long ) As
   WString
   Declare Function WBin ( ByVal number As ULong, ByVal digits As Long ) As 
   WString
   Declare Function WBin ( ByVal number As ULongInt, ByVal digits As Long ) 
   As WString
   Declare Function WBin ( ByVal number As Const Any Ptr, ByVal digits As 
   Long ) As WString

Usage
   result = WBin( number [, digits] )

Parameters
   number
      A whole number or expression evaluating to a whole number.
   digits
      Optional number of digits to return.

Return Value
   Returns a binary WString representation of number, truncated or padded 
   with zeros ("0") to fit the number of digits, if specified.

Description
   Returns a WString (Unicode) representing the binary value of the integer 
   number. Binary digits range from 0 to 1.

   If you specify digits > 0, the result wstring will be exactly that 
   length.  It will be truncated or padded with zeros on the left, if 
   necessary.

   The length of the returned string will not be longer than the maximum 
   number of digits required for the type of expression (32 for a Long, 64 
   for floating point or LongInt)

Example
   Print WBin(54321)
   Print WBin(54321, 5)
   Print WBin(54321, 20)

   will produce the output:

   1101010000110001
   10001
   00001101010000110001

Platform Differences
   * Unicode strings are not supported in the DOS port of FreeBASIC.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Wbin.

Differences from QB
   * New to FreeBASIC

See also
   * Bin
   * WHex
   * WOct



------------------------------------------------------------- KeyPgWchr ----
WChr

Returns a wide-character string containing one or more Unicode characters

Syntax
   Declare Function Wchr ( ByVal ch As Integer [, ... ] ) As WString

Usage
   result = WChr( ch0 [, ch1 ... chN ] )

Parameters
   ch
      The Unicode integer value of a character.

Return Value
   Returns a wide-character string.

Description
   WChr returns a wide-character string containing the character(s) 
   represented by the Unicode values passed to it.

   When WChr is used with numerical constants or literals, the result is 
   evaluated at compile-time, so it can be used in variable initializers.

   Not all Unicode characters can be displayed on any machine, the 
   characters available depend on the font presently in use in the console. 
   Graphics modes can't display Unicode characters, as the GfxLib built-in 
   font is not Unicode.
 
Example
   Print "The character represented by the UNICODE code of 934 is: "; WChr(934)
   Print "Multiple UNICODE characters: "; WChr(933, 934, 935)

   will produce the output:
The character represented by the UNICODE code of 934 is: Î¦
   Multiple UNICODE characters: Î¥Î¦Î§

Platform Differences
   * DOS does not support WChr.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Wchr.

Differences from QB
   * New to FreeBASIC

See also
   * Chr
   * WStr



---------------------------------------------------------- KeyPgWeekday ----
Weekday

Gets the number of day of the week from a Date Serial

Syntax
   Declare Function Weekday ( ByVal serial As Double , ByVal firstdayofweek 
   As Long = fbusesystem ) As Long

Usage
   #include "vbcompat.bi"
   result = Weekday( date_serial [, firstdayofweek ] )

Parameters
   date_serial
      the date
   firstdayofweek
      the first day of the week

Return Value
   Returns the week day number from a variable containing a date in 
   Date Serial format.

Description
   The week day values must be in the range 1-7, its meaning depends on the 
   firstdayofweek parameter

   firstdayofweek is optional.

         +-------+-----------------+-----------+
         |value  |first day of week|constant   |
         |omitted|sunday           |           |
         |0      |local settings   |fbUseSystem|
         |1      |sunday           |fbSunday   |
         |2      |monday           |fbMonday   |
         |3      |tuesday          |fbTuesday  |
         |4      |wednesday        |fbWednesday|
         |5      |thursday         |fbThursday |
         |6      |friday           |fbFriday   |
         |7      |saturday         |fbSaturday |
         +-------+-----------------+-----------+

   The compiler will not recognize this function unless vbcompat.bi is 
   included.

Example
   #include "vbcompat.bi"

   Dim a As Double = DateSerial (2005, 11, 28) + TimeSerial(7, 30, 50)

   Print Format(a, "yyyy/mm/dd hh:mm:ss "); Weekday(a)

Differences from QB
   * Did not exist in QB. This function appeared in PDS and VBDOS

See also
   * Date Serials



------------------------------------------------------ KeyPgWeekdayname ----
WeekdayName

Gets the name of a week day from its integral representation

Syntax
   Declare Function WeekdayName ( ByVal weekday As , ByVal abbreviate As 
   Long = 0, ByVal firstdayofweek As Long = fbUseSystem ) As String

Usage
   #include "vbcompat.bi"
   result = WeekdayName( weekday [, abbreviate [, firstdayofweek ] ] )

Parameters
   weekday
      the number of the day of the week
   abbreviate
      flag to indicate that name should be abbreviated
   firstdayofweek
      first day of the week

Return Value
   Returns the local operating system language day of week name from the 
   weekday value 1 to 7.

Description
   How weekday is interpreted depends on the firstdayofweek parameter.

   If abbreviate is true, a 3 letter abbreviation is returned, if false or 
   omitted, the whole name is returned.

   firstdayofweek is an optional parameter specified as follows:

         +-------+-----------------+-----------+
         |value  |first day of week|constant   |
         |omitted|sunday           |           |
         |0      |local settings   |fbUseSystem|
         |1      |sunday           |fbSunday   |
         |2      |monday           |fbMonday   |
         |3      |tuesday          |fbTuesday  |
         |4      |wednesday        |fbWednesday|
         |5      |thursday         |fbThursday |
         |6      |friday           |fbFriday   |
         |7      |saturday         |fbSaturday |
         +-------+-----------------+-----------+

   The compiler will not recognize this function unless vbcompat.bi or 
   datetime.bi is included.

Example
   #include "vbcompat.bi"

   Dim a As Double = DateSerial(2005, 11, 28) + TimeSerial(7, 30, 50)

   Print Format(a, "yyyy/mm/dd hh:mm:ss "); WeekdayName(Weekday(a))

Differences from QB
   * Did not exist in QB. This function appeared in Visual Basic.

See also
   * Date Serials



------------------------------------------------------------- KeyPgWend ----
Wend

Control flow statement.

Syntax
   While [condition]
      [statement block]
   Wend

Description
   Wend specifies the end of a While...Wend loop block.

Differences from QB
   * None

See also
   * While...Wend

   

------------------------------------------------------------ KeyPgWhile ----
While

Control flow statement.

Syntax
   Do While condition
      [statement block]
   Loop
or
   Do
      [statement block]
   Loop While condition
or
   While [condition]
      [statement block]
   Wend

Description
   While specifies that a loop block will continue if the condition 
   following it evaluates as true. This condition is checked during each 
   loop iteration.

Differences from QB
   * None

See also
   * Do...Loop
   * While...Wend

   

-------------------------------------------------------- KeyPgWhilewend ----
While...Wend

Control flow statement for looping

Syntax
   While [condition]
      [statement block]
   Wend

Description
   The While statement will cause the following set of statements in the 
   statement block to execute repeatedly if and while the expression 
   condition evaluates to true.

   If condition evaluates to false when the While statement is first 
   executed, then the statement block is skipped and execution resumes 
   immediately following the enclosing Wend statement.

   If an Exit While statement is encountered inside the statement block, 
   the loop is terminated, and execution resumes immediately following the 
   enclosing Wend statement. If a Continue While statement is encountered, 
   the rest of the statement block is skipped and execution resumes at the 
   While statement.

   Like all control flow statements, the While statement can be nested, 
   that is, it can be used in a statement block of another While statement.

   note: the While keyword is also used in the Do...Loop statement to 
   indicate the type of comparison. Used in this way, the Do statement 
   becomes functionally equivalent to the While statement, so do not 
   confuse their enclosing keywords Loop and Wend, respectively.

Example
   In this example, a While loop is used to reverse a string by iterating 
   through it backward. The loop stops if index is less than 0 (0 being the 
   first index in the string).
   Dim As String sentence                          '' string to reverse
   sentence = "The quick brown fox jumps over the lazy dog."

   Dim As String ecnetnes
   Dim As Integer index
   index = Len( sentence ) - 1                     '' point to last character
   While( index >= 0 )                             '' stop after first character
     ecnetnes += Chr( sentence[index] )           '' append character to new string
     index -= 1
   Wend

   Print "original: """ ; sentence ; """"
   Print "reversed: """ ; ecnetnes ; """"

   End 0

Dialect Differences
   * In the -lang qb and -lang fblite dialects, variables declared inside 
     a While..Wend loop have a function-wide scope as in QB 
   * In the -lang fb and -lang deprecated dialects, variables declared 
     inside a While..Wend block are visible only inside the block, and 
     can't be accessed outside it.

Differences from QB
   * None

See also
   * Exit
   * Continue
   * Do...Loop



------------------------------------------------------------- KeyPgWhex ----
WHex

Returns the hexadecimal WString (Unicode) representation of a number

Syntax
   Declare Function WHex ( ByVal number As UByte ) As WString
   Declare Function WHex ( ByVal number As UShort ) As WString
   Declare Function WHex ( ByVal number As ULong ) As WString
   Declare Function WHex ( ByVal number As ULongInt ) As WString
   Declare Function WHex ( ByVal number As Const Any Ptr ) As WString

   Declare Function WHex ( ByVal number As UByte, ByVal digits As Long ) As 
   WString
   Declare Function WHex ( ByVal number As UShort, ByVal digits As Long ) As
   WString
   Declare Function WHex ( ByVal number As ULong, ByVal digits As Long ) As 
   WString
   Declare Function WHex ( ByVal number As ULongInt, ByVal digits As Long ) 
   As WString
   Declare Function WHex ( ByVal number As Const Any Ptr, ByVal digits As 
   Long ) As WString

Usage
   result = WHex( number [, digits ] )

Parameters
   number
      A whole number or expression evaluating to a whole number.
   digits
      Optional number of digits to return.

Return Value
   Returns a hexadecimal WString representation of number, truncated or 
   padded with zeros ("0") to fit the number of digits, if specified.

Description
   Hexadecimal digits range from 0-9, or A-F.

   If you specify digits > 0, the resulting WString will be exactly that 
   length.  It will be truncated or padded with zeros on the left, if 
   necessary.

   The length of the wstring will not go longer than the maximum number of 
   digits required for the type of expression (8 for a Long, 16 for 
   floating point or LongInt)

Example
   Print Hex(54321)
   Print Hex(54321, 2)
   Print Hex(54321, 5)

   will produce the output:
   D431
   31
   0D431

Platform Differences
   * Unicode strings are not supported in the DOS port of FreeBASIC.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Whex.

Differences from QB
   * New to FreeBASIC.

See also
   * Hex
   * WBin
   * WOct



------------------------------------------------------------ KeyPgWidth ----
Width

Sets or gets the number of rows and columns of the display

Syntax
   Width [columns] [, rows]
   Width LPrint columns
   Width { #filenum | devicename }, columns
   result = Width( )

Parameters
   columns
      columns (in characters) for output
   rows
      rows (in characters) for output
   filenum
      file number to apply to
   devicename
      device name to apply to

Return Value
   Returns a 32 bit Long where the High Word is the number of rows and the 
   Low Word is the number of columns currently set.

Description
   Sets the maximum number of columns of characters of an output device 
   (console, printer or text file). If text sent to the device reaches the 
   width an automatic carriage return is generated.

   Using Width as a function returns the current console width in the low 
   word and the current height in the high word.

   If a device is not given then Width takes effect on the active 
   console/graphics screen, and a second argument specifying maximum number 
   of rows is allowed.

   In graphics modes Width is used to indirectly select the font size by 
   setting one of the character height * width pairs allowed (See 
   Screen (Graphics)). If  rows / cols is an invalid combination, no 
   changes are made to the screen display.

   Valid font heights are 8 pixels, 14 pixels and 16 pixels.  The fonts all 
   have a fixed width of 8 pixels.

   Using the Width command in graphic mode also forces a screen clear (Cls
   ).

Example

   Dim As Integer w
   w = Width
   Print "rows: " & HiWord(w)
   Print "cols: " & LoWord(w)

   ''Set up a graphics screen
   Const W = 320, H = 200
   ScreenRes W, H

   Dim As Integer twid, tw, th

   '' Fetch and print current text width/height:
   twid = Width()
   tw = LoWord(twid): th = HiWord(twid)
   Print "Default for current screen (8*8)"
   Print "Width:  " & tw
   Print "Height: " & th
   Sleep

   Width W\8, H\16 '' Use 8*16 font

   twid = Width()
   tw = LoWord(twid): th = HiWord(twid)
   Print "Set to 8*16 font"
   Print "Width:  " & tw
   Print "Height: " & th
   Sleep

   Width W\8, H\14 '' Use 8*14 font

   twid = Width()
   tw = LoWord(twid): th = HiWord(twid)
   Print "Set to 8*14 font"
   Print "Width:  " & tw
   Print "Height: " & th
   Sleep

   Width W\8, H\8 '' Use 8*8 font

   twid = Width()
   tw = LoWord(twid): th = HiWord(twid)
   Print "Set to 8*8 font"
   Print "Width:  " & tw
   Print "Height: " & th
   Sleep

Platform Differences
   * In a Windows console any values > 0 can be used in windowed mode.
   * On a DOS or Windows full-screen console, the valid dimensions depend 
     on the capabilities of the hardware.
   * Linux doesn't allow applications to change the console size.

Differences from QB
   * columns was limited to 40 or 80, while rows could be 25, 30, 43, 50 
     or 60, depending on the graphics hardware and screen mode being used.

See also
   * LoWord
   * HiWord
   * CsrLin
   * Pos



----------------------------------------------------------- KeyPgWindow ----
Window

Sets new view coordinates mapping for current viewport

Syntax
   Window [ [Screen] ( x1, y1 )-( x2, y2 ) ]

Parameters
   Screen
      Optional argument specifying y coordinates increase from top to 
      bottom.
   ( x1, y1 )-( x2, y2 )
      New floating point values corresponding to the opposite corners of 
      the current viewport.  If omitted, the Window coordinate mapping is 
      removed.

Description
   Window is used to define a new coordinates system. (x1, y1) and (x2, y2) 
   are the new coordinates to be mapped to the opposite corners of the 
   current viewport; all future coordinates passed to graphics primitive 
   statements will be affected by this new mapping. If Screen is omitted, 
   the new coordinates system will be Cartesian, that is, with y 
   coordinates increasing from bottom to top. Call Window with no argument 
   to disable the coordinates transformation.

   FreeBASIC's current behavior is to keep track of the corners of the 
   Window, rather than a specific coordinate mapping.  This means that the 
   coordinate mapping can change after calls to View.
   The Window corners are also currently taken into account when working on 
   image buffers, so when a Window is in effect, the coordinate mapping 
   will be different from image to image.

   When there is no Window in effect, there is no coordinate mapping in 
   effect, so the effective coordinate system is constant, independent of 
   image buffer sizes or View coordinates (if any).

Example
   '' The program shows how changing the view coordinates mapping for the current viewport changes the size of a figure drawn on the screen.
   '' The effect is one of zooming in and out:
   ''   - As the viewport coordinates get smaller, the figure appears larger on the screen, until parts of it are finally clipped because they lie outside the window.
   ''   - As the viewport coordinates get larger, the figure appears smaller on the screen.

   Declare Sub Zoom (ByVal X As Integer)
   Dim As Integer X = 500, Xdelta = 50

   Screen 12
   Do
     Do While X < 525 And X > 50
      X += Xdelta                      '' Change window size.
      Zoom(X)
      If Inkey <> "" Then Exit Do, Do  '' Stop if key pressed.
      Sleep 100
     Loop
     X -= Xdelta
     Xdelta *= -1                       '' Reverse size change.
   Loop

   Sub Zoom (ByVal X As Integer)
     Window (-X,-X)-(X,X)               '' Define new window.
     ScreenLock
     Cls
     Circle (0,0), 60, 11, , , 0.5, F   '' Draw ellipse with x-radius 60.
     ScreenUnlock
   End Sub

   Screen 13

   '' define clipping area
   View ( 10, 10 ) - ( 310, 150 ), 1, 15    

   '' set view coordinates
   Window ( -1, -1 ) - ( 1, 1 )             

   '' Draw X axis
   Line (-1,0)-(1,0),7
   Draw String ( 0.8, -0.1 ), "X"

   '' Draw Y axis
   Line (0,-1)-(0,1),7
   Draw String ( 0.1, 0.8 ), "Y"

   Dim As Single x, y, s

   '' compute step size
   s = 2 / PMap( 1, 0 )

   '' plot the function
   For x = -1 To 1 Step s
     y = x ^ 3
     PSet( x, y ), 14
   Next x

   '' revert to screen coordinates
   Window

   '' remove the clipping area
   View

   '' draw title
   Draw String ( 120, 160 ), "Y = X ^ 3"

   Sleep

Differences from QB
   * QBASIC preserves the coordinate mapping after subsequent calls to 
     VIEW.
   * FreeBASIC's current behavior is to preserve the WINDOW coordinates 
     after calls to VIEW, or when working on images, meaning that the 
     coordinate mapping may undergo scaling/translations. (If a WINDOW 
     hasn't been set, there is no coordinate mapping, and so it doesn't 
     change after calls to VIEW.)  The behavior may change in future, but 
     consistent behavior can be be assured over inconstent viewport 
     coordinates by re-calling WINDOW when you change the VIEW.

See also
   * Screen (Graphics)
   * View (Graphics)
   * PMap



------------------------------------------------------ KeyPgWindowtitle ----
WindowTitle

Sets the program window title

Syntax
   Declare Sub WindowTitle ( ByRef title As Const String )

Usage
   WindowTitle title

Parameters
   title
      the string to be assigned as new window title.

Description
   This statement is useful to change the program window title. The new 
   title set will become active immediately if the program already runs in 
   windowed mode, otherwise will become the new title for any window 
   produced by subsequent calls to the Screen (Graphics) statement. If this 
   function is not called before setting a new windowed mode via 
   Screen (Graphics), the program window will use the executable file name 
   (without the extension) as title by default.
   This command has no effect in consoles.

Example
   'Set screen mode 
   Screen 13

   'Set the window title
   WindowTitle "FreeBASIC example program"

   Sleep

Platform Differences
   * Not present in DOS version / target of FreeBASIC

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Windowtitle.

Differences from QB
   * New to FreeBASIC

See also
   * Screen (Graphics)



----------------------------------------------------------- KeyPgWinput ----
Winput()

Reads a number of wide-characters from console or file

Syntax
   Declare Function WInput( ByVal num As Integer ) As WString
   Declare Function WInput( ByVal num As Integer, ByVal filenum As Long = 0 
   ) As WString

Usage
   result = WInput( num [, [#]filenum } )

Parameters
   num
      Number of characters to read.
   filenum
      File number of bound file or device.

Return Value
   Returns a WString of the characters read.

Description
   Reads a number of wide-characters from the console, or a bound 
   file/device specified by filenum.

   The first version waits for and reads n wide characters from the 
   keyboard buffer. Extended keys are not read. The characters are not 
   echoed to the screen.

   The second version waits for and reads n wide characters from a file or 
   device. The file position is updated.

   Note: FreeBASIC does not currently support reading wide-characters from 
   the console.

Example
   Dim char As WString * 2

   Dim filename As String, enc As String
   Dim f As Integer

   Line Input "Please enter a file name: ", filename
   Line Input "Please enter an encoding type (optional): ", enc
   If enc = "" Then enc = "ascii"

   f = FreeFile
   If Open(filename For Input Encoding enc As #f) = 0 Then
      
      Print "Press space to read a character from the file, or escape to exit."
      
      Do
         
         Select Case Input(1)
         
         Case " " 'Space
            
            If EOF(f) Then
               
               Print "You have reached the end of the file."
               Exit Do
               
            End If
            
            char = WInput(1, f)
            Print char & " (char no " & Asc(char) & ")"
            
         Case Chr(27) 'Escape
            
            Exit Do
            
         End Select
         
      Loop
      
      Close #f
      
   Else
      
      Print "There was an error opening the file."
      
   End If

Dialect Differences
   * Not available in the -lang qb dialect.

Differences from QB
   * QB does not support Unicode

See also
   * Input()
   * Open



------------------------------------------------------------- KeyPgWith ----
With

Statement block to allow implicit access to fields in a user defined type 
variable

Syntax
   With user_defined_var
      statements
   End With

Description
   The With...End With block allows the omission of the name of a variable 
   of a user-defined Type when referring to its fields. The fields may then 
   be accessed with just a single period (.) before them, e.g. if the Type 
   contains an field element called "element", then it could be accessed 
   within the With block as ".element".

   It can be used as a shorthand to save typing and avoid cluttering the 
   source. With can also be used with dereferenced pointers, as the second 
   example shows.

   With blocks may be nested.  In this case, only the innermost With block 
   is active, and any outer ones are ignored until the inner one is closed 
   again.  See the third example for an illustration of this.

   Internally, a reference to the variable is taken at the start of the 
   With block, and then is used to calculate any element accesses within 
   the block.  Note that this means that Goto should not be used to jump 
   into a With block, otherwise the reference will not have been set, and 
   the results of trying to access it will be undefined.

   Note for With block used inside member procedure:
   To access duplicated symbols defined outside the Type, add two dots as 
   prefix: "..SomeSymbol" (inside a With...End With block).

Example
   Type rect_type
      x As Single
      y As Single
   End Type

   Dim the_rectangle As rect_type
   Dim As Integer temp, t

   With the_rectangle
      temp = .x
      .x = 234 * t + 48 + .y
      .y = 321 * t + 2
   End With

   Type rect_type
      x As Single
      y As Single
   End Type

   Dim the_rectangle As rect_type Ptr

   the_rectangle = CAllocate( 5 * Len( rect_type ) )

   Dim As Integer loopvar, temp, t

   For loopvar = 0 To 4

     With the_rectangle[loopvar]

      temp = .x
      .x = 234 * t + 48 + .y
      .y = 321 * t + 2

     End With

   Next

   Type rect_type
      x As Single
      y As Single
   End Type

   Dim As rect_type rect1, rect2

   '' Nested With blocks
   With rect1

      .x = 1
      .y = 2

      With rect2

         .x = 3
         .y = 4

      End With

   End With

   Print rect1.x, rect1.y '' 1,  2
   Print rect2.x, rect2.y '' 3,  4

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __With.
   * In the -lang qb and -lang fblite dialects, variables declared inside 
     a With..End With block have a function-wide scope as in QB.
   * In the -lang fb and -lang deprecated dialects, variables declared 
     inside a With..End With block are visible only inside the block, and 
     can't be accessed outside it.

Differences from QB
   * New to FreeBASIC

See also
   * Type



------------------------------------------------------------- KeyPgWoct ----
WOct

Converts a number to a Unicode octal representation

Syntax
   Declare Function WOct ( ByVal number As UByte ) As WString
   Declare Function WOct ( ByVal number As UShort ) As WString
   Declare Function WOct ( ByVal number As ULong ) As WString
   Declare Function WOct ( ByVal number As ULongInt ) As WString
   Declare Function WOct ( ByVal number As Const Any Ptr ) As WString

   Declare Function WOct ( ByVal number As UByte, ByVal digits As Long ) As 
   WString
   Declare Function WOct ( ByVal number As UShort, ByVal digits As Long ) As
   WString
   Declare Function WOct ( ByVal number As ULong, ByVal digits As Long ) As 
   WString
   Declare Function WOct ( ByVal number As ULongInt, ByVal digits As Long ) 
   As WString
   Declare Function WOct ( ByVal number As Const Any Ptr, ByVal digits As 
   Long ) As WString

Usage
   result = WOct( number [, digits ] )

Parameters
   number
      Number to convert to octal representation.
   digits
      Desired number of digits in the returned string.

Return Value
   The Unicode octal representation of the number, truncated or padded with 
   zeros ("0") to fit the number of digits, if specified.

Description
   Returns the octal WString (Unicode) representation of number. Octal 
   digits range from 0 to 7.

   If you specify digits > 0, the result string will be exactly that 
   length.  It will be truncated or padded with zeros on the left, if 
   necessary.

   The length of the returned string will not be longer than the maximum 
   number of digits required for the type of number (3 characters for Byte, 
   6 for Short, 11 for Long, and 22 for LongInt)

Example
   Print WOct(54321)
   Print WOct(54321, 4)
   Print WOct(54321, 8)

   will produce the output:

   152061
   2061
   00152061

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Woct.

Platform Differences
   * Unicode strings are not supported in the DOS port of FreeBASIC.

Differences from QB
   * In QBASIC Unicode was not supported.

See also
   * WBin
   * WHex



------------------------------------------------------------ KeyPgWrite ----
Write

Outputs a comma-separated list of values to the screen

Syntax
   Write [ expressionlist ]

Parameters
   expressionlist
      Comma-separated list of items to print

Description
   Outputs the values in expressionlist to the screen. The values are 
   separated with commas, and strings are enclosed in double quotes. 
   Numeric values with an absolute value of less than one are prefixed with 
   a zero (0) if none is given (e.g. 0.5, -0.123).  Floating-point numbers 
   with absolute values greater than or equal to 10^16, or with absolute 
   values greater than 0 and less than 10^-5 are printed in scientific 
   notation (e.g. 1.8e+019, 3e-005)

   If no expression list is given, Write outputs a carriage return.

Example

   Dim i As Integer = 10
   Dim d As Double = 123.456
   Dim s As String = "text"

   Write 123, "text", -.45600
   Write
   Write i, d, s

   will produce the output:


   123,"text",-0.456

   10,123.456,"text"

Differences from QB
   * QBASIC might print format floating-point values in slightly different 
     ways.

See also
   * Write #
   * Print
   * ?



---------------------------------------------------------- KeyPgWritePp ----
Write #

Outputs a comma-separated list of values to a text file or device

Syntax
   Write # filenum , [ expressionlist ]

Parameters
   filenum
      File number of an open file or device opened for Output or Append.
   expressionlist
      Comma-separated list of items to print

Description
   Outputs the values in expressionlist to the text file or device bound to 
   filenum. The values are separated with commas, and strings are enclosed 
   in double quotes. Numeric values greater than zero (0) and less than one 
   (1) are prefixed with a zero (0) if none is given (e.g., a value of 
   -.123 will be output as -0.123). Extra zeroes are truncated.

   If no expression list is given, Write # outputs a carriage return (note 
   that the comma after filenum is still necessary, even if no expression 
   list is given).
   The purpose of Write # is to create a file that can be read back by 
   using Input #.

Example

   Const filename As String = "file.txt"

   Dim filenum As Integer = FreeFile()
   If 0 <> Open(filename, For Output, As filenum) Then
      Print "error opening " & filename & " for output."
      End -1
   End If

   Dim i As Integer = 10
   Dim d As Double = 123.456
   Dim s As String = "text"

   Write #filenum, 123, "text", -.45600
   Write #filenum,
   Write #filenum, i, d, s

   will produce the file:


   123,"text",-0.456

   10,123.456,"text"

Differences from QB
   * None

See also
   * Write
   * Print #
   * ? #
   * Input #



-------------------------------------------------------- KeyPgWriteFile ----
Write (File Access)

File access specifier

Syntax
   Open filename As String For Binary Access Write As #filenum As Integer

Description
   Specifier for the Access clause in the Open statement.  Write specifies 
   that the file is accessible for output.

Example
   See example at Access

Differences from QB
   * None known.

See also
   * Access
   * Open



----------------------------------------------------------- KeyPgWspace ----
WSpace

Creates a WString of a given length filled with spaces (" ")

Syntax
   Declare Function WSpace( ByVal count As Integer ) As WString

Usage
   result = WSpace( count )

Parameters
   count
      An integer type specifying the length of the string to be created.

Return Value
   The created WString. An empty string will be returned if count <= 0.

Description
   WSpace creates a wstring (wide character string- Unicode) with the 
   specified number of spaces.

Example
   Dim a As WString * 10
   a = "x" + WSpace(3) + "x"
   Print a ' prints: x   x

Platform Differences
   * Unicode strings are not supported in the DOS port of FreeBASIC.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Wspace.

Differences from QB
   * New to FreeBASIC

See also
   * Space
   * WString



------------------------------------------------------------- KeyPgWstr ----
WStr

Returns a wide-character string representation of a number or ASCII 
character string

Syntax
   Declare Function WStr ( ByVal n As Byte ) As WString
   Declare Function WStr ( ByVal n As UByte ) As WString
   Declare Function WStr ( ByVal n As Short ) As WString
   Declare Function WStr ( ByVal n As UShort ) As WString
   Declare Function WStr ( ByVal n As Long ) As WString
   Declare Function WStr ( ByVal n As ULong ) As WString
   Declare Function WStr ( ByVal n As LongInt ) As WString
   Declare Function WStr ( ByVal n As ULongInt ) As WString
   Declare Function WStr ( ByVal n As Single ) As WString
   Declare Function WStr ( ByVal n As Double ) As WString
   Declare Function WStr ( ByRef str As Const String ) As WString
   Declare Function WStr ( ByVal str As Const WString Ptr ) As WString

Usage
   result = WStr( number )
      or
   result = WStr( string )

Parameters
   number
      Numeric expression to convert to a wide-character string.
   string
      String expression to convert to a wide-character string.

Return Value
   Returns the wide-character representation of the numeric or string 
   expression.

Description
   WStr converts numeric variables to their wide-character string 
   representation. It is the wide-character equivalent to Str.

   WStr also converts ASCII character strings to Unicode character strings. 
   If a wide-character string is given, that string is returned unmodified.

Example
   #if defined( __FB_WIN32__ )
   #include "windows.bi"
   #endif

   Dim zs As ZString * 20
   Dim ws As WString * 20

   zs = "Hello World"
   ws = WStr(zs)

   #if defined( __FB_WIN32__ )

   MessageBox(null, ws, WStr("Unicode 'Hello World'"), MB_OK Or MB_ICONINFORMATION)

   #else

   Print ws
   Print WStr("Unicode 'Hello World'")

   #endif

Platform Differences
   * DOS does not support WStr.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Wstr.

Differences from QB
   * New to FreeBASIC

See also
   * Str
   * WString



---------------------------------------------------------- KeyPgWstring ----
WString

Standard data type: wide character string

Syntax
   Dim variable As WString * size
   Dim variable As WString Ptr

Description
   A WString is a fixed-size array of wide-chars that never overflows if 
   the size is known at compile-time. It has no descriptor, and does never 
   resize unless it's a pointer and Allocate/Reallocate/Deallocate are used 
   directly. When the variable has a fixed size, FreeBASIC avoids any 
   overflow that could occur on assignment, by truncating the contents to a 
   length of size - 1.

   The end of the string is marked by the character 0 automatically added 
   by the FreeBASIC string handling functions, so that character must never 
   be part of a WString or the content will be truncated. The character 0 
   will be appended when the string is created, and the length will be 
   calculated by scanning the string for the first null character.

   In a WString, Len returns the size of the contained string and SizeOf 
   returns the space allocated to the WString.  SizeOf only works if the 
   size is known by the compiler, i.e. a fixed-size WString variable is 
   passed directly, not as a dereferenced pointer or a ByRef function 
   argument.

   This type is provided for support non-Latin based alphabets. Any 
   intrinsic string function like Left will work with WStrings too, as will 
   any string operator.

   When processing source files, FreeBASIC can parse ASCII files with 
   Unicode escape sequences (\u),  or UTF-8, UTF-16LE, UTF-16BE, UTF-32LE 
   and UTF-32BE files, as long as they were saved with Byte Order Mark 
   (BOM).

   The FreeBASIC text file functions can read and write Unicode files in 
   different encodings, provided the Encoding is specified when the file is 
   opened. The text is automatically converted to the internal encoding at 
   read and converted back to the file encoding at write.

   SizeOf( WString ) returns the number of bytes used by a WString 
   character in the current platform.

   When allocating dynamic memory for a WString, the safest is to use 
   CAllocate (or at worst, to use Allocate followed by an immediate 
   assignment of the string data, as in the second example), in order to 
   avoid creating string data without any null character (the terminal 
   character for a WString).

   Note : When any operand of a binary operator (as assignment, equal, +, 
   *, ...) consists in dereferencing a 'Wstring Ptr' pointer ('pw'), this 
   can give a 'Wstring' string or a 'Numeric' variable, depending on the 
   other operand. If the other operand is numeric, so the dereferenced '
   Wstring Ptr' pointer ('*pw') will be treated as a 'Numeric' reference to 
   the one character pointed. If a 'Wstring' pointer indexing '[]' operator 
   is used as dereferencing syntax ('pw[n]'), it is basically a short-cut 
   version of the 'String' indexing '[]' operator ('(*pw)[n]').

Example
   Dim As WString * 13 str1 => "hello, world"
   Print str1
   Print Len(str1)    'returns 12, the length of the string it contains 
   Print SizeOf(str1) 'returns 13 * sizeof(wstring), the number of bytes used by the variable

   Dim As WString Ptr str2
   str2 = Allocate( 13 * Len(WString) )
   *str2 = "hello, world"
   Print *str2
   Print Len(*str2)      'returns 12, the length of the string it points to

Platform Differences
   Support for wstrings relies in the C runtime library available in the 
   platform and the internal format may vary.
      * Unicode is not supported in the DOS port of FreeBASIC. In this 
        port a character takes up always 1 byte and Wstrings will behave as 
        standard ASCII Zstrings
      * On Win32 wstrings are encoded in UCS-2 and a character takes up 
        always 2 bytes. This is actually not UTF-16 LE, as FreeBASIC 
        doesn't bother with surrogates introduced in Win XP. This further 
        means that what FreeBASIC understands with a character may not 
        represent a full codepoint.
      * On Linux wstrings are encoded in UCS-4 and a character takes up 4 
        bytes.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Wstring.

Differences from QB
   * New to FreeBASIC

See also
   * String (data type)
   * ZString (data type)
   * String (function)
   * WString (function)
   * WSpace
   * WStr
   * WChr
   * WBin
   * WHex
   * WOct
   * Winput()
   * Standard Data Type Limits
   * Extends Wstring



-------------------------------------------------- KeyPgWstringFunction ----
Wstring (Function)

Fills a WString with a certain length of a certain wide character

Syntax
   Declare Function WString ( ByVal count As Integer, ByVal ch_code As Long 
   ) As WString
   Declare Function WString ( ByVal count As Integer, ByRef ch As Const 
   WString ) As WString

Usage
   result = WString( count, ch_code )
      or
   result = WString( count, ch )

Parameters
   count
      An Integer specifying the length of the string to be created.
   ch_code
      A Long specifying the Unicode char to be used to fill the string.
   ch
      A WString whose first character is to be used to fill the string.

Return Value
   The created WString. An empty string will be returned if either ch is an 
   empty string, or count <= 0.

Description
   WString generates a temporary WString filled with count copies of a 
   Unicode character. This string can be printed or assigned to a 
   previously Dimed WString.

Example
   Print WString( 4, 934 )         
   Print WString( 5, WStr("Indeed") )   
   End 0

   &#934;&#934;&#934;&#934;
   IIIII
   
Platform Differences
   * Unicode strings are not supported in the DOS port of FreeBASIC.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Wstring.

Differences from QB
   * QBasic does not support Unicode

See also
   * String (data type)
   * WSpace
   * WString (data type)




============================================================================
    X

------------------------------------------------------------ KeyPgOpXor ----
Operator Xor (Exclusive Disjunction)

Returns the bitwise-xor (exclusive disjunction) of two numeric values

Syntax
   Declare Operator Xor ( ByRef lhs As T1, ByRef rhs As T2 ) As Ret

Usage
   result = lhs Xor rhs

Parameters
   lhs
      The left-hand side expression.
   T1
      Any numeric or boolean type.
   rhs
      The right-hand side expression.
   T2
      Any numeric or boolean type.
   Ret
      A numeric or boolean type (varies with T1 and T2).

Return Value
   Returns the bitwise-xor of the two operands.

Description
   This operator returns the bitwise-exclusion of its operands, a logical 
   operation that results in a value with bits set depending on the bits of 
   the operands (for conversion of a boolean to an integer, false or true 
   boolean value becomes 0 or -1 integer value).

   The truth table below demonstrates all combinations of a 
   boolean-exclusion operation:

      +-------+-------+------+
      |Lhs Bit|Rhs Bit|Result|
      |0      |0      |0     |
      |1      |0      |1     |
      |0      |1      |1     |
      |1      |1      |0     |
      +-------+-------+------+

   No short-circuiting is performed - both expressions are always 
   evaluated.

   The return type depends on the types of values passed. Byte, UByte and 
   floating-point type values are first converted to Integer. If the left 
   and right-hand side types differ only in signedness, then the return 
   type is the same as the left-hand side type (T1), otherwise, the larger 
   of the two types is returned. Only if the left and right-hand side types 
   are both Boolean, the return type is also Boolean.

   This operator can be overloaded for user-defined types.

Example
   ' Using the XOR operator on two numeric values
   Dim As UByte numeric_value1, numeric_value2
   numeric_value1 = 15 '00001111
   numeric_value2 = 30 '00011110

   'Result =  17  =     00010001
   Print numeric_value1 Xor numeric_value2
   Sleep

   ' Using the XOR operator on two conditional expressions
   Dim As UByte numeric_value1, numeric_value2
   numeric_value1 = 10
   numeric_value2 = 15

   If numeric_value1 = 10 Xor numeric_value2 = 20 Then Print "Numeric_Value1 equals 10 or Numeric_Value2 equals 20"
   Sleep

   ' This will output "Numeric_Value1 equals 10 or Numeric_Value2 equals 20"
   ' because only the first condition of the IF statement is true

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * None

See also
   * Operator Truth Tables



----------------------------------------------------------- KeyPgXorGfx ----
Xor

Parameter to the Put graphics statement which uses a bit-wise Xor as the 
blitting method

Syntax
   Put [ target, ] [ STEP ] ( x,y ), source [ ,( x1,y1 )-( x2,y2 ) ], Xor

Parameters
   Xor
      Required.

Description
   The Xor method combines each source pixel with the corresponding 
   destination pixel, using the bit-wise Xor function.  The result of this 
   is output as the destination pixel.
   This method works in all graphics modes.  There is no mask color, 
   although color values of 0 (RGBA(0, 0, 0, 0) in full-color modes) will 
   have no effect, because of the behavior of Xor.

   In full-color modes, each component (red, green, blue and alpha) is kept 
   in a discrete set of bits, so the operation can be made to only affect 
   some of the channels, by making sure the all the values of the other 
   channels are set to 0.

Example
   ''open a graphics window
   ScreenRes 320, 200, 16

   ''create a sprite containing a circle
   Const As Integer r = 32
   Dim c As Any Ptr = ImageCreate(r * 2 + 1, r * 2 + 1, 0)
   Circle c, (r, r), r, RGBA(255, 255, 255, 0), , , 1, f

   ''put the three sprites, overlapping each other in the middle
   Put (146 - r, 108 - r), c, Xor
   Put (174 - r, 108 - r), c, Xor
   Put (160 - r,  84 - r), c, Xor

   ''free the memory used by the sprite
   ImageDestroy c

   ''pause the program before closing
   Sleep

Differences from QB
   * None

See also
   * Xor
   * Put (Graphics)




============================================================================
    Y

------------------------------------------------------------- KeyPgYear ----
Year

Gets the year from a Date Serial

Syntax
   Declare Function Year ( ByVal date_serial As Double ) As Long

Usage
   #include "vbcompat.bi"
   result = Year( date_serial )

Parameters
   date_serial
      the date

Return Value
   Returns the year from a  variable containing a date in  Date Serial  
   format. 

Description

   The compiler will not recognize this function unless vbcompat.bi is 
   included.

Example
   #include "vbcompat.bi"

   Dim a As Double = DateSerial (2005, 11, 28) + TimeSerial(7, 30, 50)

   Print Format(a, "yyyy/mm/dd hh:mm:ss "); Year(a)

Differences from QB
   * Did not exist in QB. This function appeared in PDS and VBDOS

See also
   * Date Serials




============================================================================
    Z

---------------------------------------------------------- KeyPgZstring ----
ZString

Standard data type: 8 bit character string

Syntax
   Dim variable As ZString * size
   Dim variable As ZString Ptr

Description
   A ZString is a C-style fixed-size array of chars.  It has no descriptor 
   so its length is calculated faster to pass it as an argument to 
   functions. When the variable has a fixed size, FreeBASIC avoids any 
   overflow that could occur on assignment, by truncating the contents to a 
   length of size - 1.

   A ZString Ptr can point to a standard ZString, also can be used to 
   implement an "user-managed" ZString, in this case Allocate/Reallocate/
   Deallocate must be used to size-resize-dispose it and is up  to the user 
   to avoid overflows . 

   The end of the string is marked by a null character (0 ASCII). This is 
   automatically added by the FreeBASIC string handling functions.  A null 
   character will be appended when the string is created, and the length 
   will be calculated by scanning the string for the first null character. 
   A null character (e.g. Chr(0)) may never be contained in the text of a 
   ZString or the rest of the string will be truncated.

   In a ZString, Len returns the size of the contained string and SizeOf 
   returns the space allocated to the ZString.  SizeOf only works if the 
   size is known by the compiler, i.e. a fixed-size ZString variable is 
   passed directly, not as a dereferenced pointer or a ByRef function 
   argument.

   Any intrinsic string functions like Left will work with ZString's too, 
   plus any string operator.

   This type is provided for easy interfacing with C libraries and to also 
   replace the fixed-length strings, that can't be managed through 
   pointers.
   Any string type argument may be directly passed to a procedure referring 
   to a parameter declared as ZString Ptr. The compiler performs itself an 
   automatic conversion (without warning message) between any string type 
   argument and the ZString Ptr type parameter.

   When allocating dynamic memory for a ZString, the safest is to use 
   CAllocate (or at worst, to use Allocate followed by an immediate 
   assignment of the string data, as in the second example), in order to 
   avoid creating string data without any null character (the terminal 
   character for a ZString).

   Note : When any operand of a binary operator (as assignment, equal, +, 
   *, ...) consists in dereferencing a 'Zstring Ptr' pointer ('pz'), this 
   can give a 'Zstring' string or a 'Ubyte' variable, depending on the 
   other operand. If the other operand is numeric, so the dereferenced '
   Zstring Ptr' pointer ('*pz') will be treated as a 'Ubyte' reference to 
   the one character pointed. If a 'Zstring' pointer indexing '[]' operator 
   is used as dereferencing syntax ('pz[n]'), it is basically a short-cut 
   version of the 'String' indexing '[]' operator ('(*pz)[n]').

Example
   Dim As ZString * 13 str1 => "hello, world"
   Print str1
   Print Len(str1)     'returns 12, the size of the string it contains 
   Print SizeOf(str1)  'returns 13, the size of the variable

   Dim As ZString Ptr str2
   str2 = Allocate( 13 )
   *str2 = "hello, world"
   Print *str2
   Print Len(*str2)     'returns 12, the size of the string it contains 

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Zstring.

Differences from QB
   * New to FreeBASIC

See also
   * String
   * WString
   * Standard Data Type Limits
   * Extends Zstring



---------------------------------------------------------- CatPgOpIndex ----
Operator List

List of operators used in FreeBASIC.

Assignment Operators
   * =[>] (Assignment)
   * &= (Concatenate And Assign)
   * += (Add And Assign)
   * -= (Subtract And Assign)
   * *= (Multiply And Assign)
   * /= (Divide And Assign)
   * \= (Integer Divide And Assign)
   * ^= (Exponentiate And Assign)
   * Mod= (Modulus And Assign)
   * And= (Conjunction And Assign)
   * Eqv= (Equivalence And Assign)
   * Imp= (Implication And Assign)
   * Or= (Inclusive Disjunction And Assign)
   * Xor= (Exclusive Disjunction And Assign)
   * Shl= (Shift Left And Assign)
   * Shr= (Shift Right And Assign)
   * Let (Assignment)
   * Let() (Assignment)

Type Cast Operators
   * Cast (Operator)
   * CPtr

Arithmetic Operators
   * + (Add)
   * - (Subtract)
   * * (Multiply)
   * / (Divide)
   * \ (Integer Divide)
   * ^ (Exponentiate)
   * Mod (Modulus)
   * - (Negate)
   * Shl (Shift Left)
   * Shr (Shift Right)

Indexing Operators
   * () (Array Index)
   * [] (String Index)
   * [] (Pointer Index)

String Operators
   * + (String Concatenation)
   * & (String Concatenation With Conversion)
   * Strptr (String Pointer)
Relational Operators
   * = (Equal)
   * <> (Not Equal)
   * < (Less Than)
   * <= (Less Than Or Equal)
   * >= (Greater Than Or Equal)
   * > (Greater Than)

Bitwise Operators
   * And (Conjunction)
   * Eqv (Equivalence)
   * Imp (Implication)
   * Not (Complement)
   * Or (Inclusive Disjunction)
   * Xor (Exclusive Disjunction)

Short Circuit Operators
   * Andalso (Short Circuit Conjunction)
   * Orelse (Short Circuit Inclusive Disjunction)

Preprocessor Operators
   * # (Argument Stringize)
   * ## (Argument Concatenation)
   * ! (Escaped String Literal)
   * $ (Non-Escaped String Literal)

Pointer Operators
   * @ (Address Of)
   * * (Value Of)
   * Varptr (Variable Pointer)
   * Procptr (Procedure Pointer)

Type or Class Operators
   * . (Member Access)
   * -> (Pointer To Member Access)
   * Is (Run-Time Type Information Operator)

Memory Operators
   * New Expression
      * New Overload
   * Placement New
   * Delete Statement
      * Delete Overload

Iteration Operators
   * For, Next, and Step




============================================================================
    Variables and Data Types

-------------------------------------------------------- CatPgVariables ----
Variable Declarations

Statements to declare and allocate space for variables.

Dim
   Declares a variable at the current scope.
Const
   Declares a non-modifiable variable.
Scope
   Begins a new scope block.
Static
   Declares variables in a procedure that retain their value between calls.
Shared
   Used with Dim allows variables to be visible throughout a module.
Var
   Declares variables where the data type is implied from an initializer.
Byref (Variables)
   Used with Dim or Static or Var allows to declare references.



----------------------------------------------------- CatPgUserDefTypes ----
User Defined Types

Declaration
   Declaring and describing user defined types
Referencing
   Accessing data in a user defined type
Member Procedures
   Declaring and defining methods related to a user defined type
Member Access Control
   Controlling when data and member procedures are accessed

Declarations
   Enum...End Enum
      User defined enumeration of values
   Type...End Type
      User defined structure of non overlapping data and member procedures
   Class...End Class
      Not implemented.  Keyword reserved.
   Union...End Union
      User defined structure of overlapping data
   Extends
      Extends an user defined type to derive another
   Extends Wstring
      Extends an user defined type to inherits Wstring behavior
   Extends Zstring
      Extends an user defined type to inherits Zstring behavior
   Implements
      Not implemented.  Keyword reserved.
   Field
      Specifies field alignment within a user defined type
   Object
      Built-in type providing run-time type information

Referencing
   Temporary Types
      Creates a temporary copy of a user defined type
   This
      Built-in, hidden, parameter passed to non-static member procedures to 
      access the user defined type instance
   Base (Member Access)
      Built-in, hidden, variable to access the base user defined type 
      instance in derived user defined types
   Type Alias
      Declares a user defined type from other user defined or standard data 
      types
   With
      Compound statement to access the data and members of a user defined 
      type

Member Procedures
   Base (Initialization)
      Specifies an initializer for the base user defined type in derived 
      user defined type constructors
   Constructor
      Declares or defines a member procedure that is automatically called 
      when a user defined type is created
   Destructor
      Declares or defines a member procedure that is automatically called 
      when a user defined type is destroyed or goes out of scope
   Function
      Declares or defines a member procedure returning a value
   Operator
      Declares or defines an overloaded operator
   Override
      Member method attribute that specifies that the method is expected to 
      override a virtual method in the base user defined type
   Property
      Declares or defines property member procedures for a user defined 
      type
   Sub
      Declare or defines a member procedure
   Static (Member)
      Declares or defines a member procedure or variable is static
   Virtual
      Member method attribute that declares that a member must have an 
      implementation
   Abstract
      Member method attribute that declares that a member must be 
      implemented in a derived user defined type
   Const (Member)
      Member method attribute that declares or defines that the method is 
      readonly and does not modify the user defined types's data

Member Access Control
   Public: (Access Control)
      Data and members in a user defined type have public visibility
   Private: (Access Control)
      Data and members in a user defined type have private visibility
   Protected: (Access Control)
      Data and members in a user defined type have protected visibility



----------------------------------------------------- CatPgStdDataTypes ----
Standard Data Types

Built-in data types

Integer types
   Types that store integer values, whose range is determined by the size 
   of the data type and its signedness.
Floating-point types
   Types that store real number values, whose range and precision is 
   determined by the size of the data type.
Boolean types
   Types that store boolean values.
Procedure Types
   Types that store pointers to procedures
Data Type Modifiers
   Specifies additional characteristics of a standard or user-defined data 
   type.
String types
   Types that store or point to an array of characters.
Class types
   Types that provide special capabilities to be used directly or to be 
   extended by user-defined types

Integer types
   Byte and UByte
      8-bit wide data types that store integer values.
   Short and UShort
      16-bit wide data types that store integer values.
   Long and ULong
      32-bit wide data types that store integer values.
   Integer and UInteger
      32-bit or 64-bit wide data types that store integer values.
   LongInt and ULongInt
      64-bit wide data types that store integer values.

Floating-point types
   Single
      32-bit wide data types that store real number values.
   Double
      64-bit wide data types that store real number values.

Boolean types
   Boolean
      1-bit wide data types that store boolean values.

Procedure Types
   Function Pointer
      Types that store a pointer to a function procedure
   Sub Pointer
      Types that store a pointer to a sub procedure
Data Type Modifiers
   Const
      Specifies a read only type.
   Pointer and Ptr (Shortcut For 'Pointer')
      Modifies types to be pointer types.
   Unsigned
      Specifies an unsigned integer type.
   Alias (Modifier)
      Modifies how a datatype is linked with other languages (Name 
      mangling).

String types
   String
      Fixed-length and variable-length strings with built-in memory 
      management.
   ZString
      Fixed-length and variable-length null-terminated strings.
   WString
      Fixed-length and variable-length null-terminated strings of wide 
      characters.

Class types
   Object
      Super class providing run-time type information

See also
   * Variable types and limits
   * Pointers to Procedures



----------------------------------------------------------- TblVarTypes ----
Standard Data Type Limits

Standard variable types and limits.

Numeric Types

         +---------+--------------+-----------------+--------------------------------------------------+---------------------------------------------------+----------------+-------------+
         | Type    | Size in bits | Format          | Minimum Value                                    | Maximum Value                                     | Literal Suffix | Sig. Digits |
         | BYTE    | 8            | signed   integer|-128                                              |+127                                               |                |2+           |
         |UBYTE    | 8            | unsigned integer|0                                                 |+255                                               |                |2+           |
         |SHORT    |16            |signed   integer |-32768                                            |+32767                                             |                |4+           |
         |USHORT   |16            | unsigned integer|0                                                 |65535                                              |                |4+           |
         |LONG     |32            |signed   integer |-2147483648                                       |+2147483647                                        |&, l            |9+           |
         |ULONG    | 32           |unsigned integer |0                                                 |+4294967295                                        |ul              |9+           |
         |INTEGER  |32/64 [*]     | signed   integer|[*]32bit: -2147483648, 64bit: -9223372036854775808|[*]32bit: +2147483647, 64bit: +9223372036854775807 |%               |[*]          |
         |UINTEGER |32/64 [*]     | unsigned integer|0                                                 |[*]32bit: +4294967295, 64bit: +18446744073709551615|u               |[*]          |
         |LONGINT  | 64           |signed   integer |-9223372036854775808                              |+9223372036854775807                               |ll              |18+          |
         | ULONGINT|64            |unsigned integer |0                                                 |+18446744073709551615                              | ull            |19+          |
         |SINGLE   | 32           |floating point   |[**]+/-1.401 298 E-45                             |[**]+/-3.402 823 E+38                              |!, f            |6+           |
         |DOUBLE   |64            | floating point  |[**]+/-4.940 656 458 412 465 E-324                |[**]+/-1.797 693 134 862 316 E+308                 |#, d            |15+          |
         |enums    |32/64 [*]     | signed integer  |[*]32bit: -2147483648, 64bit: -9223372036854775808|[*]32bit: +2147483647, 64bit: +9223372036854775807 |                |[*]          |
         +---------+--------------+-----------------+--------------------------------------------------+---------------------------------------------------+----------------+-------------+

   [*] Integer and UInteger data types vary with platform, matching the 
   size of pointers.
   [**] The minimum and maximum values for the floating-point types Single 
   and Double are, respectively, the values closest to zero and the values 
   closest to positive and negative infinity.

String Types

         +---------+---------------------------+------------------------------+-------------------------------------------------------+----------------+
         |Type     | Character Size (in bytes) | Minimum Size (in characters) | Maximum Size (in characters)                          | Literal Suffix |
         | String  | 1                         | 0                            | [**]32bit: +2147483647, 64bit: +9223372036854775807   | $              |
         | Zstring | 1                         | 0                            | [**]32bit: +2147483647, 64bit: +9223372036854775807   | [N/A]          |
         | Wstring | [*]                       | [*]0                         | [*,**]32bit: +2147483647, 64bit: +9223372036854775807 | [N/A]          |
         +---------+---------------------------+------------------------------+-------------------------------------------------------+----------------+

   [*] Unicode, or "wide", characters vary in both size and availability 
   with platform.
   [**] All runtime library string procedures take and produce Integer 
   values for sizes and positions. The actual maximum size will vary 
   (smaller) with storage location and/or platform.

Arrays

         +---------+-------------------------------------------------+--------------------------------+----------------------------+-------------------------+
         |Platform | Maximum Subscript Range                         | Maximum Elements per Dimension | Minimum/Maximum Dimensions | Maximum Size (in bytes) |
         | 32bit   | [*][-2147483648, +2147483647]                   | [*]+2147483647                 | 1/8                        | [*]+2147483647          |
         | 64bit   | [*][-9223372036854775808, +9223372036854775807] | [*]+9223372036854775807        | 1/8                        | [*]+9223372036854775807 |
         +---------+-------------------------------------------------+--------------------------------+----------------------------+-------------------------+

   [*] All runtime library array procedures take and produce Integer values 
   for subscripts and indexes. The actual limits will vary (smaller) with 
   the number of dimensions, element size, storage location and/or 
   platform.

See also
   Usage of suffixes for variables
   Usage of suffixes for literals / numbers



---------------------------------------------------------- CatPgCasting ----
Converting Data Types

Operators and procedures that convert between different types.

Generic conversions
   Operators to convert between arbitrary types.
Conversions to integral types
   Operators to convert to integral types.
Conversions to floating-point types
   Operators to convert to floating-point types.
Conversions to/from string types
   Operators to convert top an from string types.
Conversion to boolean types
   Operators to convert to boolean types.

Generic conversions
   Cast and CPtr
      Converts expressions between different types.

Conversions to integral types
   CByte and CUByte
      Converts numeric expressions to 8-bit values.
   CShort and CUShort
      Converts numeric expressions to 16-bit values.
   CLng and CULng
      Converts numeric expressions to 32-bit values.
   CInt and CUInt
      Converts numeric expressions to 32-bit or 64-bit values.
   CLngInt and CULngInt
      Converts numeric expressions to 64-bit values.
   CSign
      Converts a numeric expression to a signed-type value.
   CUnsg
      Converts a numeric expression to an unsigned-type value.
Conversions to floating-point types
   CSng and CDbl
      Converts a numeric or string expression to floating-point values.

Conversions to/from string types
   Str and WStr
      Converts numeric expressions or booleans to their string 
      representation.
   Val
      Converts a numeric string expression to a floating-point value.
   ValInt and ValUInt
      Converts numeric string expressions to integer values.
   ValLng and ValULng
      Converts numeric string expressions to long values.

Conversion to boolean types
   CBool
      Converts a numeric or string expression to a boolean value.




============================================================================
    Assignment operators

----------------------------------------------------- KeyPgOpAssignment ----
Operator =[>] (Assign)

Assigns a value to a variable

Syntax
   Declare Operator Let ( ByRef lhs As T1, ByRef rhs As T2 )

Usage
   lhs = rhs
      or
   lhs => rhs

         or, in the QB dialect,

   [ Let ] lhs = rhs
      or
   [ Let ] lhs => rhs

Parameters
   lhs
      The variable to assign to.
   T1
      Any numeric, boolean, string or pointer type.
   rhs
      The value to assign to lhs.
   T2
      Any type convertible to T2.

Description
   This operator assigns the value of its right-hand side operand (rhs) to 
   its left-hand side operand (lhs). The right-hand side operand must be 
   implicitly convertible to the left-hand side type (T1) (for conversion 
   of a boolean to an integer, false or true boolean value becomes 0 or -1 
   integer value). For example, you cannot assign a numeric value to a 
   string type; to do that, first convert the numeric value to a string 
   using Str or WStr.
   Assignment between arrays is not supported presently.

   Avoid confusion with Operator = (Equal), which also uses the '=' symbol.
   For this purpose and for solving some cases of ambiguity of the parser 
   (see Byref (Function Results)), the alternative symbol '=>' can be used 
   for assignments in place of '=' (same as already for the initializers).
      Note: the '=>' symbol has been chosen against '<=' (already the 
      operator 'Less Than Or Equal') and ':=' (':' used as statement 
      separator).

   This operator can be overloaded for user-defined types as a member 
   Operator using the appropriate syntax.

Example
   Dim i As Integer
   i = 420    ' <- this is the assignment operator

   If  i = 69 Then   '<-this is the equivalence operator 
     Print "ERROR: i should equal 420"
     End -1
   End If

   Print "All is good."
   End 0

   ' compile with -lang fblite or qb

   #lang "fblite"

   Dim i As Integer
   Let i = 300 ' <-alternate syntax

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.
   * In the -lang qb dialect, an assignment expression can be preceded by 
     the Let keyword.

Differences from QB
   * None

See also 
   * Operator = (Equal)
   * Operator Let (Assignment)
   * Swap
   * Coercion and Conversion



-------------------------------------------------- KeyPgOpCombineConcat ----
Operator &= (Concatenate And Assign)

Appends and assigns a string onto another string

Syntax
   Declare Operator &= ( ByRef lhs As String, ByRef rhs As T2 )
   Declare Operator &= ( ByRef lhs As WString, ByRef rhs As T2 )

Usage
   lhs &= rhs

Parameters
   lhs
      The string to assign to.
   rhs
      The value to append to lhs.
   T2
      Any numeric, string or user-defined type that can be converted to a 
      string.

Description
   This operator appends one string onto another. The right-hand side 
   expression (rhs) is converted to a string before concatenation. It is 
   functionally equivalent to,

      lhs = lhs & rhs

   where the result is assigned back to the left-hand side string.

   This operator can be overloaded for user-defined types as a member 
   Operator using the appropriate syntax.

   Note: This operator exists in C/C++ with a different meaning - there it 
   performs a bitwise And=.

Example
   Dim s As String = "Hello, "
   s &= " world!"
   Print s

   will produce the output:


   Hello, world!

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * New to FreeBASIC

See also
   * Operator & (String Concatenation With Conversion)
   * Operator +=  (Add And Assign)



----------------------------------------------------- KeyPgOpCombineAdd ----
Operator += (Add And Assign)

Adds and assigns a value to a variable

Syntax
   Declare Operator += ( ByRef lhs As T1, ByRef rhs As T2 )

   Declare Operator += ( ByRef lhs As T Ptr, ByRef rhs As Integer )

   Declare Operator += ( ByRef lhs As String, ByRef rhs As String )
   Declare Operator += ( ByRef lhs As WString, ByRef rhs As WString )

Usage
   lhs += rhs

Parameters
   lhs
      The variable to assign to.
   T1
      Any numeric type.
   rhs
      The value to add to lhs.
   T2
      Any numeric type.
   T
      Any data type.

Description
   This operator adds and assigns a value to a variable. It is functionally 
   equivalent to:

      lhs = lhs + rhs

   For numeric types, the right-hand side expression (rhs) will be 
   converted to the left-hand side type (T1).

   For string types, this operator is functionally equivalent to 
   Operator &= (Concatenate And Assign).

   This operator can be overloaded for user-defined types as a member 
   Operator using the appropriate syntax.

Example
   Dim n As Double
   n = 6
   n += 1
   Print n
   Sleep

Output:

   7

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * New to FreeBASIC

See also
   * Operator + (Add)
   * Mathematical Functions



----------------------------------------------------- KeyPgOpCombineSub ----
Operator -= (Subtract And Assign)

Subtracts and assigns a value to a variable

Syntax
   Declare Operator -= ( ByRef lhs As T1, ByRef rhs As T2 )
   Declare Operator -= ( ByRef lhs As T Ptr, ByRef rhs As Integer )

Usage
   lhs -= rhs

Parameters
   lhs
      The variable to assign to.
   T1
      Any numeric type.
   rhs
      The value to subtract from lhs.
   T2
      Any numeric type.
   T
      Any data type.

Description
   This operator subtracts and assigns a value to a variable. It is 
   functionally equivalent to:
      lhs = lhs - rhs

   For numeric types, the right-hand side expression (rhs) will be 
   converted to the left-hand side type (T1).

   This operator can be overloaded for user-defined types as a member 
   Operator using the appropriate syntax.

Example
   Dim n As Double
   n = 6
   n -= 2.2
   Print n
   Sleep

Output:

   3.8

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * New to FreeBASIC

See also
   * Operator - (Subtract)
   * Mathematical Functions



------------------------------------------------ KeyPgOpCombineMultiply ----
Operator *= (Multiply And Assign)

Multiplies and assigns a value to a variable

Syntax
   Declare Operator *= ( ByRef lhs As T1, ByRef rhs As T2 )

Usage
   lhs *= rhs

Parameters
   lhs
      The variable to assign to.
   T1
      Any numeric type.
   rhs
      The value to multiply lhs by.
   T2
      Any numeric type.

Description
   This operator multiplies and assigns a value to a variable. It is 
   functionally equivalent to:
      lhs = lhs * rhs

   The right-hand side expression (rhs) will be converted to the left-hand 
   side type (T1).

   This operator can be overloaded for user-defined types as a member 
   Operator using the appropriate syntax.

Example
   Dim n As Double
   n = 6
   n *= 2
   Print n
   Sleep

Output:

   12

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * New to FreeBASIC

See also
   * Operator * (Multiply)
   * Mathematical Functions



-------------------------------------------------- KeyPgOpCombineDivide ----
Operator /= (Divide And Assign)

Divides and assigns a value to a variable

Syntax
   Declare Operator /= ( ByRef lhs As T1, ByRef rhs As T2 )

Usage
   lhs /= rhs

Parameters
   lhs
      The variable to assign to.
   T1
      Any numeric type.
   rhs
      The value to divide lhs by.
   T2
      Any numeric type.

Description
   This operator divides and assigns a value to a variable. It is 
   functionally equivalent to:
      lhs = lhs / rhs

   This operator can be overloaded for user-defined types as a member 
   Operator using the appropriate syntax.

Example
   Dim n As Double
   n = 6
   n /= 2.2
   Print n
   Sleep

Output:

   2.727272727272727

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * New to FreeBASIC

See also
   * Operator / (Divide)
   * Mathematical Functions



------------------------------------------- KeyPgOpCombineIntegerDivide ----
Operator \= (Integer Divide And Assign)

Integer divides and assigns a value to a variable

Syntax
   Declare Operator \= ( ByRef lhs As T1, ByRef rhs As T2 )

Usage
   lhs \= rhs

Parameters
   lhs
      The variable to assign to.
   T1
      Any numeric type.
   rhs
      The value to divide lhs by.
   T2
      Any numeric type.

Description
   This operator multiplies and assigns a value to a variable. It is 
   functionally equivalent to:
      lhs = lhs \ rhs

   This operator can be overloaded for user-defined types as a member 
   Operator using the appropriate syntax.

Example
   Dim n As Double
   n = 6
   n \= 2.2
   Print n
   Sleep

Output:

   3

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * New to FreeBASIC

See also
   * Operator \ (Integer Divide)
   * Mathematical Functions



-------------------------------------------- KeyPgOpCombineExponentiate ----
Operator ^= (Exponentiate And Assign)

Exponentiates and assigns a value to a variable

Syntax
   Declare Operator ^= ( ByRef lhs As Double, ByRef rhs As Double )

Usage
   lhs ^= rhs

Parameters
   lhs
      The variable to assign to.
   rhs
      The value to exponentiate lhs by.

Description
   This operator exponentiates and assigns a value to a variable. It is 
   functionally equivalent to:
      lhs = lhs ^ rhs

   This operator can be overloaded for user-defined types as a member 
   Operator using the appropriate syntax.

   Note: This operator exists in C/C++ with a different meaning - there it 
   performs a Bitwise Xor=.

Example
   Dim n As Double
   n = 6
   n ^= 2
   Print n
   Sleep

Output:

   36

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * New to FreeBASIC

See also
   * Operator ^ (Exponentiate)
   * Mathematical Functions



------------------------------------------------------------ KeyPgOpLet ----
Operator Let (Assign)

Indicates the assignment operator when overloading Operator = (Assignment)

Syntax
   { Type | Class | Union } typename
      Declare Operator Let ( [ ByRef | ByVal ] rhs As datatype )
   End { Type | Class | Union }

   Operator typename.Let ( [ ByRef | ByVal ] rhs As datatype )

Usage
   lhs = rhs
      or
   lhs => rhs

Parameters
   typename 
      name of the Type, Class, or Union.
   lhs
      The variable to assign to.
   rhs
      The value to assign.

Description
   Let is used to overload the Operator =[>] (Assignment) operator and to 
   distinguish it from the comparison operator Operator = (Equal).

   lhs =[>] rhs will assign the rhs to lhs by invoking the Let operator 
   procedure defined in typename.
   This includes the case of an object returned from a function by value, 
   by using Function =[>] rhs (or function_identifier =[>] rhs) assignment.
   Assigning one array is not supported presently.

   An operator Let (assign) must be defined if the shallow implicit copy is 
   not sufficient. This happens in cases when the object manages 
   dynamically allocated memory or other resources which need to be 
   specially copied (for example if a member pointer points to dynamically 
   allocated memory, the implicit assignment operator will simply copy the 
   pointer value instead of allocate memory and then perform the copy of 
   data).
      Note: It is safe to do a check for self-assignment at the top of the 
      Let body (by comparing the address of implicit 'this' instance with 
      the address of 'rhs' parameter) to avoid object destruction if 
      previously allocated memory is first deallocated (see example below).

Example
   Type UDT
     Public:
      Declare Constructor (ByVal zp As Const ZString Ptr)  ''constructor with string initializer
      Declare Operator Let (ByRef rhs As UDT)              ''operator Let (assignment)
      Declare Function getString () As String              ''function to get string
      Declare Destructor ()                                ''destructor
     Private:         
      Dim zp As ZString Ptr                                ''private pointer to avoid direct access
   End Type

   Constructor UDT (ByVal zp As Const ZString Ptr)
     This.zp = CAllocate(Len(*zp) + 1)
     *This.zp = *zp
   End Constructor

   Operator UDT.Let (ByRef rhs As UDT)
     If @This <> @rhs Then  '' check for self-assignment to avoid object destruction
      Deallocate(This.zp)
      This.zp = CAllocate(Len(*rhs.zp) + 1)
      *This.zp = *rhs.zp
     End If
   End Operator

   Function UDT.getString () As String
     Return *This.zp
   End Function

   Destructor UDT ()
     Deallocate(This.zp)
   End Destructor

   Dim u As UDT = UDT("")
   u = Type<UDT>("Thanks to the overloading operator Let (assign)")
   Print u.getString
   Sleep

Output:

   Thanks To the overloading Operator Let (assign)

Dialect Differences
   * In the -lang qb and -lang fblite dialects, this operator cannot be 
     overloaded.
   * In the -lang qb and -lang fblite dialects, an assignment expression 
     can be preceded by the Let keyword.

Differences from QB
   * None.

See also
   * Let
   * Operator Let() (Assignment)
   * Operator =[>] (Assignment)
   * Operator = (Equal)
   * Coercion and Conversion



-------------------------------------------------------- KeyPgOpLetlist ----
Operator Let() (Assignment)

Assigns fields of a user defined type to a list of variables

Syntax
   Let( variable1 [, variable2 [, ... ]] ) = UDT_var
      or
   Let( variable1 [, variable2 [, ... ]] ) => UDT_var

Parameters
   variable1 [, variable2 [, ... ]]
      Comma separated list of variables to receive the values of the UDT 
      variable's fields.
   UDT_var
      A user defined type variable.

Description
   Assigns the values from the UDT_var variable's fields to the list of 
   variables.

   When the UDT Extends a Base, the first variable (variable1) assigned by 
   the operator then corresponds to a Base instance (only the other 
   variables are those to receive the values of the data fields of the UDT
   ).

   Union is not supported.

Example
   Type Vector3D
      x As Double
      y As Double
      z As Double
   End Type

   Dim a As Vector3D = ( 5, 7, 9 )

   Dim x As Double, y As Double

   '' Get the first two fields only
   Let( x, y ) = a

   Print "x = "; x
   Print "y = "; y

Output:

   x =  5
   y =  7

   Type Parent
      Dim As Integer p1, p2
   End Type

   Type Child Extends Parent
      Dim As Integer c1, c2
   End Type

   Type GrandChild Extends Child
      Dim As Integer gc1, gc2
   End Type

   Dim As GrandChild gc = Type(1, 2, 3, 4, 5, 6)

   Dim As Integer i1, i2
   Dim As Integer j1, j2
   Dim As Parent p
   Dim As Child c

   Let(c, i1, i2) = gc
   Print c.p1, c.p2, c.c1, c.c2, i1, i2

   Let(p, j1, j2) = gc
   Print p.p1, p.p2, j1, j2

Output:

    1             2             3             4             5             6
    1             2             5             6

Dialect Differences
   * Only available in the -lang fb dialect.

Differences from QB
   * New to FreeBASIC

See also
   * Let
   * Operator =[>] (Assignment)
   * Operator Let (Assignment)



------------------------------------------------- KeyPgOpCombineModulus ----
Operator Mod= (Modulus And Assign)

Divides a value and assigns the remainder to a variable

Syntax
   Declare Operator Mod= ( ByRef lhs As Integer, ByRef rhs As Integer )

Usage
   lhs Mod= rhs

Parameters
   lhs
      The variable to assign to.
   rhs
      The value to divide lhs by.

Description
   This operator divides two values of Integer type and assigns the 
   remainder to its left-hand side (lhs) variable. It is functionally 
   equivalent to:
      lhs = lhs Mod rhs

   This operator can be overloaded for user-defined types as a member 
   Operator using the appropriate syntax.

Example
   Dim n As Integer
   n = 11
   n Mod= 3
   '' The result is 2
   Print n
   Sleep

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * New to FreeBASIC

See also
   * Operator Mod (Modulus)
   * Mathematical Functions



----------------------------------------------------- KeyPgOpCombineAnd ----
Operator And= (Conjunction And Assign)

Performs a bitwise-and (conjunction) and assigns the result to a variable

Syntax
   Declare Operator And= ( ByRef lhs As T1, ByRef rhs As T2 )

Usage
   lhs And= rhs

Parameters
   lhs
      The variable to assign to.
   T1
      Any numeric or boolean type.
   rhs
      The value to perform a bitwise-and (conjunction) with lhs.
   T2
      Any numeric or boolean type.

Description
   This operator performs a bitwise-and and assigns the result to a 
   variable (for conversion of a boolean to an integer, false or true 
   boolean value becomes 0 or -1 integer value). It is functionally 
   equivalent to:
      lhs = lhs And rhs

   And= compares each bit of its operands, lhs and rhs, and if both bits 
   are 1, then the corresponding bit in the first operand, lhs, is set to 
   1, otherwise it is set to 0.

   And= cannot be used in conditional expressions.

   This operator can be overloaded for user-defined types as a member 
   Operator using the appropriate syntax.

Example
   ' Using the AND= operator on two numeric values
   Dim As UByte numeric_value1, numeric_value2
   numeric_value1 = 15 '' 00001111
   numeric_value2 = 30 '' 00011110

   numeric_value1 And= numeric_value2

   '' Result =  14  =     00001110
   Print numeric_value1
   Sleep

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * New to FreeBASIC

See also
   * And



----------------------------------------------------- KeyPgOpCombineEqv ----
Operator Eqv= (Equivalence And Assign)

Performs a bitwise-eqv (equivalence) and assigns the result to a variable

Syntax
   Declare Operator Eqv= ( ByRef lhs As T1, ByRef rhs As T2 )

Usage
   lhs Eqv= rhs

Parameters
   lhs
      The variable to assign to.
   T1
      Any numeric or boolean type.
   rhs
      The value to perform a bitwise-eqv (equivalence) with lhs.
   T2
      Any numeric or boolean type.

Description
   This operator performs a bitwise-eqv and assigns the result to a 
   variable (for conversion of a boolean to an integer, false or true 
   boolean value becomes 0 or -1 integer value). It is functionally 
   equivalent to:
      lhs = lhs Eqv rhs

   Eqv= compares each bit of its operands, lhs and rhs, and if both bits 
   are the same (either both 0 or both 1), then the corresponding bit in 
   the first operand, lhs, is set to 1, otherwise it is set to 0.

   This operator can be overloaded for user-defined types as a member 
   Operator using the appropriate syntax.

Example
   Dim As UByte a = &b00110011
   Dim As UByte b = &b01010101
   a Eqv= b
   '' Result    a = &b10011001
   Print Bin(a)

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * New to FreeBASIC

See also
   * Eqv



----------------------------------------------------- KeyPgOpCombineImp ----
Operator Imp= (Implication And Assign)

Performs a bitwise-imp (implication) and assigns the result to a variable

Syntax
   Declare Operator Imp= ( ByRef lhs As T1, ByRef rhs As T2 )

Usage
   lhs Imp= rhs

Parameters
   lhs
      The variable to assign to.
   T1
      Any numeric or boolean type.
   rhs
      The value to perform a bitwise-imp (implication) with lhs.
   T2
      Any numeric or boolean type.

Description
   This operator performs a bitwise-imp and assigns the result to a 
   variable (for conversion of a boolean to an integer, false or true 
   boolean value becomes 0 or -1 integer value). It is functionally 
   equivalent to:
      lhs = lhs Imp rhs

   Imp is a bitwise operator which is the same as (Not lhs) Or rhs.  Imp= 
   compares each bit of its operands, lhs and rhs, and if the bit in lhs is 
   0 or the bit in rhs is 1, then the corresponding bit in the first 
   operand, lhs, is set to 1, otherwise it is set to 0.

   This operator can be overloaded for user-defined types as a member 
   Operator using the appropriate syntax.

Example
   Dim As UByte a = &b00110011
   Dim As UByte b = &b01010101
   a Imp= b
   '' Result    a = &b11011101
   Print Bin(a)

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * New to FreeBASIC

See also
   * Imp
   * Assignment Operators



------------------------------------------------------ KeyPgOpCombineOr ----
Operator Or= (Inclusive Disjunction And Assign)

Performs a bitwise-or (inclusive disjunction) and assigns the result to a 
variable

Syntax
   Declare Operator Or= ( ByRef lhs As T1, ByRef rhs As T2 )

Usage
   lhs Or= rhs

Parameters
   lhs
      The variable to assign to.
   T1
      Any numeric or boolean type.
   rhs
      The value to perform a bitwise-or (inclusive disjunction) with lhs.
   T2
      Any numeric or boolean type.

Description
   This operator performs a bitwise-or and assigns the result to a variable 
   (for conversion of a boolean to an integer, false or true boolean value 
   becomes 0 or -1 integer value). It is functionally equivalent to:
      lhs = lhs Or rhs

   Or= compares each bit of its operands, lhs and rhs, and if either bits 
   are 1, then the corresponding bit in the first operand, lhs, is set to 
   1, otherwise it is set to 0.

   This operator can be overloaded for user-defined types as a member 
   Operator using the appropriate syntax.

Example
   Dim As UByte a = &b00110011
   Dim As UByte b = &b01010101
   a Or= b
   '' Result    a = &b01110111
   Print Bin(a)

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * New to FreeBASIC

See also
   * Or



----------------------------------------------------- KeyPgOpCombineXor ----
Operator Xor= (Exclusive Disjunction And Assign)

Performs a bitwise-xor (exclusive disjunction) and assigns the result to a 
variable

Syntax
   Declare Operator Xor= ( ByRef lhs As T1, ByRef rhs As T2 )

Usage
   lhs Xor= rhs

Parameters
   lhs
      The variable to assign to.
   T1
      Any numeric or boolean type.
   rhs
      The value to perform a bitwise-xor (exclusive or) with lhs.
   T2
      Any numeric or boolean type.

Description
   This operator performs a bitwise-or and assigns the result to a variable 
   (for conversion of a boolean to an integer, false or true boolean value 
   becomes 0 or -1 integer value). It is functionally equivalent to:
      lhs = lhs Xor rhs

   Xor= compares each bit of its operands, lhs and rhs, and if both bits 
   are the same (both 1 or both 0), then the corresponding bit in the first 
   operand, lhs, is set to 0, otherwise it is set to 1.

   This operator can be overloaded for user-defined types as a member 
   Operator using the appropriate syntax.

Example
   Dim As UByte a = &b00110011
   Dim As UByte b = &b01010101
   a Xor= b
   '' Result    a = &b01100110
   Print Bin(a)

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * New to FreeBASIC

See also
   * Xor



----------------------------------------------- KeyPgOpCombineShiftLeft ----
Operator Shl= (Shift Left And Assign)

Shifts left and assigns a value to a variable

Syntax
   Declare Operator Shl= ( ByRef lhs As Integer, ByRef rhs As Integer )
   Declare Operator Shl= ( ByRef lhs As UInteger, ByRef rhs As UInteger )
   Declare Operator Shl= ( ByRef lhs As LongInt, ByRef rhs As LongInt )
   Declare Operator Shl= ( ByRef lhs As ULongInt, ByRef rhs As ULongInt )

Usage
   lhs shl= rhs

Parameters
   lhs
      The variable to assign to.
   rhs
      The value to shift lhs left by.

Description
   This operator shifts the bits in its left-hand side (lhs) parameter a 
   number of times specified by its right-hand side (rhs) parameter, and 
   assigns the result to lhs. It is functionally equivalent to:
      lhs = lhs Shl rhs

   This operator can be overloaded for user-defined types as a member 
   Operator using the appropriate syntax.

Example
   Dim i As Integer
   i = &b00000011   '' = 3
   i Shl= 3         '' = i*2^3
   '' Result: 11000          24            24
   Print Bin(i), i, 3*2^3
   Sleep

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Shl=.

Differences from QB
   * New to FreeBASIC

See also
   * Operator Shl (Shift Left)
   * Operator Shr= (Shift Right And Assign)
   * Mathematical Functions



---------------------------------------------- KeyPgOpCombineShiftRight ----
Operator Shr= (Shift Right And Assign)

Shifts right and assigns a value to a variable

Syntax
   Declare Operator Shr= ( ByRef lhs As Integer, ByRef rhs As Integer )
   Declare Operator Shr= ( ByRef lhs As UInteger, ByRef rhs As UInteger )
   Declare Operator Shr= ( ByRef lhs As LongInt, ByRef rhs As LongInt )
   Declare Operator Shr= ( ByRef lhs As ULongInt, ByRef rhs As ULongInt )

Usage
   lhs shr= rhs

Parameters
   lhs
      The variable to assign to.
   rhs
      The value to shift lhs right by.

Description
   This operator shifts the bits in its left-hand side (lhs) parameter a 
   number of times specified by its right-hand side (rhs) parameter, and 
   assigns the result to lhs. It is functionally equivalent to:
      lhs = lhs Shr rhs

   This operator can be overloaded for user-defined types as a member 
   Operator using the appropriate syntax.

Example
   Dim i As Integer
   i = &b00011000   '' = 24
   i Shr= 3         '' = i\2^3
   '' Result: 11          3            3
   Print Bin(i), i, 24\2^3
   Sleep

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Shr=.

Differences from QB
   * New to FreeBASIC

See also
   * Operator Shr (Shift Right)
   * Operator Shl= (Shift Left And Assign)
   * Mathematical Functions




============================================================================
    Arithmetic operators

------------------------------------------------------------ KeyPgOpAdd ----
Operator + (Addition)

Sums two expressions

Syntax
   Declare Operator + ( ByRef lhs As Integer, ByRef rhs As Integer ) As 
   Integer
   Declare Operator + ( ByRef lhs As UInteger, ByRef rhs As UInteger ) As 
   UInteger

   Declare Operator + ( ByRef lhs As Single, ByRef rhs As Single ) As Single
   Declare Operator + ( ByRef lhs As Double, ByRef rhs As Double ) As Double

   Declare Operator + ( ByRef lhs As T Pointer, ByRef rhs As Integer ) As T 
   Pointer
   Declare Operator + ( ByRef rhs As Integer, ByRef lhs As T Pointer ) As T 
   Pointer

   Declare Operator + ( ByRef lhs As T, ByRef rhs As Integer ) As T
   Declare Operator + ( ByRef lhs As Integer, ByRef rhs As T ) As T

Usage
   result = lhs + rhs

Parameters
   lhs
      The left-hand side expression to sum.
   rhs
      The right-hand side expression to sum.
   T
      Any pointer type.

Return Value
   Returns the sum of two expressions.

Description
   When the left and right-hand side expressions are numeric values, 
   Operator + (Add) returns the sum of the two values.

   When the left and right-hand side expressions are string values, 
   Operator + (Add) concatenates the two strings and returns the result.

   If an integral value n is added to a T Pointer type, the operator 
   performs pointer arithmetic on the address, returning the memory 
   position of a T value, n indices away (assuming n is within bounds of a 
   contiguous array of T values).  This behaves differently from numeric 
   addition, because the Integer value is scaled by SizeOf( T ).

   Neither operand is modified in any way.

   This operator can be overloaded to accept user-defined types.

Example
   Dim n As Single
   n = 4.75 + 5.25
   Print n

   will produce the output:


   10

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * None

See also
   * Operator + (String Concatenation)
   * Mathematical Functions



------------------------------------------------------- KeyPgOpSubtract ----
Operator - (Subtract)

Subtracts two expressions

Syntax
   Declare Operator - ( ByRef lhs As Integer, ByRef rhs As Integer ) As 
   Integer
   Declare Operator - ( ByRef lhs As UInteger, ByRef rhs As UInteger ) As 
   UInteger

   Declare Operator - ( ByRef lhs As Single, ByRef rhs As Single ) As Single
   Declare Operator - ( ByRef lhs As Double, ByRef rhs As Double ) As Double

   Declare Operator - ( ByRef lhs As T Pointer, ByRef rhs As T Pointer ) As 
   Integer
   Declare Operator - ( ByRef lhs As T Pointer, ByRef rhs As Integer ) As T 
   Pointer

   Declare Operator - ( ByRef lhs As T, ByRef rhs As T ) As Integer
   Declare Operator - ( ByRef lhs As T, ByRef rhs As Integer ) As T
   Declare Operator - ( ByRef lhs As Integer, ByRef rhs As T ) As T

Usage
   result = lhs - rhs

Parameters
   lhs
      The left-hand side expression to subtract from.
   rhs
      The right-hand side expression to subtract.
   T
      Any pointer type.

Return Value
   Returns the subtraction of two expressions.

Description
   When the left and right-hand side expressions are numeric values, 
   Operator - (Subtract) returns the subtraction of the two values.

   If the left and right-hand side expressions are both of the T Pointer 
   type, for some type T, the operator performs pointer subtraction on the 
   address, returning the result.  This is different from numeric 
   subtraction because the difference is divided by SizeOf( T ).

   If an integral value n is subtracted from a T Pointer type, the operator 
   performs pointer arithmetic on the address, returning the memory 
   position of a T value, n indices before (assuming (-n) is within bounds 
   of a contiguous array of T values).  This behaves differently from 
   numeric subtraction, because the Integer value is scaled by SizeOf( T ).

   Neither operand is modified in any way.

   This operator can be overloaded to accept user-defined types.

Example
   Dim n As Single
   n = 4 - 5
   Print n

   will produce the output:


   -1

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * None

See also
   * Mathematical Functions



------------------------------------------------------- KeyPgOpMultiply ----
Operator * (Multiply)

Multiplies two numeric expressions

Syntax
   Declare Operator * ( ByRef lhs As Integer, ByRef rhs As Integer ) As 
   Integer
   Declare Operator * ( ByRef lhs As UInteger, ByRef rhs As UInteger ) As 
   UInteger

   Declare Operator * ( ByRef lhs As Single, ByRef rhs As Single ) As Single
   Declare Operator * ( ByRef lhs As Double, ByRef rhs As Double ) As Double

Usage
   result = lhs * rhs

Parameters
   lhs
      The left-hand side multiplicand expression.
   rhs
      The right-hand side multiplicand expression.

Return Value
   Returns the product of two multiplicands.

Description
   Operator * (Multiply) returns the product of two multiplicands.

   Neither operand is modified in any way.

   This operator can be overloaded to accept user-defined types.

Example
   Dim n As Double
   n = 4 * 5
   Print n
   Sleep

Output:

   20

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * None

See also
   * Mathematical Functions



--------------------------------------------------------- KeyPgOpDivide ----
Operator / (Divide)

Divides two numeric expressions

Syntax
   Declare Operator / ( ByRef lhs As Single, ByRef rhs As Single ) As Single
   Declare Operator / ( ByRef lhs As Double, ByRef rhs As Double ) As Double

Usage
   result = lhs / rhs

Parameters
   lhs
      The left-hand side dividend expression.
   rhs
      The right-hand side divisor expression.

Return Value
   Returns the quotient of a dividend and divisor.

Description
   Operator / (Divide) returns the quotient of a dividend and divisor.

   Neither operand is modified in any way. Unlike with integer division, 
   float division by zero is safe to perform, the quotient will hold a 
   special value representing infinity, converting it to a string returns 
   something like "Inf" or "INF", exact text is platform specific. 

   This operator can be overloaded to accept user-defined types.

Example
   Dim n As Double
   Print n / 5
   n = 6 / 2.3
   Print n
   Sleep

Output:

   0
   2.608695652173913

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * None

See also
   * Operator \ (Integer Divide)
   * Mathematical Functions



-------------------------------------------------- KeyPgOpIntegerDivide ----
Operator \ (Integer Divide)

Divides two Integer expressions

Syntax
   Declare Operator \ ( ByRef lhs As Integer, ByRef rhs As Integer ) As 
   Integer
   Declare Operator \ ( ByRef lhs As UInteger, ByRef rhs As UInteger ) As 
   UInteger

Usage
   result = lhs \ rhs

Parameters
   lhs
      The left-hand side dividend expression.
   rhs
      The right-hand side divisor expression.

Return Value
   Returns the quotient of an Integer dividend and divisor.

Description
   Operator \ (Integer division) divides two Integer expressions and 
   returns the result. Float numeric values are converted to Integer by 
   rounding up or down, and the fractional part of the resulting quotient 
   is truncated.

   If the divisor (rhs) is zero (0), a division by zero error (crash) will 
   be raised.

   Neither of the operands are modified in any way.

   This operator can be overloaded for user-defined types.

Example
   Dim n As Double
   Print n \ 5
   n = 7 \ 2.6  '' => 7 \ 3  => 2.33333  => 2
   Print n
   n = 7 \ 2.4  '' => 7 \ 2 => 3.5 => 3
   Print n
   Sleep

Output:

   0
   2
   3

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * None

See also
   * Operator / (Floating-Point Divide)
   * Operator Mod (Modulus)
   * Mathematical Functions



--------------------------------------------------- KeyPgOpExponentiate ----
Operator ^ (Exponentiate)

Raises a numeric expression to some power

Syntax
   Declare Operator ^ ( ByRef lhs As Double, ByRef rhs As Double ) As Double

Usage
   result = lhs ^ rhs

Parameters
   lhs
      The left-hand side base expression.
   rhs
      The right-hand side exponent expression.

Return Value
   Returns the exponentiation of a base expression raised to some exponent.

Description
   Operator ^ (Exponentiate) returns the result of a base expression (lhs) 
   raised to some exponent expression (rhs). ^ works with double float 
   numbers only, operands of other types will be converted into double 
   before performing the exponentiation. Exponent of a fractional value (1/
   n) is the same as taking nth root from the base, for example, 2 ^ (1/3) 
   is the cube root of 2.

   Neither of the operands are modified in any way.

   Note: this operation is not guaranteed to be fully accurate, and there 
   may be some inaccuracy in the least significant bits of the number.  
   This is particularly noticeable when the result is expected to be an 
   exact number: in these cases, you may find the result is out by a very 
   small amount.  For this reason, you should never assume that an 
   exponentiation expression will be exactly equal to the value you expect.
   This also means that you should be wary of using rounding methods such 
   as Int and Fix on the result: if you expect the result to be an integer 
   value, then there's a chance that it might be slightly lower, and will 
   round down to a value that is one less than you would expect.

   This operator can be overloaded for user-defined types.

   Note: This operator exists in C/C++ with a different meaning - there it 
   performs a Bitwise Xor.

Example
   Dim As Double n
   Input "Please enter a positive number: ", n
   Print 
   Print n;" squared is "; n ^ 2
   Print "The fifth root of "; n;" is "; n ^ 0.2
   Sleep

Output:

   Please enter a positive number: 3.4

    3.4 squared Is 11.56
   The fifth root of 3.4 Is 1.27730844458754

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * None

See also
   * Mathematical Functions



-------------------------------------------------------- KeyPgOpModulus ----
Operator Mod (Modulus)

Finds the remainder from a division operation

Syntax
   Declare Operator Mod ( ByRef lhs As Integer, ByRef rhs As Integer ) As 
   Integer

Usage
   result = lhs Mod rhs

Parameters
   lhs
      The left-hand side dividend expression.
   rhs
      The right-hand side divisor expression.

Return Value
   Returns the remainder of a division operation.

Description
   Operator Mod (Modulus) divides two Integer expressions and returns the 
   remainder. Float numeric values are converted to Integer by rounding up 
   or down.

   Neither of the operands are modified in any way.

   This operator can be overloaded for user-defined types.

Example
   Print 47 Mod 7
   Print 5.6 Mod 2.1
   Print 5.1 Mod 2.8

Output:

   5
   0
   2

This is because: 
   * 47 divided by 7 gives a remainder of 5
   * 5.6 is rounded to 6 while 2.1 is rounded to 2. This makes the problem 
     6 MOD 2 which means 6 divided by 2 which gives a remainder of 0
   * 5.1 is rounded to 5 while 2.8 is rounded to 3. This makes the problem 
     5 MOD 3 which means 5 divided by 3 which gives a remainder of 2

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * None

See also
   * Mathematical Functions



--------------------------------------------------------- KeyPgOpNegate ----
Operator - (Negate)

Changes the sign of a numeric expression

Syntax
   Declare Operator - ( ByRef rhs As Integer ) As Integer
   Declare Operator - ( ByRef rhs As Single ) As Single
   Declare Operator - ( ByRef rhs As Double ) As Double

Usage
   result = - rhs

Parameters
   rhs
      The right-hand side numeric expression to negate.

Return Value
   Returns the negative of the expression.

Description
   Operator - (Negate) is a unary operator that negates the value of its 
   operand.

   The operand is not modified in any way.

   This operator can be overloaded for user-defined types.

Example
   Dim n As LongInt
   Print -5
   n = 65432568459
   n = - n
   Print n
   Sleep

Output:

   -5
   -65432568459

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * None

See also
   * Mathematical Functions



------------------------------------------------------ KeyPgOpShiftLeft ----
Operator Shl (Shift Left)

Shifts the bits of a numeric expression to the left

Syntax
   Declare Operator Shl ( ByRef lhs As Integer, ByRef rhs As Integer ) As 
   Integer
   Declare Operator Shl ( ByRef lhs As UInteger, ByRef rhs As UInteger ) As 
   UInteger

Usage
   result = lhs Shl rhs

Parameters
   lhs
      The left-hand side expression.
   rhs
      The right-hand side shift expression.

Return Value
   Returns the result of lhs being shifted left rhs number of times.

Description
   Operator Shl (Shift left) shifts all of the bits in the left-hand side 
   expression (lhs) left a number of times specified by the right-hand side 
   expression (rhs). Numerically, the result is the same as "CInt( lhs * 2 ^
   rhs )". For example, "&b0101 Shl 1" returns the binary number &b01010, 
   and "5 Shl 1" returns 10.

   Neither of the operands are modified in any way.

   If the result is too large to fit inside the result's data type, the 
   leftmost bits are discarded ("shifted out").
   The results of this operation are undefined for values of rhs less than 
   zero, or greater than or equal to the number of bits in the result's 
   data type.

   This operator can be overloaded for user-defined types.

Example
   'Double a number
   For i As Integer = 0 To 10
      
      Print 5 Shl i, Bin(5 Shl i, 16)
      
   Next i

Output:

    5            0000000000000101
    10           0000000000001010
    20           0000000000010100
    40           0000000000101000
    80           0000000001010000
    160          0000000010100000
    320          0000000101000000
    640          0000001010000000
    1280         0000010100000000
    2560         0000101000000000
    5120         0001010000000000

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Shl.

Differences from QB
   * New to FreeBASIC

See also
   * Operator Shl= (Shift Left And Assign)
   * Operator Shr (Shift Right)
   * Bin
   * Mathematical Functions



----------------------------------------------------- KeyPgOpShiftRight ----
Operator Shr (Shift Right)

Shifts the bits of a numeric expression to the right

Syntax
   Declare Operator Shr ( ByRef lhs As Integer, ByRef rhs As Integer ) As 
   Integer
   Declare Operator Shr ( ByRef lhs As UInteger, ByRef rhs As UInteger ) As 
   UInteger

Usage
   result = lhs Shr rhs

Parameters
   lhs
      The left-hand side expression.
   rhs
      The right-hand side shift expression.

Return Value
   Returns the result of lhs being shifted right rhs number of times.

Description
   Operator Shr (Shift right) shifts all of the bits in the left-hand side 
   expression (lhs) right a number of times specified by the right-hand 
   side expression (rhs). Numerically, the result is the same as "Int(lhs / 
   2 ^ rhs)". For example, "&b0101 Shr 1" returns the binary number &b010, 
   and "5 Shr 1" returns 2.

   If the left-hand side expression is signed and negative, the sign bit is 
   copied in the newly created bits on the left after the shift.  For 
   example, "-5 Shr 2" returns -2.

   Neither of the operands are modified in any way.

   The results of this operation are undefined for values of rhs less than 
   zero, or greater than or equal to the number of bits in the result's 
   data type.

   This operator can be overloaded for user-defined types.

Example
   'Halve a number
   For i As Integer = 0 To 10
      
      Print 1000 Shr i, Bin(1000 Shr i, 16)
      
   Next i

Output:

    1000         0000001111101000
    500          0000000111110100
    250          0000000011111010
    125          0000000001111101
    62           0000000000111110
    31           0000000000011111
    15           0000000000001111
    7            0000000000000111
    3            0000000000000011
    1            0000000000000001
    0            0000000000000000

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Shr.

Differences from QB
   * New to FreeBASIC

See also
   * Operator Shr= (Shift Right And Assign)
   * Operator Shl (Shift Left)
   * Bin
   * Mathematical Functions




============================================================================
    Conditional operators

---------------------------------------------------------- KeyPgOpEqual ----
Operator = (Equal)

Compares two expressions for equality

Syntax
   Declare Operator = ( ByRef lhs As Byte, ByRef rhs As Byte ) As Integer
   Declare Operator = ( ByRef lhs As UByte, ByRef rhs As UByte ) As Integer
   Declare Operator = ( ByRef lhs As Short, ByRef rhs As Short ) As Integer
   Declare Operator = ( ByRef lhs As UShort, ByRef rhs As UShort ) As 
   Integer
   Declare Operator = ( ByRef lhs As Integer, ByRef rhs As Integer ) As 
   Integer
   Declare Operator = ( ByRef lhs As UInteger, ByRef rhs As UInteger ) As 
   Integer
   Declare Operator = ( ByRef lhs As LongInt, ByRef rhs As LongInt ) As 
   Integer
   Declare Operator = ( ByRef lhs As ULongInt, ByRef rhs As ULongInt ) As 
   Integer

   Declare Operator = ( ByRef lhs As Single, ByRef rhs As Single ) As 
   Integer
   Declare Operator = ( ByRef lhs As Double, ByRef rhs As Double ) As 
   Integer

   Declare Operator = ( ByRef lhs As String, ByRef rhs As String ) As 
   Integer
   Declare Operator = ( ByRef lhs As ZString, ByRef rhs As ZString ) As 
   Integer
   Declare Operator = ( ByRef lhs As WString, ByRef rhs As WString ) As 
   Integer

   Declare Operator = ( ByRef lhs As T, ByRef rhs As T ) As Integer

   Declare Operator = ( ByRef lhs As Boolean, ByRef rhs As Boolean ) As 
   Boolean

Usage
   result = lhs = rhs

Parameters
   lhs
      The left-hand side expression to compare to.
   rhs
      The right-hand side expression to compare to.
   T
      Any pointer type.

Return Value
   Returns negative one (-1) if expressions are equal, or zero (0) if 
   unequal.

Description
   Operator = (Equality) is a binary operator that compares two expressions 
   for equality and returns the result - a boolean value mainly in the form 
   of an Integer: negative one (-1) for true and zero (0) for false. Only 
   if the left and right-hand side types are both Boolean, the return type 
   is also Boolean. The arguments are not modified in any way.

   This operator can be overloaded to accept user-defined types as well.

   Operator = (Equality) should not be confused with initializations or 
   assignments, both of which also use the "=" symbol.

Example

   Dim i As Integer = 0    '' initialization: initialise i with a value of 0
   i = 420                 '' assignment: assign to i the value of 420

   If (i = 69) Then        '' equation: compare the equality of the value of i and 69
      Print "serious error: i should equal 420"
      End -1
   End If

   Operator <> (Inequality) is complement to Operator = (Equality), and is 
   functionally identical when combined with Operator Not (Bit-wise 
   Complement).

      If (420 = 420) Then Print "(420 = 420) is true."
      If Not (69 <> 69) Then Print "not (69 <> 69) is true."

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * none

See also
   * Operator <> (Inequality)
   * Operator =[>] (Assignment)
 


------------------------------------------------------- KeyPgOpNotEqual ----
Operator <> (Not Equal)

Compares two expressions for inequality

Syntax
   Declare Operator <> ( ByRef lhs As Byte, ByRef rhs As Byte ) As Integer
   Declare Operator <> ( ByRef lhs As UByte, ByRef rhs As UByte ) As Integer
   Declare Operator <> ( ByRef lhs As Short, ByRef rhs As Short ) As Integer
   Declare Operator <> ( ByRef lhs As UShort, ByRef rhs As UShort ) As 
   Integer
   Declare Operator <> ( ByRef lhs As Integer, ByRef rhs As Integer ) As 
   Integer
   Declare Operator <> ( ByRef lhs As UInteger, ByRef rhs As UInteger ) As 
   Integer
   Declare Operator <> ( ByRef lhs As LongInt, ByRef rhs As LongInt ) As 
   Integer
   Declare Operator <> ( ByRef lhs As ULongInt, ByRef rhs As ULongInt ) As 
   Integer

   Declare Operator <> ( ByRef lhs As Single, ByRef rhs As Single ) As 
   Integer
   Declare Operator <> ( ByRef lhs As Double, ByRef rhs As Double ) As 
   Integer

   Declare Operator <> ( ByRef lhs As String, ByRef rhs As String ) As 
   Integer
   Declare Operator <> ( ByRef lhs As ZString, ByRef rhs As ZString ) As 
   Integer
   Declare Operator <> ( ByRef lhs As WString, ByRef rhs As WString ) As 
   Integer

   Declare Operator <> ( ByRef lhs As T, ByRef rhs As T ) As Integer

   Declare Operator <> ( ByRef lhs As Boolean, ByRef rhs As Boolean ) As 
   Boolean

Usage
   result = lhs <> rhs

Parameters
   lhs
      The left-hand side expression to compare to.
   rhs
      The right-hand side expression to compare to.
   T
      Any pointer type.

Return Value
   Returns negative one (-1) if expressions are not equal, or zero (0) if 
   equal.

Description
   Operator <> (Not equal) is a binary operator that compares two 
   expressions for inequality and returns the result - a boolean value 
   mainly in the form of an Integer: negative one (-1) for true and zero 
   (0) for false. Only if the left and right-hand side types are both 
   Boolean, the return type is also Boolean. The arguments are not modified 
   in any way.

   This operator can be overloaded to accept user-defined types as well.

Example

   Dim As String a = "hello", b = "world"
   Dim As Integer i = 10, j = i

   If (a <> b) Then
     Print a & " does not equal " & b
   End If

   If (i <> j) Then
     Print "error: " & i & " does not equal " & j
   End If

   Operator = (Equal) is complement to Operator <> (Not equal), and is 
   functionally identical when combined with Operator Not (Bit-wise 
   Complement).

      If (69 <> 420) Then Print "(69 <> 420) is true."
      If Not (69 = 420) Then Print "not (69 = 420) is true."

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * none

See also
   * Operator = (Equal)



------------------------------------------------------- KeyPgOpLessThan ----
Operator < (Less Than)

Compares an expression less than another expression

Syntax
   Declare Operator < ( ByRef lhs As Byte, ByRef rhs As Byte ) As Integer
   Declare Operator < ( ByRef lhs As UByte, ByRef rhs As UByte ) As Integer
   Declare Operator < ( ByRef lhs As Short, ByRef rhs As Short ) As Integer
   Declare Operator < ( ByRef lhs As UShort, ByRef rhs As UShort ) As 
   Integer
   Declare Operator < ( ByRef lhs As Integer, ByRef rhs As Integer ) As 
   Integer
   Declare Operator < ( ByRef lhs As UInteger, ByRef rhs As UInteger ) As 
   Integer
   Declare Operator < ( ByRef lhs As LongInt, ByRef rhs As LongInt ) As 
   Integer
   Declare Operator < ( ByRef lhs As ULongInt, ByRef rhs As ULongInt ) As 
   Integer

   Declare Operator < ( ByRef lhs As Single, ByRef rhs As Single ) As 
   Integer
   Declare Operator < ( ByRef lhs As Double, ByRef rhs As Double ) As 
   Integer

   Declare Operator < ( ByRef lhs As String, ByRef rhs As String ) As 
   Integer
   Declare Operator < ( ByRef lhs As ZString, ByRef rhs As ZString ) As 
   Integer
   Declare Operator < ( ByRef lhs As WString, ByRef rhs As WString ) As 
   Integer

   Declare Operator < ( ByRef lhs As T, ByRef rhs As T ) As Integer

Usage
   result = lhs < rhs

Parameters
   lhs
      The left-hand side expression to compare to.
   rhs
      The right-hand side expression to compare to.
   T
      Any pointer type.

Return Value
   Returns negative one (-1) if the left-hand side expression is less than 
   the right-hand side expression, or zero (0) if greater than or equal.

Description
   Operator < (Less than) is a binary operator that compares two 
   expressions for inequality and returns the result - a boolean value in 
   the form of an Integer: negative one (-1) for true and zero (0) for 
   false. The arguments are not modified in any way.

   This operator can be overloaded to accept user-defined types as well.

Example

   Const size As Integer = 4
   Dim array(size - 1) As Integer = { 1, 2, 3, 4 }

   Dim index As Integer = 0
   While (index < size)
      Print array(index)
      index += 1
   Wend

   Operator >= (Greater than or equal) is complement to Operator < (Less 
   than), and is functionally identical when combined with Operator Not 
   (Bit-wise Complement).

      If (69 < 420) Then Print "(69 < 420) is true."
      If Not (69 >= 420) Then Print "not (69 >= 420) is true."

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * none

See also
   * Operator >= (Greater than or equal)



------------------------------------------------ KeyPgOpLessThanOrEqual ----
Operator <= (Less Than Or Equal)

Compares an expression less than or equal to another expression

Syntax
   Declare Operator <= ( ByRef lhs As Byte, ByRef rhs As Byte ) As Integer
   Declare Operator <= ( ByRef lhs As UByte, ByRef rhs As UByte ) As Integer
   Declare Operator <= ( ByRef lhs As Short, ByRef rhs As Short ) As Integer
   Declare Operator <= ( ByRef lhs As UShort, ByRef rhs As UShort ) As 
   Integer
   Declare Operator <= ( ByRef lhs As Integer, ByRef rhs As Integer ) As 
   Integer
   Declare Operator <= ( ByRef lhs As UInteger, ByRef rhs As UInteger ) As 
   Integer
   Declare Operator <= ( ByRef lhs As LongInt, ByRef rhs As LongInt ) As 
   Integer
   Declare Operator <= ( ByRef lhs As ULongInt, ByRef rhs As ULongInt ) As 
   Integer

   Declare Operator <= ( ByRef lhs As Single, ByRef rhs As Single ) As 
   Integer
   Declare Operator <= ( ByRef lhs As Double, ByRef rhs As Double ) As 
   Integer

   Declare Operator <= ( ByRef lhs As String, ByRef rhs As String ) As 
   Integer
   Declare Operator <= ( ByRef lhs As ZString, ByRef rhs As ZString ) As 
   Integer
   Declare Operator <= ( ByRef lhs As WString, ByRef rhs As WString ) As 
   Integer

   Declare Operator <= ( ByRef lhs As T, ByRef rhs As T ) As Integer

Usage
   result = lhs <= rhs

Parameters
   lhs
      The left-hand side expression to compare to.
   rhs
      The right-hand side expression to compare to.
   T
      Any pointer type.

Return Value
   Returns negative one (-1) if the left-hand side expression is less than 
   or equal to the right-hand side expression, or zero (0) if greater than.

Description
   Operator <= (Less than or Equal) is a binary operator that compares an 
   expression less than or equal to another expression and returns the 
   result - a boolean value in the form of an Integer: negative one (-1) 
   for true and zero (0) for false. The arguments are not modified in any 
   way.

   This operator can be overloaded to accept user-defined types as well.

Example
   Operator > (Greater than) is complement to Operator <= (Less than or 
   Equal), and is functionally identical when combined with Operator Not 
   (Bit-wise Complement).

      If (69 <= 420) Then Print "(69 <= 420) is true."
      If Not (60 > 420) Then Print "not (420 > 69) is true."

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * none

See also
   * Operator > (Greater than)



--------------------------------------------- KeyPgOpGreaterThanOrEqual ----
Operator >= (Greater Than Or Equal)

Compares an expression greater than or equal to another expression

Syntax
   Declare Operator >= ( ByRef lhs As Byte, ByRef rhs As Byte ) As Integer
   Declare Operator >= ( ByRef lhs As UByte, ByRef rhs As UByte ) As Integer
   Declare Operator >= ( ByRef lhs As Short, ByRef rhs As Short ) As Integer
   Declare Operator >= ( ByRef lhs As UShort, ByRef rhs As UShort ) As 
   Integer
   Declare Operator >= ( ByRef lhs As Integer, ByRef rhs As Integer ) As 
   Integer
   Declare Operator >= ( ByRef lhs As UInteger, ByRef rhs As UInteger ) As 
   Integer
   Declare Operator >= ( ByRef lhs As LongInt, ByRef rhs As LongInt ) As 
   Integer
   Declare Operator >= ( ByRef lhs As ULongInt, ByRef rhs As ULongInt ) As 
   Integer

   Declare Operator >= ( ByRef lhs As Single, ByRef rhs As Single ) As 
   Integer
   Declare Operator >= ( ByRef lhs As Double, ByRef rhs As Double ) As 
   Integer

   Declare Operator >= ( ByRef lhs As String, ByRef rhs As String ) As 
   Integer
   Declare Operator >= ( ByRef lhs As ZString, ByRef rhs As ZString ) As 
   Integer
   Declare Operator >= ( ByRef lhs As WString, ByRef rhs As WString ) As 
   Integer

   Declare Operator >= ( ByRef lhs As T, ByRef rhs As T ) As Integer

Usage
   result = lhs >= rhs

Parameters
   lhs
      The left-hand side expression to compare to.
   rhs
      The right-hand side expression to compare to.
   T
      Any pointer type.

Return Value
   Returns negative one (-1) if the left-hand side expression is greater 
   than or equal to the right-hand side expression, or zero (0) if less 
   than.

Description
   Operator >= (Greater than or Equal) is a binary operator that compares 
   an expression greater than or equal to another expression and returns 
   the result - a boolean value in the form of an Integer: negative one 
   (-1) for true and zero (0) for false. The arguments are not modified in 
   any way.

   This operator can be overloaded to accept user-defined types as well.

Example
   Operator < (Less than) is complement to Operator >= (Greater than or 
   Equal), and is functionally identical when combined with Operator Not 
   (Bit-wise Complement).

      If (420 >= 69) Then Print "(420 >= 69) is true."
      If Not (420 < 69) Then Print "not (420 < 69) is true."

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * none

See also
   * Operator < (Less than)



---------------------------------------------------- KeyPgOpGreaterThan ----
Operator > (Greater Than)

Compares an expression greater than another expression

Syntax
   Declare Operator > ( ByRef lhs As Byte, ByRef rhs As Byte ) As Integer
   Declare Operator > ( ByRef lhs As UByte, ByRef rhs As UByte ) As Integer
   Declare Operator > ( ByRef lhs As Short, ByRef rhs As Short ) As Integer
   Declare Operator > ( ByRef lhs As UShort, ByRef rhs As UShort ) As 
   Integer
   Declare Operator > ( ByRef lhs As Integer, ByRef rhs As Integer ) As 
   Integer
   Declare Operator > ( ByRef lhs As UInteger, ByRef rhs As UInteger ) As 
   Integer
   Declare Operator > ( ByRef lhs As LongInt, ByRef rhs As LongInt ) As 
   Integer
   Declare Operator > ( ByRef lhs As ULongInt, ByRef rhs As ULongInt ) As 
   Integer

   Declare Operator > ( ByRef lhs As Single, ByRef rhs As Single ) As 
   Integer
   Declare Operator > ( ByRef lhs As Double, ByRef rhs As Double ) As 
   Integer

   Declare Operator > ( ByRef lhs As String, ByRef rhs As String ) As 
   Integer
   Declare Operator > ( ByRef lhs As ZString, ByRef rhs As ZString ) As 
   Integer
   Declare Operator > ( ByRef lhs As WString, ByRef rhs As WString ) As 
   Integer

   Declare Operator > ( ByRef lhs As T, ByRef rhs As T ) As Integer

Usage
   result = lhs > rhs

Parameters
   lhs
      The left-hand side expression to compare to.
   rhs
      The right-hand side expression to compare to.
   T
      Any pointer type.

Return Value
   Returns negative one (-1) if the left-hand side expression is greater 
   than the right-hand side expression, or zero (0) if less than or equal.

Description
   Operator > (Greater than) is a binary operator that compares an 
   expression greater than another expression and returns the result - a 
   boolean value in the form of an Integer: negative one (-1) for true and 
   zero (0) for false. The arguments are not modified in any way.

   This operator can be overloaded to accept user-defined types as well.

Example
   Operator <= (Less than or equal) is complement to Operator > (Greater 
   than), and is functionally identical when combined with Operator Not 
   (Bit-wise Complement).

      If (420 > 69) Then Print "(420 > 69) is true."
      If Not (420 <= 69) Then Print "not (420 <= 69) is true."

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * none

See also
   * Operator <= (Less than or equal)



------------------------------------------------------------- KeyPgOpIs ----
Operator Is (Run-Time Type Information)

Check if an object is compatible to a type derived from its compile-time 
type
(in the context of inheritance)

Syntax
   result = expression Is  typename

Parameters
   expression
      The expression to check, an object of a type that is directly or 
      indirectly derived from Object using Extends.
   typename
      The child type to check for. This type must be directly or indirectly 
      derived from the type of expression (the compile-time type of the 
      object).

Return Value
   Returns negative one (-1) if the expression is an object of real-type 
   typename or one of its base-types derived from the expression type, or 
   zero (0) if it's an object of an incompatible type.

Description
   The Is operator must be used in conjunction with inheritance in order to 
   check compatibility between objects and types from an inheritance 
   structure extending the built-in Object type.

   The Is operator is a binary operator that checks whether an object is 
   compatible to its derived types at run-time. Because Is relies on 
   Run-Time Type Information (RTTI), it can only be used with types that 
   are derived from the built-in Object type using Extends. The compiler 
   disallows using Is for checks that can be solved at compile-time.

   The Is operator is successful not only for the real-type (the "lowest"), 
   but also for its base-types, as long as they are still below the type of 
   expression (the compile-time type). In order to determine the real-type, 
   all possibilities from lowest to highest must be checked.

   Extending the built-in Object type allows to add an extra hidden vtable 
   pointer field at the top of the Type. The vtable is used to access 
   information for run-time type identification used by the Is operator.

   This operator cannot be overloaded.

Example
   Type Vehicle Extends Object
      As String Name
   End Type

   Type Car Extends Vehicle
   End Type

   Type Cabriolet Extends Car
   End Type

   Type Bike Extends Vehicle
   End Type

   Sub identify(ByVal p As Object Ptr)
      Print "Identifying:"

      '' Not a Vehicle object?
      If Not (*p Is Vehicle) Then
         Print , "unknown object"
         Return
      End If

      '' The cast is safe, because we know it's a Vehicle object
      Print , "name: " & CPtr(Vehicle Ptr, p)->Name

      If *p Is Car Then
         Print , "It's a car"
      End If

      If *p Is Cabriolet Then
         Print , "It's a cabriolet"
      End If

      If *p Is Bike Then
         Print , "It's a bike"
      End If
   End Sub

   Dim As Car ford
   ford.name = "Ford"
   identify(@ford)

   Dim As Cabriolet porsche
   porsche.name = "Porsche"
   identify(@porsche)

   Dim As Bike mountainbike
   mountainbike.name = "Mountain Bike"
   identify(@mountainbike)

   Dim As Vehicle v
   v.name = "some unknown vehicle"
   identify(@v)

   Dim As Object o
   identify(@o)

Differences from QB
   * New to FreeBASIC

See also
   * Extends
   * Extends Zstring
   * Extends Wstring
   * Object
   * Is (Select Case)
   * TypeOf
 



============================================================================
    Logical operators

------------------------------------------------------------ KeyPgOpAnd ----
Operator And (Conjunction)

Returns the bitwise-and (conjunction) of two numeric values

Syntax
   Declare Operator And ( ByRef lhs As T1, ByRef rhs As T2 ) As Ret

Usage
   result = lhs And rhs

Parameters
   lhs
      The left-hand side expression.
   T1
      Any numeric or boolean type.
   rhs
      The right-hand side expression.
   T2
      Any numeric or boolean type.
   Ret
      A numeric or boolean type (varies with T1 and T2).

Return Value
   Returns the bitwise-and (conjunction) of the two operands.

Description
   This operator returns the bitwise-and of its operands, a logical 
   operation that results in a value with bits set depending on the bits of 
   the operands (for conversion of a boolean to an integer, false or true 
   boolean value becomes 0 or -1 integer value).

   The truth table below demonstrates all combinations of a boolean-and 
   operation:

      +-------+-------+------+
      |Lhs Bit|Rhs Bit|Result|
      |0      |0      |0     |
      |1      |0      |0     |
      |0      |1      |0     |
      |1      |1      |1     |
      +-------+-------+------+

   No short-circuiting is performed - both expressions are always 
   evaluated.

   The return type depends on the types of values passed. Byte, UByte and 
   floating-point type values are first converted to Integer. If the left 
   and right-hand side types differ only in signedness, then the return 
   type is the same as the left-hand side type (T1), otherwise, the larger 
   of the two types is returned. Only if the left and right-hand side types 
   are both Boolean, the return type is also Boolean.

   This operator can be overloaded for user-defined types.

Example
   ' Using the AND operator on two numeric values
   Dim As UByte numeric_value1, numeric_value2
   numeric_value1 = 15 '00001111
   numeric_value2 = 30 '00011110

   'Result =  14  =     00001110
   Print numeric_value1 And numeric_value2
   Sleep

   ' Using the AND operator on two conditional expressions
   Dim As UByte numeric_value1, numeric_value2
   numeric_value1 = 15
   numeric_value2 = 25

   If numeric_value1 > 10 And numeric_value1 < 20 Then Print "Numeric_Value1 is between 10 and 20"
   If numeric_value2 > 10 And numeric_value2 < 20 Then Print "Numeric_Value2 is between 10 and 20"
   Sleep

   ' This will output "Numeric_Value1 is between 10 and 20" because
   ' both conditions of the IF statement is true
   ' It will not output the result of the second IF statement because the first
   ' condition is true and the second is false.

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * None

See also
   * AndAlso
   * Operator Truth Tables



------------------------------------------------------------ KeyPgOpEqv ----
Operator Eqv (Equivalence)

Returns the bitwise-and (equivalence) of two numeric values

Syntax
   Declare Operator Eqv ( ByRef lhs As T1, ByRef rhs As T2 ) As Ret

Usage
   result = lhs Eqv rhs

Parameters
   lhs
      The left-hand side expression.
   T1
      Any numeric or boolean type.
   rhs
      The right-hand side expression.
   T2
      Any numeric or boolean type.
   Ret
      A numeric or boolean type (varies with T1 and T2).

Return Value
   Returns the bitwise-equivalence of the two operands.

Description
   This operator returns the bitwise-equivalence of its operands, a logical 
   operation that results in a value with bits set depending on the bits of 
   the operands (for conversion of a boolean to an integer, false or true 
   boolean value becomes 0 or -1 integer value).

   The truth table below demonstrates all combinations of a 
   boolean-equivalence operation:

      +-------+-------+------+
      |Lhs Bit|Rhs Bit|Result|
      |0      |0      |1     |
      |1      |0      |0     |
      |0      |1      |0     |
      |1      |1      |1     |
      +-------+-------+------+

   No short-circuiting is performed - both expressions are always 
   evaluated.

   The return type depends on the types of values passed. Byte, UByte and 
   floating-point type values are first converted to Integer. If the left 
   and right-hand side types differ only in signedness, then the return 
   type is the same as the left-hand side type (T1), otherwise, the larger 
   of the two types is returned. Only if the left and right-hand side types 
   are both Boolean, the return type is also Boolean.

   This operator can be overloaded for user-defined types.

Example
   Dim As UByte a = &b00110011
   Dim As UByte b = &b01010101, c
   c = a Eqv b '' c = &b10011001

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * None

See also
   * Operator Truth Tables



------------------------------------------------------------ KeyPgOpImp ----
Operator Imp (Implication)

Returns the bitwise-and (implication) of two numeric values

Syntax
   Declare Operator Imp ( ByRef lhs As T1, ByRef rhs As T2 ) As Ret

Usage
   result = lhs Imp rhs

Parameters
   lhs
      The left-hand side expression.
   T1
      Any numeric or boolean type.
   rhs
      The right-hand side expression.
   T2
      Any numeric or boolean type.
   Ret
      A numeric or boolean type (varies with T1 and T2).

Return Value
   Returns the bitwise-implication of the two operands.

Description
   This operator returns the bitwise-implication of its operands, a logical 
   operation that results in a value with bits set depending on the bits of 
   the operands (for conversion of a boolean to an integer, false or true 
   boolean value becomes 0 or -1 integer value).

   The truth table below demonstrates all combinations of a 
   boolean-implication operation:

      +-------+-------+------+
      |Lhs Bit|Rhs Bit|Result|
      |0      |0      |1     |
      |1      |0      |0     |
      |0      |1      |1     |
      |1      |1      |1     |
      +-------+-------+------+

   No short-circuiting is performed - both expressions are always 
   evaluated.

   The return type depends on the types of values passed. Byte, UByte and 
   floating-point type values are first converted to Integer. If the left 
   and right-hand side types differ only in signedness, then the return 
   type is the same as the left-hand side type (T1), otherwise, the larger 
   of the two types is returned. Only if the left and right-hand side types 
   are both Boolean, the return type is also Boolean.

   This operator can be overloaded for user-defined types.

Example
   Dim As UByte a, b, c
   a = &b00001111
   b = &b01010101
   c = a Imp b '' c = &b11110101

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * None

See also
   * Operator Truth Tables



------------------------------------------------------------ KeyPgOpNot ----
Operator Not (Complement)

Returns the bitwise-not (complement) of a numeric value

Syntax
   Declare Operator Not ( ByRef rhs As Byte ) As Integer
   Declare Operator Not ( ByRef rhs As UByte ) As Integer
   Declare Operator Not ( ByRef rhs As Single ) As Integer
   Declare Operator Not ( ByRef rhs As Double ) As Integer

   Declare Operator Not ( ByRef rhs As T ) As T

Usage
   result = Not rhs

Parameters
   rhs
      The right-hand side expression.
   T
      Any numeric or boolean type.

Return Value
   Returns the bitwise-complement of its operand.

Description
   This operator returns the bitwise-complement of its operand, a logical 
   operation that results in a value with bits set depending on the bits of 
   the operand.
   (for a boolean type, 'Not false' returns 'true' and 'Not true' returns 
   'false')

   The truth table below demonstrates all combinations of a 
   boolean-complement operation:

      +-------+------+
      |Rhs Bit|Result|
      |0      |1     |
      |1      |0     |
      +-------+------+

   This operator can be overloaded for user-defined types.

Example
   ' Using the NOT operator on a numeric value

   Dim numeric_value As Byte
   numeric_value = 15 '00001111

   'Result = -16 =     11110000
   Print Not numeric_value

   ' Using the NOT operator on conditional expressions
   Dim As UByte numeric_value1, numeric_value2
   numeric_value1 = 15
   numeric_value2 = 25

   If Not numeric_value1 = 10 Then Print "Numeric_Value1 is not equal to 10"
   If Not numeric_value2 = 25 Then Print "Numeric_Value2 is not equal to 25"

   ' This will output "Numeric_Value1 is not equal to 10" because
   ' the first IF statement is false.
   ' It will not output the result of the second IF statement because the
   ' condition is true. 

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * None

See also
   * Operator Truth Tables



------------------------------------------------------------- KeyPgOpOr ----
Operator Or (Inclusive Disjunction)

Returns the bitwise-or (inclusive disjunction) of two numeric values

Syntax
   Declare Operator Or ( ByRef lhs As T1, ByRef rhs As T2 ) As Ret

Usage
   result = lhs Or rhs

Parameters
   lhs
      The left-hand side expression.
   T1
      Any numeric or boolean type.
   rhs
      The right-hand side expression.
   T2
      Any numeric or boolean type.
   Ret
      A numeric or boolean type (varies with T1 and T2).

Return Value
   Returns the bitwise-disjunction of the two operands.

Description
   This operator returns the bitwise-disjunction of its operands, a logical 
   operation that results in a value with bits set depending on the bits of 
   the operands (for conversion of a boolean to an integer, false or true 
   boolean value becomes 0 or -1 integer value).

   The truth table below demonstrates all combinations of a 
   boolean-disjunction operation:

      +-------+-------+------+
      |Lhs Bit|Rhs Bit|Result|
      |0      |0      |0     |
      |1      |0      |1     |
      |0      |1      |1     |
      |1      |1      |1     |
      +-------+-------+------+

   No short-circuiting is performed - both expressions are always 
   evaluated.

   The return type depends on the types of values passed. Byte, UByte and 
   floating-point type values are first converted to Integer. If the left 
   and right-hand side types differ only in signedness, then the return 
   type is the same as the left-hand side type (T1), otherwise, the larger 
   of the two types is returned. Only if the left and right-hand side types 
   are both Boolean, the return type is also Boolean.

   This operator can be overloaded for user-defined types.

Example
   ' Using the OR operator on two numeric values
   Dim As UByte numeric_value1, numeric_value2
   numeric_value1 = 15 '00001111
   numeric_value2 = 30 '00011110

   'Result =  31  =     00011111       
   Print numeric_value1 Or numeric_value2
   Sleep

   ' Using the OR operator on two conditional expressions
   Dim As UByte numeric_value
   numeric_value = 10

   If numeric_value = 5 Or numeric_value = 10 Then Print "Numeric_Value equals 5 or 10"
   Sleep

   ' This will output "Numeric_Value equals 5 or 10" because
   ' while the first condition of the first IF statement is false, the second is true

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * None

See also
   * OrElse
   * Operator Truth Tables



------------------------------------------------------------ KeyPgOpXor ----
Operator Xor (Exclusive Disjunction)

Returns the bitwise-xor (exclusive disjunction) of two numeric values

Syntax
   Declare Operator Xor ( ByRef lhs As T1, ByRef rhs As T2 ) As Ret

Usage
   result = lhs Xor rhs

Parameters
   lhs
      The left-hand side expression.
   T1
      Any numeric or boolean type.
   rhs
      The right-hand side expression.
   T2
      Any numeric or boolean type.
   Ret
      A numeric or boolean type (varies with T1 and T2).

Return Value
   Returns the bitwise-xor of the two operands.

Description
   This operator returns the bitwise-exclusion of its operands, a logical 
   operation that results in a value with bits set depending on the bits of 
   the operands (for conversion of a boolean to an integer, false or true 
   boolean value becomes 0 or -1 integer value).

   The truth table below demonstrates all combinations of a 
   boolean-exclusion operation:

      +-------+-------+------+
      |Lhs Bit|Rhs Bit|Result|
      |0      |0      |0     |
      |1      |0      |1     |
      |0      |1      |1     |
      |1      |1      |0     |
      +-------+-------+------+

   No short-circuiting is performed - both expressions are always 
   evaluated.

   The return type depends on the types of values passed. Byte, UByte and 
   floating-point type values are first converted to Integer. If the left 
   and right-hand side types differ only in signedness, then the return 
   type is the same as the left-hand side type (T1), otherwise, the larger 
   of the two types is returned. Only if the left and right-hand side types 
   are both Boolean, the return type is also Boolean.

   This operator can be overloaded for user-defined types.

Example
   ' Using the XOR operator on two numeric values
   Dim As UByte numeric_value1, numeric_value2
   numeric_value1 = 15 '00001111
   numeric_value2 = 30 '00011110

   'Result =  17  =     00010001
   Print numeric_value1 Xor numeric_value2
   Sleep

   ' Using the XOR operator on two conditional expressions
   Dim As UByte numeric_value1, numeric_value2
   numeric_value1 = 10
   numeric_value2 = 15

   If numeric_value1 = 10 Xor numeric_value2 = 20 Then Print "Numeric_Value1 equals 10 or Numeric_Value2 equals 20"
   Sleep

   ' This will output "Numeric_Value1 equals 10 or Numeric_Value2 equals 20"
   ' because only the first condition of the IF statement is true

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * None

See also
   * Operator Truth Tables




============================================================================
    Short circuit operators

-------------------------------------------------------- KeyPgOpAndAlso ----
Operator Andalso (Short Circuit Conjunction)

Returns the short circuit-and (conjunction) of two numeric values

Syntax
   Declare Operator AndAlso ( ByRef lhs As T1, ByRef rhs As T2 ) As Ret

Usage
   result = lhs AndAlso rhs

Parameters
   lhs
      The left-hand side expression.
   T1
      Any numeric or boolean type.
   rhs
      The right-hand side expression.
   T2
      Any numeric or boolean type.
   Ret
      A numeric or boolean type (varies with T1 and T2).

Return Value
   Returns the short circuit-and (conjunction) of the two operands.

Description
   This operator evaluates the left hand side expression.  If the result is 
   zero, then zero is immediately returned.  If the result is nonzero then 
   the right hand side is evaluated, and the logical result from that is 
   returned.
   (for conversion of a boolean to an integer, false or true boolean value 
   becomes 0 or -1 integer value) 

   The truth table below demonstrates all combinations of a short 
   circuit-and operation, the '-' denotes that the operand is not 
   evaluated.

      +---------+---------+------+
      |Lhs Value|Rhs Value|Result|
      |0        |-        |0     |
      |nonzero  |0        |0     |
      |nonzero  |nonzero  |-1    |
      +---------+---------+------+

   Short-circuiting is performed - only expressions needed to calculate the 
   result are evaluated.  The left hand side lhs is evaluated first, and 
   only if it evaluates to non-zero (true) is the right hand side rhs also 
   evaluated.  If the left hand side evaluation lhs returns zero (false), 
   it is known that at that point that the overall condition is false, so 
   the right hand side rhs is not evaluated (skipped).

   The return type is almost always an Integer, of the value 0 or -1, 
   denoting false and true respectively. Except if the left and right-hand 
   side types are both Boolean, then the return type is also Boolean.

   This operator cannot be overloaded for user-defined types.

Example
   '' Using the ANDALSO operator to guard against array access
   '' when the index is out of range

   Dim As Integer isprime(1 To 10) = { _
      _ ' 1  2  3  4  5  6  7  8  9  10
         0, 1, 1, 0, 1, 0, 1, 0, 0, 0 _
      }

   Dim As Integer n
   Input "Enter a number between 1 and 10: ", n

   '' isprime() array will only be accessed if n is in range
   If (n >= 1 And n <= 10) AndAlso isprime(n) Then
      Print "n is prime"
   Else
      Print "n is not prime, or out of range"
   End If

Differences from QB
   * This operator was not available in QB.

See also
   * OrElse
   * And
   * Operator Truth Tables



--------------------------------------------------------- KeyPgOpOrElse ----
Operator Orelse (Short Circuit Inclusive Disjunction)

Returns the short circuit-or (Inclusive Disjunction) of two numeric values

Syntax
   Declare Operator OrElse ( ByRef lhs As T1, ByRef rhs As T2 ) As Ret

Usage
   result = lhs OrElse rhs

Parameters
   lhs
      The left-hand side expression.
   T1
      Any numeric or boolean type.
   rhs
      The right-hand side expression.
   T2
      Any numeric or boolean type.
   Ret
      A numeric or boolean type (varies with T1 and T2).

Return Value
   Returns the short circuit-or (inclusive disjunction) of the two 
   operands.

Description
   This operator evaluates the left hand side expression.  If the result is 
   nonzero, then -1 (true) is immediately returned.  If the result is zero 
   then the right hand side is evaluated, and the logical result from that 
   is returned, returning -1 (true) for a nonzero value or 0 (false) for 
   zero.
   (for conversion of a boolean to an integer, false or true boolean value 
   becomes 0 or -1 integer value)

   The truth table below demonstrates all combinations of a short 
   circuit-or operation, the '-' denotes that the operand is not evaluated.

      +---------+---------+------+
      |Lhs Value|Rhs Value|Result|
      |0        |0        |0     |
      |0        |nonzero  |-1    |
      |nonzero  |-        |-1    |
      +---------+---------+------+

   Short-circuiting is performed - only expressions needed to calculate the 
   result are evaluated.  The left hand side lhs is evaluated first, and 
   only if it evaluates to zero (false) is the right hand side rhs also 
   evaluated. If the left hand side evaluation lhs returns non-zero (true), 
   it is known that at that point that the overall condition is true, so 
   the right hand side rhs is not evaluated (skipped).

   The return type is almost always an Integer, of the value 0 or -1, 
   denoting false and true respectively. Except if the left and right-hand 
   side types are both Boolean, then the return type is also Boolean.

   This operator cannot be overloaded for user-defined types.

Example
   ' Using the ORELSE operator on two numeric values
   Dim As Integer numeric_value1, numeric_value2
   numeric_value1 = 15
   numeric_value2 = 30

   'Result = -1
   Print numeric_value1 OrElse numeric_value2
   Sleep

Differences from QB
   * This operator was not available in QB.

See also
   * AndAlso
   * Or
   * Operator Truth Tables




============================================================================
    Indexing operators

----------------------------------------------------- KeyPgOpArrayIndex ----
Operator () (Array Index)

Returns a reference to an element in an array

Syntax
   Declare Operator () ( lhs() As T, ByRef rhs As Integer, ... ) ByRef As T

Usage
   result = lhs ( rhs [, ...] )

Parameters
   lhs
      An array.
   rhs
      An index of an element in the array.
   T
      Any data type.

Description
   This operator returns a reference to an element in an array. For 
   multidimensional arrays, multiple indexes must be specified (up to the 
   total number of dimensions of the array).

   For any dimension d in array a, any index less than LBound(a, d) or 
   greater than UBound(a, d) will result in a runtime error.

Example

   Dim array(0 To 4) As Integer = { 0, 1, 2, 3, 4 }

   For index As Integer = 0 To 4
      Print array(index);
   Next
   Print

   will produce the output:


    0 1 2 3 4

Differences from QB
   * None

See also
   * Operator [] (Pointer Index)



---------------------------------------------------- KeyPgOpStringIndex ----
Operator [] (String Index)

Returns a reference to a character in a string

Syntax
   Declare Operator [] ( ByRef lhs As String, ByRef rhs As Integer ) ByRef 
   As UByte
   Declare Operator [] ( ByRef lhs As ZString, ByRef rhs As Integer ) ByRef 
   As UByte
   Declare Operator [] ( ByRef lhs As WString, ByRef rhs As Integer ) ByRef 
   As T

Usage
   result = lhs [ rhs ]

Parameters
   lhs
      The string (a string reference, not a string returned as local copy).
   rhs
      A zero-based offset from the first character.
   T
      The wide-character type (varies per platform).

Description
   This operator returns a reference to a specific character in a string:
      * This operator must not be used in case of empty string because 
        reference is undefined (inducing runtime error).
      * Otherwise, the user must ensure that the index does not exceed the 
        range "[0, Len(lhs) - 1]". Outside this range, results are 
        undefined.

Example
   Dim a As String = "Hello, world!"
   Dim i As Integer

   For i = 0 To Len(a) - 1
      Print Chr(a[i]) & " ";
   Next i
   Print

Will print

   H e l l o ,   w o r l d ! 

Differences from QB
   * New to FreeBASIC

See also
   * String Operators



------------------------------------------------------- KeyPgOpPtrIndex ----
Operator [] (Pointer Index)

Returns a reference to memory offset from an address

Syntax
   Declare Operator [] ( ByRef lhs As T Pointer, ByRef rhs As Integer ) 
   ByRef As T

Usage
   result = lhs [ rhs ]

Parameters
   lhs
      The base address.
   rhs
      A signed offset from lhs.
   T
      Any data type.

Description
   This operator returns a reference to a value some distance in memory 
   from a base address. It is essentially shorthand for "*(lhs + rhs)" 
   because the reference can be thought of as a pointer having as value the 
   memory location "(lhs + rhs)", and which is implicitly dereferenced; 
   both do exactly the same thing.
   Like pointer arithmetic, any type of Pointer can be indexed except for 
   an Any Pointer. Also, like pointer arithmetic, it is up to the user to 
   make sure meaningful data is being accessed.

   When indexing a '2-dimensional' pointer (i.e. a T Ptr Ptr), the first 
   (leftmost) index is applied before the second: For example, Pt[I1][I2] = 
   *(Pt[I1] + I2) = *(*(Pt + I1) + I2)
   In general, when using an 'n-dimensional' pointer: Pt[I1][I2].....[In], 
   the index order (from left to right) corresponds to the dereferencing 
   order.

   This operator must not be used in case of null pointer because reference 
   is undefined (inducing runtime error).
   Otherwise, the user must ensure that the offset value (rhs) is in a 
   range that allows an access to valid memory. Outside this range, results 
   are undefined.

   This operator can be overloaded for user-defined types as a member 
   Operator using the appropriate syntax.

Example
   '' initialize a 5-element array
   Dim array(4) As Integer = { 0, 1, 2, 3, 4 }

   '' point to the first element
   Dim p As Integer Ptr = @array(0)

   '' use pointer indexing to output array elements
   For index As Integer = 0 To 4
      Print p[index];
   Next
   Print

   Will give the output,

    0 1 2 3 4

Differences from QB
   * New to FreeBASIC

See also
   * Pointer Arithmetic
   * Operator * (Value Of)
   * Operator [] (String Index)
   * Operator () (Array Index)
   * Operator + (Add)
   * Operator - (Subtract)
   * Pointer Operators




============================================================================
    String operators

--------------------------------------------------------- KeyPgOpConcat ----
Operator + (String Concatenation)

Concatenates two strings

Syntax
   Declare Operator + ( ByRef lhs As String, ByRef rhs As String ) As String
   Declare Operator + ( ByRef lhs As ZString, ByRef rhs As ZString ) As 
   ZString
   Declare Operator + ( ByRef lhs As WString, ByRef rhs As WString ) As 
   WString

Usage
   result = lhs + rhs

Parameters
   lhs
      The left-hand side string to concatenate.
   rhs
      The right-hand side string to concatenate.

Description
   This operator concatenates two strings.  Unlike 
   Operator & (String Concatenation With Conversion) both expressions must 
   be strings, and may not be converted (in fact, any attempt to 
   concatenate a string with a non-string or two non-strings will result in 
   a type mismatch error, with the exception of when operator overloading 
   is used in a UDT).

Example
   Dim As String a = "Hello, ", b = "World!"
   Dim As String c
   c = a + b
   Print c

Output:

   Hello, World!

Differences from QB
   * None

See also
   * Operator + (Add)
   * Operator & (String Concatenation With Conversion)
   * Str



-------------------------------------------------- KeyPgOpConcatConvert ----
Operator & (String Concatenation With Conversion)

Concatenates two strings, converting non-strings to strings as needed

Syntax
   Declare Operator & ( ByRef lhs As T, ByRef rhs As U ) As V

Usage
   result = lhs & rhs

Parameters
   lhs
      The left-hand side expression to concatenate.
   T
      Any standard data type or user-defined type that can be converted to 
      a standard data type.
   rhs
      The right-hand side expression to concatenate.
   U
      Any standard data type or user-defined type that can be converted to 
      a standard data type.
   V
      The resultant string type (varies with operands).

Description
   This operator concatenates two expressions. If either of the expressions 
   is not a string type, it is converted to String with Str.

   If either of the expressions is a WString, a WString is returned, 
   otherwise a String is returned.

   This operator can be overloaded to accept user-defined types.

   Note: This operator exists in C/C++ with a different meaning - there it 
   performs a bitwise And.

Example
   Dim As String A,C
   Dim As Single B
   A="The result is: "
   B=124.3
   C=A & B
   Print C
   Sleep

Output:

   The result Is: 124.3

Differences from QB
   * New to FreeBASIC

See also
   * Operator + (String Concatenation)
   * Str



--------------------------------------------------------- KeyPgOpStrptr ----
Operator Strptr (String Pointer)

Returns the address of a string's character data.

Syntax
   Declare Operator StrPtr ( ByRef lhs As String ) As ZString Ptr
   Declare Operator StrPtr ( ByRef lhs As WString ) As ZString Ptr

Usage
   result = StrPtr ( lhs )

Parameters
   lhs
      A string.

Return Value
   Returns a ZString Ptr to a string's character data (null value in case 
   of empty string).

Description
   This operator returns a ZString Ptr that points to the beginning of a 
   string's character data. Operator Strptr is the proper method for 
   acquiring the address of a string's character data.
   In case of empty String (only for variable length strings), Operator 
   Strptr returns a null pointer.

   Note that when passed a WString, Operator Strptr still returns a ZString 
   Ptr, which may not be the desired result.

   The related Operator Varptr (Variable Pointer) and 
   Operator @ (Address Of), when used with a String, return the address of 
   the internal string descriptor.
   When a variable length string is modified, the address of its descriptor 
   remains always the same, but the the string's character data address 
   (returned by Operator Strptr) may change (like any allocated memory that 
   must be reallocated).
   When a fixed length string is modified, the string's character data 
   address (returned by Operator Strptr) is unchanged.

   Note: For a variable length string, the operator returns a ZString Const 
   Ptr (because returning by reference the string's characters pointer set 
   in the string descriptor, this one is to be considered as read only). If 
   the keyword Var is used to declare/initialize a user pointer from 
   Operator Strptr, this user pointer is also defined as read only (it can 
   not be modified further).

Example
   '' This example uses Strptr to demonstrate using pointers with strings
   Dim myString As String
   Dim toMyStringDesc As Any Ptr
   Dim toMyString As ZString Ptr

   '' Note that using standard VARPTR notation will return a pointer to the
   '' descriptor, not the string data itself
   myString = "Improper method for Strings"
   toMyStringDesc = @myString
   Print myString
   Print Hex( toMyStringDesc )
   Print

   '' However, using Strptr returns the proper pointer
   myString = "Hello World Examples Are Silly"
   toMyString = StrPtr(myString)
   Print myString
   Print *toMyString
   Print

   '' And the pointer acts like pointers to other types
   myString = "MyString has now changed"
   Print myString
   Print *toMyString
   Print

Differences from QB
   * New to FreeBASIC, but does exactly the same thing as SAdd

See also
   * SAdd
   * VarPtr
   * ProcPtr
   * Pointers




============================================================================
    Preprocessor operators

---------------------------------------------------- KeyPgOpPpStringize ----
Operator # (Preprocessor Stringize)

Preprocessor operator to convert macro arguments to strings

Syntax
   #macro_argument

Description
   This operator converts the macro_argument into a string whose value is 
   the name of the argument. This substitution is made during the macro 
   expansion, previous to compilation.

   Note: because of this feature, care should be taken when using 
   file-handling statements in a macro.  Because of potential ambiguity 
   with file-handling statements that take a "#filenum" parameter, if 
   filenum is one of the macro parameters, it may be necessary to wrap the 
   filenum expression in parenthesis (e.g. "#(filenum)"), to separate it 
   from the # sign.  Otherwise, filenum will be stringized in the macro.

Example
   #define SEE(x) Print #x ;" = "; x
   Dim variable As Integer, another_one As Integer
   variable=1
   another_one=2
   SEE(variable)
   SEE(another_one)

Output:

   variable = 1
   another_one = 2

Differences from QB
   * New to FreeBASIC

See also
   * Preprocessor



------------------------------------------------------- KeyPgOpPpConcat ----
Operator ## (Preprocessor Concatenate)

Preprocessor operator to concatenate strings

Syntax
   text##text

Description
   This operator creates a new token by concatenating the texts at both 
   sides of it.  This text can be recognized by other macros and further 
   expanded.  One use, is to create a macro that expands to different macro 
   names, variable names, and function names depending on the arguments 
   received.

Example
   #define Concat(t,n) t##n

   Print concat (12,34)

   Dim Concat (hello,world) As Integer
   Concat (hello,world)=99
   Print helloworld

   Output:

   1234
   99

Differences from QB
   * New to FreeBASIC

See also
   * Preprocessor



------------------------------------------------------- KeyPgOpPpEscape ----
Operator ! (Escaped String Literal)

Explicitly indicates that a string literal should be processed for escape 
sequences.

Syntax
   !"text"

Parameters
   !
      The preprocessor escaped string operator
   "text"	
      The string literal containing escape characters

Description
   This operator explicitly indicates that the string literal following it 
   (wrapped in double quotes) should be processed for escape sequences.  
   This a preprocessor operator and can only be used with string literals 
   at compile time.

   The default behavior for string literals is that they not be processed 
   for escape sequences.  Option Escape can be used in the -lang fblite 
   dialect to override this default behaviour causing all strings to be 
   processed for escape sequences.

   Use the $ Operator (Non-Escaped String Literal) operator to explicitly 
   indicate that a string should not be processed for escape sequences.

Example
   Print "Some escape sequence examples:"
   Print !"1.\tsingle quote (\\\') : \'"
   Print !"2.\tdouble quote (\\\") : \""
   Print !"3.\tbackslash    (\\\\) : \\"
   Print !"4.\tascii char   (\\65): \65"

   '' OUTPUT:
   ''
   '' Some escape sequence examples:
   '' 1.	single quote (\') : '
   '' 2.	double quote (\") : "
   '' 3.	backslash    (\\) : \
   '' 4.	ascii char   (\65): A

Differences from QB
   * New to FreeBASIC

See also
   * Operator $ (Non-Escaped String Literal)
   * Option Escape
   * Preprocessor
   * Literals
   * Escape Sequences



----------------------------------------------------- KeyPgOpPpNoescape ----
Operator $ (Non-Escaped String Literal)

Explicitly indicates that a string literal should not be processed for 
escape sequences.

Syntax
   $"text"

Parameters
   $
      The preprocessor non-escaped operator
   "text"	
      The string literal

Description
   This operator explicitly indicates that the string literal following it 
   (wrapped in double quotes) should not be processed for escape sequences. 
   This a preprocessor operator and can only be used with string literals 
   at compile time.

   The default behavior for string literals is that they not be processed 
   for escape sequences.  However, Option Escape in the -lang fblite 
   dialect can be used to override this default behaviour causing all 
   strings to be processed for escape sequences.

   Use the ! Operator (Escaped String Literal) to explicitly indicate that 
   a string should be processed for escape sequences.

Example
   '' Compile with -lang fblite or qb

   #lang "fblite"

   Print "Default"
   Print "Backslash  : \\"
   Print !"Backslash !: \\"
   Print $"Backslash $: \\"
   Print

   Option Escape

   Print "Option Escape"
   Print "Backslash  : \\"
   Print !"Backslash !: \\"
   Print $"Backslash $: \\"
   Print

   '' OUTPUT:

   '' Default
   '' Backslash  : \\
   '' Backslash !: \
   '' Backslash $: \\

   '' Option Escape
   '' Backslash  : \
   '' Backslash !: \
   '' Backslash $: \\

Differences from QB
   * New to FreeBASIC

See also
   * Operator ! (Escaped String Literal)
   * Option Escape
   * Preprocessor
   * Literals
   * Escape Sequences




============================================================================
    Pointer operators

--------------------------------------------------------- KeyPgOpVarptr ----
Operator Varptr (Variable Pointer)

Returns the address of a variable or object

Syntax
   Declare Operator VarPtr ( ByRef lhs As T ) As T Ptr

Syntax
   result = VarPtr ( lhs )

Parameters
   lhs
      A variable or object.
   T
      Any data type.

Return Value
   Returns the address of a variable or object.

Description
   This operator returns the address of its operand.

   When the operand is of type String, the address of the internal string 
   descriptor is returned. Use Operator Strptr (String Pointer) to retrieve 
   the address of the string data.

   The operand cannot be an array, but may be an array element. For 
   example, "VarPtr(myarray(0))" returns the address of "myarray(0)".

   Operator @ (Address Of), when used with variables or objects, has 
   identical behavior.

Example
   Dim a As Integer, addr As Integer
   a = 10

   '' place the address of a in addr
   addr = CInt( VarPtr(a) )

   '' change all 4 bytes (size of INTEGER) of a
   Poke Integer, addr, -1000 
   Print a

   '' place the address of a in addr (same as above)
   addr = CInt( @a )

   '' print the least or most significant byte, depending on the CPU endianess
   Print Peek( addr ) 

Differences from QB
   * None

See also
   * Pointers
   * Peek
   * Poke



--------------------------------------------------------- KeyPgOpStrptr ----
Operator Strptr (String Pointer)

Returns the address of a string's character data.

Syntax
   Declare Operator StrPtr ( ByRef lhs As String ) As ZString Ptr
   Declare Operator StrPtr ( ByRef lhs As WString ) As ZString Ptr

Usage
   result = StrPtr ( lhs )

Parameters
   lhs
      A string.

Return Value
   Returns a ZString Ptr to a string's character data (null value in case 
   of empty string).

Description
   This operator returns a ZString Ptr that points to the beginning of a 
   string's character data. Operator Strptr is the proper method for 
   acquiring the address of a string's character data.
   In case of empty String (only for variable length strings), Operator 
   Strptr returns a null pointer.

   Note that when passed a WString, Operator Strptr still returns a ZString 
   Ptr, which may not be the desired result.

   The related Operator Varptr (Variable Pointer) and 
   Operator @ (Address Of), when used with a String, return the address of 
   the internal string descriptor.
   When a variable length string is modified, the address of its descriptor 
   remains always the same, but the the string's character data address 
   (returned by Operator Strptr) may change (like any allocated memory that 
   must be reallocated).
   When a fixed length string is modified, the string's character data 
   address (returned by Operator Strptr) is unchanged.

   Note: For a variable length string, the operator returns a ZString Const 
   Ptr (because returning by reference the string's characters pointer set 
   in the string descriptor, this one is to be considered as read only). If 
   the keyword Var is used to declare/initialize a user pointer from 
   Operator Strptr, this user pointer is also defined as read only (it can 
   not be modified further).

Example
   '' This example uses Strptr to demonstrate using pointers with strings
   Dim myString As String
   Dim toMyStringDesc As Any Ptr
   Dim toMyString As ZString Ptr

   '' Note that using standard VARPTR notation will return a pointer to the
   '' descriptor, not the string data itself
   myString = "Improper method for Strings"
   toMyStringDesc = @myString
   Print myString
   Print Hex( toMyStringDesc )
   Print

   '' However, using Strptr returns the proper pointer
   myString = "Hello World Examples Are Silly"
   toMyString = StrPtr(myString)
   Print myString
   Print *toMyString
   Print

   '' And the pointer acts like pointers to other types
   myString = "MyString has now changed"
   Print myString
   Print *toMyString
   Print

Differences from QB
   * New to FreeBASIC, but does exactly the same thing as SAdd

See also
   * SAdd
   * VarPtr
   * ProcPtr
   * Pointers



-------------------------------------------------------- KeyPgOpProcptr ----
Operator Procptr (Procedure Pointer)

Returns the address of a procedure

Syntax
   Declare Operator ProcPtr ( ByRef lhs As T ) As T Ptr

Usage
   result = ProcPtr ( lhs )

Parameters
   lhs
      A procedure.
   T
      The type of procedure.

Return Value
   Returns the address of the procedure.

Description
   This operator returns the address of a Sub or Function procedure.

   Operator @ (Address Of), when used with procedures, has identical 
   behavior.

Example
   ' This example uses ProcPtr to demonstrate function pointers
   Declare Function Subtract( x As Integer, y As Integer) As Integer
   Declare Function Add( x As Integer, y As Integer) As Integer
   Dim myFunction As Function( x As Integer, y As Integer) As Integer

   ' myFunction will now be assigned to Add
   myFunction = ProcPtr( Add )
   Print myFunction(2, 3)

   ' myFunction will now be assigned to Subtract.  Notice the different output.
   myFunction = ProcPtr( Subtract )
   Print myFunction(2, 3)

   Function Add( x As Integer, y As Integer) As Integer
      Return x + y
   End Function

   Function Subtract( x As Integer, y As Integer) As Integer
      Return x - y
   End Function

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Procptr.

Differences from QB
   * New to FreeBASIC

See also
   * Sub
   * VarPtr
   * StrPtr
   * Pointers



------------------------------------------------------------- KeyPgOpAt ----
Operator @ (Address Of)

Returns the address of a string literal, variable, object or procedure

Syntax
   Declare Operator @ ( ByRef rhs As T ) As T Pointer

Usage
   result = @ rhs

Parameters
   rhs
      The string literal, variable, object or procedure to retrieve the 
      address of.
   T
      Any standard, user-defined or procedure type.

Return Value
   Returns the address of the right-hand side (rhs) operand.

Description
   Operator @ (Address of) returns the memory address of its operand.

   When the operand is of type String, the address of the internal string 
   descriptor is returned. Use Operator Strptr (String pointer) to retrieve 
   the address of the string data.

   The operand cannot be an array, but may be an array element. For 
   example, "@myarray(0)" returns the address of "myarray(0)".

   This operator can be overloaded for user-defined types as a member 
   Operator using the appropriate syntax.

Example
   'This program demonstrates the use of the @ operator.

   Dim a As Integer
   Dim b As Integer

   Dim addr As Integer Ptr

   a = 5   'Here we place the values 5 and 10 into a and b, respectively.
   b = 10

   'Here, we print the value of the variables, then where in memory they are stored.
   Print "The value in A is ";a;" but the pointer to a is ";@a
   Print "The value in B is ";b;" but the pointer to b is ";@b

   'Now, we will take the integer ptr above, and use @ to place a value into it.
   'Note that the * will check the value in the ptr, just as @ checked the ptr 
   'for a normal variable.

   addr = @a

   Print "The pointer addr is now pointing at the memory address to a, value: ";*addr

   addr = @b

   Print "The pointer addr is now pointing at the memory address to b, value: ";*addr

   'This program demonstrates how the @ symbol can be used
   'to create pointers to subroutines.

   Declare Sub mySubroutine ()

   Dim say_Hello As Sub() 

   say_Hello = @mySubroutine   'We tell say_Hello to point to mySubroutine.
                        'The sub() datatype acts as a pointer here.

   say_Hello() 'Now we can run say_Hello just like mySubroutine.

   Sub mySubroutine
      Print "hi"
   End Sub

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * New to FreeBASIC

See also
   * VarPtr
   * ProcPtr
   * Operator * (Value Of)
   * Pointers



-------------------------------------------------------- KeyPgOpValueOf ----
Operator * (Value Of)

Dereferences a pointer

Syntax
   Declare Operator * ( ByRef rhs As T Pointer ) ByRef As T

Usage
   result = * rhs

Parameters
   rhs
      The address to dereference.
   T
      Any standard, user-defined or procedure type.

Return Value
   Returns a reference to the value stored at the address rhs.

Description
   Operator * (Value of) returns a reference to the value stored at an 
   address, and is often called the dereference operator. The operand is 
   not modified in any way.
   Any type of Pointer can be dereferenced except for an Any Pointer.

   As a reference, the result of this operator can be used on the left-hand 
   side of assignments.

   This operator must not be used in case of null pointer because reference 
   is undefined (inducing runtime error).
   Otherwise, the user must ensure that the pointer value induces access to 
   a valid memory. Otherwise, results are undefined.

   This operator can be overloaded for user-defined types.

Example
   'This program demonstrates the use of * to utilize the value a pointer points to.
   Dim a As Integer
   Dim pa As Integer Ptr

   pa=@a 'Here, we use the @ operator to point our integer ptr at 'a'.
   ' 'a' is, in this case, a standard integer variable.

   a=9     'Here we give 'a' a value of 9.

   Print "The value of 'a' is";*pa 'Here, we display the value of 'a' using a pointer. 

   *pa = 1 'Here we use our pointer to change the value of 'a'
   Print "The new value of 'a' is";a 'Here we display the new value of 'a'.

Output:

   The value of 'a' is 9
   The New value of 'a' is 1

Dialect Differences
   * In the -lang qb dialect, this operator cannot be overloaded.

Differences from QB
   * New to FreeBASIC

See also
   * Operator @ (Address Of)
   * Operator [] (Pointer Index)
   * Pointers




============================================================================
    Type or Class operators

--------------------------------------------------- KeyPgOpMemberAccess ----
Operator . (Member Access)

Returns a reference to a member from a reference to an object

Syntax
   Declare Operator . ( ByRef lhs As T ) ByRef As U

Usage
   result = lhs . rhs

Parameters
   lhs
      An object.
   T
      A user-defined type.
   rhs
      The name of a member to access.
   U
      The type that rhs refers to.

Return Value
   Returns a reference to the member specified by rhs.

Description
   Operator . (Member access) returns a reference to a member of an object.

   Operator . (Member access) can also be used to access members of an 
   implicit object inside a With..End With block.

   This operator cannot be overloaded.

Example

   Type T
      As Integer a, b
   End Type

   Dim x As T

   '' Access the member 'a' of x.
   x.a = 10

   '' Access the member 'b' of x.
   With x
      .b = 20
   End With

Dialect Differences
   * None

Differences from QB
   * None

See also
   * Operator -> (Pointer To Member Access)
   * Operator @ (Address Of)
   * Operator * (Value Of)
   * With..End With

   

   


------------------------------------------------ KeyPgOpPtrMemberAccess ----
Operator -> (Pointer To Member Access)

Returns a reference to a member from a pointer to an object

Syntax
   Declare Operator -> ( ByRef lhs As T Ptr ) ByRef As U

Usage
   result = lhs -> rhs

Parameters
   lhs
      The address of an object.
   T
      A user-defined type.
   rhs
      The name of a member to access.
   U
      The type that rhs refers to.

Return Value
   Returns a reference to the member specified by rhs.

Description
   Operator -> (Pointer to member access) returns a reference to a member 
   of an object through a pointer to that object. It has the effect of 
   dereferencing a pointer to an object, then using 
   Operator . (Member Access). For example, "p->member" is equivalent to "x
   .member", if x is an object of user-defined type and p is a pointer to 
   an object of the same type. "p->member" is equivalent to "(*p).member".

   This operator can be overloaded for user-defined types.

Example

   Type rect
      x As Integer
      y As Integer
   End Type

   Dim r As rect
   Dim rp As rect Pointer = @r

   rp->x = 4
   rp->y = 2

   Print "x = " & rp->x & ", y = " & rp->y
   Sleep

Dialect Differences
   * Not available in the -lang qb dialect.

Differences from QB
   * New to FreeBASIC

See also
   * Operator . (Member Access)
   * Operator @ (Address Of)
   * Operator * (Value Of)



------------------------------------------------------------- KeyPgOpIs ----
Operator Is (Run-Time Type Information)

Check if an object is compatible to a type derived from its compile-time 
type
(in the context of inheritance)

Syntax
   result = expression Is  typename

Parameters
   expression
      The expression to check, an object of a type that is directly or 
      indirectly derived from Object using Extends.
   typename
      The child type to check for. This type must be directly or indirectly 
      derived from the type of expression (the compile-time type of the 
      object).

Return Value
   Returns negative one (-1) if the expression is an object of real-type 
   typename or one of its base-types derived from the expression type, or 
   zero (0) if it's an object of an incompatible type.

Description
   The Is operator must be used in conjunction with inheritance in order to 
   check compatibility between objects and types from an inheritance 
   structure extending the built-in Object type.

   The Is operator is a binary operator that checks whether an object is 
   compatible to its derived types at run-time. Because Is relies on 
   Run-Time Type Information (RTTI), it can only be used with types that 
   are derived from the built-in Object type using Extends. The compiler 
   disallows using Is for checks that can be solved at compile-time.

   The Is operator is successful not only for the real-type (the "lowest"), 
   but also for its base-types, as long as they are still below the type of 
   expression (the compile-time type). In order to determine the real-type, 
   all possibilities from lowest to highest must be checked.

   Extending the built-in Object type allows to add an extra hidden vtable 
   pointer field at the top of the Type. The vtable is used to access 
   information for run-time type identification used by the Is operator.

   This operator cannot be overloaded.

Example
   Type Vehicle Extends Object
      As String Name
   End Type

   Type Car Extends Vehicle
   End Type

   Type Cabriolet Extends Car
   End Type

   Type Bike Extends Vehicle
   End Type

   Sub identify(ByVal p As Object Ptr)
      Print "Identifying:"

      '' Not a Vehicle object?
      If Not (*p Is Vehicle) Then
         Print , "unknown object"
         Return
      End If

      '' The cast is safe, because we know it's a Vehicle object
      Print , "name: " & CPtr(Vehicle Ptr, p)->Name

      If *p Is Car Then
         Print , "It's a car"
      End If

      If *p Is Cabriolet Then
         Print , "It's a cabriolet"
      End If

      If *p Is Bike Then
         Print , "It's a bike"
      End If
   End Sub

   Dim As Car ford
   ford.name = "Ford"
   identify(@ford)

   Dim As Cabriolet porsche
   porsche.name = "Porsche"
   identify(@porsche)

   Dim As Bike mountainbike
   mountainbike.name = "Mountain Bike"
   identify(@mountainbike)

   Dim As Vehicle v
   v.name = "some unknown vehicle"
   identify(@v)

   Dim As Object o
   identify(@o)

Differences from QB
   * New to FreeBASIC

See also
   * Extends
   * Extends Zstring
   * Extends Wstring
   * Object
   * Is (Select Case)
   * TypeOf
 



============================================================================
    Memory operators

------------------------------------------------------------ KeyPgOpNew ----
Operator New Expression

Operator to dynamically allocate memory and construct data of a specified 
type.

Usage
   result = New datatype
      or
   result = New datatype ( initializers, ... )
      or
   result = New datatype[ count ]

Parameters
   datatype
      Name of the data type to create.
   initializers
      Initial value(s) for the variable.
   count
      Exact number of elements to allocate.

Return Value
   A pointer of type datatype to the newly allocated data, or null pointer 
   if the memory allocation failed.

Description
   The New Expression operator dynamically allocates memory and constructs 
   a specified data type.

   For simple types, like integers, an initial value can be given. For 
   types without constructors, initial values can be specified for each 
   field (either with default initializer at data-field declaration, or 
   with initializer list as in New datatype (initializers, ..) if all type 
   data-fields are numeric primitives only and without any default 
   initializers). For types with at least one constructor, the initialize 
   list (if any) must match an existing constructor. If no initializers are 
   given, the default values for those types will be set.

   New[] Expression operator is the (one-dimensional) array-version of the 
   New Expression operator and allocates enough memory for the specified 
   number of objects. The default constructor for the type will be used to 
   set the initial values for each item.

   Objects created with New Expression operator must be freed with 
   Delete Statement operator. Object array created with New[] Expression 
   operator must be freed with Delete[] Statement operator, the 
   array-version of Delete Statement operator. You cannot mix and match the 
   different versions of the operators.

   Specifying an initial value of Any, as in New datatype (Any) will 
   allocate memory for the type, but not initialize the data.  This is only 
   valid on data types that do not have constructors (otherwise for data 
   types with constructors, syntax of simple memory allocation with pointer 
   conversion, like Cptr(datatype Ptr, Allocate(Sizeof(datatype))), can be 
   substituted to the invalid use of New...Any).

   Specifying an initial value of Any, as in New datatype[count] {Any} will 
   allocate memory for the array, but not initialize the data.  This is 
   only valid on data types that do not have constructors (otherwise for 
   data types with constructors, syntax of simple memory allocation with 
   pointer conversion, like Cptr(datatype Ptr, Allocate(count * 
   Sizeof(datatype))), can be substituted to the invalid use of New...Any).

   The total memory, in bytes, to be allocated with New datatype[count] 
   expression is calculated as sizeof(datatype) * count, plus 
   sizeof(uinteger) if there is an implicit or explicit Destructor.  The 
   total memory requested in bytes to be allocated must not overflow the 
   value that can be held by a UInteger.  The extra uinteger, if allocated, 
   stores the number of elements as part of the allocation, so that 
   Delete Statement can determine the count of destructors to call.

   If the memory allocation fails, a null pointer is returned and no 
   constructors are called.

   The dynamic memory allocation process part provided by the New 
   Expression operator can be overloaded for user-defined types as a member 
   operator New Overload. The following process part for data construction 
   can never be modified.

   Note: Using pointer = New datatype[count] may be unsafe if pointer was 
   declared with a type different from datatype (for sub-type polymorphism 
   purpose for example), because the pointer arithmetic fails to access the 
   elements if the pointer type size is different from the size of datatype 
   (when using Operator [] (Pointer Index) or adding an offset (element 
   number) to the pointer, or even when Delete[] Statement itself (the 
   array-version of Delete Statement) must destroy the elements).

Example
   Type Rational
      As Integer   numerator, denominator
   End Type

   Scope

      ' Create and initialize a "rational" and store its address.
      Dim p As Rational Ptr = New Rational(3, 4)
     
      ' test if null return pointer
      If (p = 0) Then
         Print "Error: unable to allocate memory, quitting."
         End -1
      End If

      Print p->numerator & "/" & p->denominator

      ' Destroy the rational and give its memory back to the system. 
      Delete p

   End Scope

   Scope

      ' Allocate memory for 100 integers and store the address of the first one.
      Dim p As Integer Ptr = New Integer[100]

      ' test if null return pointer
      If (p = 0) Then
         Print "Error: unable to allocate memory, quitting."
         End -1
      End If

      ' Assign some values to the integers in the array.
      For i As Integer = 0 To 99
         p[i] = i
      Next

      ' Free the entire integer array.
      Delete[] p

   End Scope

   Sleep

   '' Example of nested New [] to get a 2-dimentional object array (4*3)

   Type UDT
      Dim As Integer N
      Declare Constructor ()
      Declare Destructor ()
   End Type

   Constructor UDT ()
      Print "Constructor",
   End Constructor

   Destructor UDT ()
      Print "Destructor",
   End Destructor

   Dim As UDT Ptr Ptr p = New UDT Ptr [4]  '' New [] allocation for the first dimension:
                                 ''   no internal allocation of extra uinteger because
                                 ''   allocation of array of pointers (to UDT objects with destructor)
   For I As Integer = 0 To 3
      p[I] = New UDT [5]                  '' New [] allocations for the last dimension:
                                 ''   internal allocation of an extra uinteger for each New [],
                                 ''   because allocation of an array of UDT objects with destructor
      Print
   Next I

   For I As Integer = 0 To 3
      For J As Integer = 0 To 4
         p[I][J].N = I * 10 + J  '' assignment of each object array element
      Next J
   Next I

   Print
   For I As Integer = 0 To 3
      For J As Integer = 0 To 4
         Print p[I][J].N,        '' display of each object array element
      Next J
      Print
   Next I
   Print

   For I As Integer = 0 To 3
      Delete [] p[I]  '' Delete [] deallocations for the last dimension
      Print
   Next I
   Delete [] p         '' Delete [] deallocation for the first dimension)
   Print

   Sleep

      Output example:

   Constructor   Constructor   Constructor   Constructor   Constructor
   Constructor   Constructor   Constructor   Constructor   Constructor
   Constructor   Constructor   Constructor   Constructor   Constructor
   Constructor   Constructor   Constructor   Constructor   Constructor

    0             1             2             3             4
    10            11            12            13            14
    20            21            22            23            24
    30            31            32            33            34

   Destructor    Destructor    Destructor    Destructor    Destructor
   Destructor    Destructor    Destructor    Destructor    Destructor
   Destructor    Destructor    Destructor    Destructor    Destructor
   Destructor    Destructor    Destructor    Destructor    Destructor

Dialect Differences
   * Only available in the -lang fb dialect.

Differences from QB
   * New to FreeBASIC

See also
   * Delete Statement
   * Placement New
   * New Overload



---------------------------------------------------- KeyPgOpNewOverload ----
Operator New Overload

Member operator to overload dynamic memory allocation process part provided 
by Operator New Expression when applying to a UDT (User Defined Type).

Syntax
   Declare Operator New ( size As UInteger ) As Any Ptr
   Declare Operator new[] ( size As UInteger ) As Any Ptr

Parameters
   size 
      Number of bytes to allocate.

Return Value
   A pointer of type Any Ptr to the start of the newly allocated memory.

Description
   The member operator New Overload overloads the dynamic memory allocation 
   process part provided by the New Expression operator when applying to a 
   UDT (User Defined Type). So the user can define its own dynamic memory 
   allocation process part.
   But after that, the UDT instance construction process part provided by 
   the New Expression operator is not modified.

   New[] Overload operator is the (one-dimensional) array-version of the 
   New Overload operator and overloads the dynamic memory allocation 
   process provided by the  New[] Expression operator when applying to a 
   UDT (User Defined Type).

   Memory allocated with New Overload operator must be freed by also 
   defining a Delete Overload operator. Memory allocated with New[] 
   Overload operator must be freed by also defining a Delete[] Overload 
   operator, the array-version of Delete Overload operator. You cannot mix 
   and match the different versions of the operators.

   Member operators New Overload, and New[] Overload are always static, 
   even if not explicitly declared (Static keyword is unnecessary but 
   allowed). Thus, they do not have an implicit This instance argument 
   passed to them (because instance not yet been constructed).

Example
   Dynamic allocation displayer for UDT, by using the member operators 
   "New([]) Overload" and "Delete([]) Overload" (very simple example, only 
   for syntax usage):
      * displaying of memory allocations: addresses, sizes,
      * displaying of memory deallocations: addresses.

   Type UDTdisplayer
     '' user UDT fields:
      Dim As Byte b(1 To 1024*1024)
     '' display fields:
      Public:
        Declare Operator New (ByVal size As UInteger) As Any Ptr
        Declare Operator Delete (ByVal buf As Any Ptr)
        Declare Operator New[] (ByVal size As UInteger) As Any Ptr
        Declare Operator Delete[] (ByVal buf As Any Ptr)
      Private:
        Declare Static Function allocation (ByRef N As String, ByVal size As UInteger) As Any Ptr
        Declare Static Sub deallocation (ByRef D As String, ByVal p As Any Ptr)
   End Type

   Operator UDTdisplayer.New (ByVal size As UInteger) As Any Ptr
     Return UDTdisplayer.allocation("New", size)
   End Operator

   Operator UDTdisplayer.Delete (ByVal buf As Any Ptr)
     UDTdisplayer.deallocation("Delete", buf)
   End Operator

   Operator UDTdisplayer.New[] (ByVal size As UInteger) As Any Ptr
     Return UDTdisplayer.allocation("New[]", size)
   End Operator

   Operator UDTdisplayer.Delete[] (ByVal buf As Any Ptr)
     UDTdisplayer.deallocation("Delete[]", buf)
   End Operator

   Function UDTdisplayer.allocation (ByRef N As String, ByVal size As UInteger) As Any Ptr
     Dim As Any Ptr p = Allocate(size)
     Print "memory allocation for " & size & " bytes from '" & N & "' at address: " & p
     Return p
   End Function

   Sub UDTdisplayer.deallocation (ByRef D As String, ByVal p As Any Ptr)
     Print "memory deallocation from '" & D & "' at address " & p
     Deallocate p
   End Sub

   Randomize
   Dim As UDTdisplayer Ptr pu1 = New UDTdisplayer
   Dim As UDTdisplayer Ptr pu2 = New UDTdisplayer[3]
   Delete pu1
   Delete[] pu2

   Sleep

      Output example:

   memory allocation For 1048576 bytes from 'New' at address: 32677920
   memory allocation For 3145728 bytes from 'New[]' at address: 33775648
   memory deallocation from 'Delete' at address 32677920
   memory deallocation from 'Delete[]' at address 33775648

   Aligned memory allocator:
      * by using the member operators "New Overload" and "Delete 
        Overload", any created User object is aligned to a multiple of 
        "ALIGN" bytes (256 bytes in this example),
      * the real pointer of the allocated memory is saved just above the 
        User pointer, in the padding block.

   Const ALIGN = 256

   Type UDT
     Dim As Byte a(0 To 10 * 1024 * 1024 - 1) '' 10 megabyte fixed array
     Declare Operator New (ByVal size As UInteger) As Any Ptr
     Declare Operator Delete (ByVal buffer As Any Ptr)
     Declare Constructor ()
     Declare Destructor ()
   End Type

   Operator UDT.New (ByVal size As UInteger) As Any Ptr
     Print "  Overloaded New operator, with parameter size = &h" & Hex(size)
     Dim pOrig As Any Ptr = CAllocate(ALIGN-1 + SizeOf(UDT Ptr) + size)
     Dim pMin As Any Ptr = pOrig + SizeOf(UDT Ptr) 
     Dim p As Any Ptr = pMin + ALIGN-1 - (CUInt(pMin + ALIGN-1) Mod ALIGN)
     Cast(Any Ptr Ptr, p)[-1] = pOrig
     Operator = p
     Print "  real pointer = &h" & Hex(pOrig), "return pointer = &h" & Hex(p)
   End Operator

   Operator UDT.Delete (ByVal buffer As Any Ptr)
     Print "  Overloaded Delete operator, with parameter buffer = &h" & Hex(buffer)
     Dim pOrig As Any Ptr = Cast(Any Ptr Ptr, buffer)[-1]
     Deallocate(pOrig)
     Print "  real pointer = &h" & Hex(pOrig)
   End Operator

   Constructor UDT ()
     Print "  Constructor, @This = &h" & Hex(@This)
   End Constructor

   Destructor UDT ()
     Print "  Destructor, @This = &h" & Hex(@This)
   End Destructor

   Print "'Dim As UDT Ptr p = New UDT'"
   Dim As UDT Ptr p = New UDT

   Print "  p = &h" & Hex(p)

   Print "'Delete p'"
   Delete p

   Sleep

      Output example:

   'Dim As UDT Ptr p = New UDT'
     Overloaded New Operator, With parameter size = &hA00000
     real Pointer = &h420020   Return Pointer = &h420100
     Constructor, @This = &h420100
     p = &h420100
   'Delete p'
     Destructor, @This = &h420100
     Overloaded Delete Operator, With parameter buffer = &h420100
     real Pointer = &h420020

   Dynamic allocation manager for UDT, by using the member operators "New[] 
   Overload" and "Delete[] Overload":
      * monitoring of memory allocations/deallocations: addresses, sizes 
        and total memory used,
      * detection of abnormal deallocation requests,
      * detection of a failed allocation (Allocate() returning null 
        pointer),
      * detection of total allocated memory size exceeding a threshold,
      * the last two detection cases induces an automatic memory freeing 
        before forcing the program to end.
   The principle is to manage a dynamic list of successful allocations, but 
   not yet freed, containing the allocated addresses with their requested 
   sizes:

   Type UDTmanager
     '' user UDT fields:
      Dim As Byte b(1 To 1024*1024)
     '' manager fields:
      Public:
        Declare Operator New[] (ByVal size As UInteger) As Any Ptr
        Declare Operator Delete[] (ByVal buf As Any Ptr)
        Static As UInteger maxmemory
      Private:
        Static As Any Ptr address()
        Static As UInteger bytes()
        Static upbound As UInteger
        Declare Static Function printLine (ByRef text As String, ByVal index As UInteger, ByVal sign As Integer) As UInteger
        Declare Static Sub endProgram ()
   End Type

   Dim As UInteger UDTmanager.maxmemory = 3 * 1024 * 1024 * 1024
   ReDim UDTmanager.address(0)
   ReDim UDTmanager.bytes(0)
   Dim UDTmanager.upbound As UInteger = 0

   Function UDTmanager.printLine (ByRef text As String, ByVal index As UInteger, ByVal sign As Integer) As UInteger
     Dim As UInteger total = 0
     For I As UInteger = 1 To UDTmanager.upbound
      If I <> index OrElse Sgn(sign) > 0 Then
        total += UDTmanager.bytes(I)
      End If
     Next I
     Print text, "&h" & Hex(UDTmanager.address(index), SizeOf(Any Ptr) * 2),
     If sign <> 0 Then
      Print Using " +####.## MB"; Sgn(sign) * Cast(Integer, UDTmanager.bytes(index) / 1024) / 1024;
     Else
      Print Using "( ####.## MB)"; UDTmanager.bytes(index) / 1024 / 1024;
     End If
     Print,
     Print Using "###.## GB"; total / 1024 / 1024 / 1024
     Return total
   End Function

   Sub UDTmanager.endProgram ()
     Do While UDTmanager.upbound > 0
      Deallocate UDTmanager.address(UDTmanager.upbound)
      UDTmanager.printLine("memory deallocation forced", UDTmanager.upbound, -1)
      UDTmanager.upbound -= 1
      ReDim Preserve UDTmanager.address(UDTmanager.upbound)
      ReDim Preserve UDTmanager.bytes(UDTmanager.upbound)
     Loop
     Print "end program forced"
     Print
     Sleep
     End
   End Sub

   Operator UDTmanager.New[] (ByVal size As UInteger) As Any Ptr
     Dim As Any Ptr p = Allocate(size)
     If p > 0 Then
      UDTmanager.upbound += 1
      ReDim Preserve UDTmanager.address(UDTmanager.upbound)
      ReDim Preserve UDTmanager.bytes(UDTmanager.upbound)
      UDTmanager.address(UDTmanager.upbound) = p
      UDTmanager.bytes(UDTmanager.upbound) = size
      If UDTmanager.printLine("memory allocation", UDTmanager.upbound, +1) > UDTmanager.maxmemory Then
        UDTmanager.address(0) = p
        UDTmanager.bytes(0) = size
        Print
        UDTmanager.printLine("memory allocation exceeded", 0, 0)
        UDTmanager.endProgram()
      End If
      Return p
     Else
      UDTmanager.address(0) = p
      UDTmanager.bytes(0) = size
      Print
      UDTmanager.printLine("memory allocation failed", 0, 0)
      UDTmanager.endProgram()
     End If
   End Operator

   Operator UDTmanager.Delete[] (ByVal buf As Any Ptr)
     Dim As UInteger found = 0
     For I As UInteger = 1 To UDTmanager.upbound
      If UDTmanager.address(I) = buf Then
        Deallocate buf
        UDTmanager.printLine("memory deallocation", I, -1)
        For J As UInteger = I + 1 To UDTmanager.upbound
         UDTmanager.address(J - 1) = UDTmanager.address(J)
         UDTmanager.bytes(J - 1) = UDTmanager.bytes(J)
        Next J
        UDTmanager.upbound -= 1
        ReDim Preserve UDTmanager.address(UDTmanager.upbound)
        ReDim Preserve UDTmanager.bytes(UDTmanager.upbound)
        found = 1
        Exit For
      End If
     Next I
     If found = 0 Then
      UDTmanager.address(0) = buf
      UDTmanager.bytes(0) = 0
      UDTmanager.printLine("deallocation not matching", 0, 0)
     End If
   End Operator

   Print "Message",, "Address" & Space(SizeOf(Any Ptr)), "Size", "Total"
   Print
   Randomize
   Dim As UDTmanager Ptr pu1 = New UDTmanager[CUInt(Rnd() * 256 + 1)]
   Dim As UDTmanager Ptr pu2 = New UDTmanager[CUInt(Rnd() * 256 + 1)]
   Dim As UDTmanager Ptr pu3 = Cast(UDTmanager Ptr, 1)
   Delete[] pu2
   Delete[] pu3
   Delete[] pu2
   Delete[] pu1
   Do
     Dim As UDTmanager Ptr pu = New UDTmanager[CUInt(Rnd() * 512 + 1)]
   Loop

      Output for fbc 32-bit (maximum dynamic data < 2 GB).
      Here, program is stopped because of memory allocation failed:

   Message                     Address       Size          Total

   memory allocation           &h020E0020       +99.00 MB    0.10 GB
   memory allocation           &h083F3020        +3.00 MB    0.10 GB
   memory deallocation         &h083F3020        -3.00 MB    0.10 GB
   deallocation Not matching   &h00000001    (    0.00 MB)   0.10 GB
   deallocation Not matching   &h083F3020    (    0.00 MB)   0.10 GB
   memory deallocation         &h020E0020       -99.00 MB    0.00 GB
   memory allocation           &h020ED020      +103.00 MB    0.10 GB
   memory allocation           &h087F2020      +106.00 MB    0.20 GB
   memory allocation           &h0F20D020      +230.00 MB    0.43 GB
   memory allocation           &h1D812020      +137.00 MB    0.56 GB
   memory allocation           &h2612C020      +377.00 MB    0.93 GB
   memory allocation           &h3DA30020      +275.00 MB    1.20 GB
   memory allocation           &h4ED40020      +220.00 MB    1.41 GB
   memory allocation           &h5C958020      +229.00 MB    1.64 GB

   memory allocation failed    &h00000000    (  142.00 MB)   1.64 GB
   memory deallocation forced  &h5C958020      -229.00 MB    1.41 GB
   memory deallocation forced  &h4ED40020      -220.00 MB    1.20 GB
   memory deallocation forced  &h3DA30020      -275.00 MB    0.93 GB
   memory deallocation forced  &h2612C020      -377.00 MB    0.56 GB
   memory deallocation forced  &h1D812020      -137.00 MB    0.43 GB
   memory deallocation forced  &h0F20D020      -230.00 MB    0.20 GB
   memory deallocation forced  &h087F2020      -106.00 MB    0.10 GB
   memory deallocation forced  &h020ED020      -103.00 MB    0.00 GB
   End program forced

      Output for fbc 64-bit (maximum dynamic data < virtual memory).
      Here, program is stopped because of total allocated memory size > 3 
      GB (adjustable threshold):

   Message                     Address                     Size          Total

   memory allocation           &h0000000001EA5040            +105.00 MB    0.10 GB
   memory allocation           &h00000000087BC040             +93.00 MB    0.19 GB
   memory deallocation         &h00000000087BC040             -93.00 MB    0.10 GB
   deallocation Not matching   &h0000000000000001          (    0.00 MB)   0.10 GB
   deallocation Not matching   &h00000000087BC040          (    0.00 MB)   0.10 GB
   memory deallocation         &h0000000001EA5040            -105.00 MB    0.00 GB
   memory allocation           &h0000000001EA1040            +155.00 MB    0.15 GB
   memory allocation           &h000000000B9BF040            +165.00 MB    0.31 GB
   memory allocation           &h0000000015ED8040            +382.00 MB    0.69 GB
   memory allocation           &h000000002DCE7040            +458.00 MB    1.13 GB
   memory allocation           &h000000004A6FB040            +255.00 MB    1.38 GB
   memory allocation           &h000000005A607040             +96.00 MB    1.48 GB
   memory allocation           &h000000006061B040            +426.00 MB    1.89 GB
   memory allocation           &h000000007FFF9040            +221.00 MB    2.11 GB
   memory allocation           &h000000008DD03040            +119.00 MB    2.22 GB
   memory allocation           &h0000000095413040            +147.00 MB    2.37 GB
   memory allocation           &h000000009E727040            +217.00 MB    2.58 GB
   memory allocation           &h00000000AC03C040            +334.00 MB    2.91 GB
   memory allocation           &h00000000C0E4B040            +280.00 MB    3.18 GB

   memory allocation exceeded  &h00000000C0E4B040          (  280.00 MB)   3.18 GB
   memory deallocation forced  &h00000000C0E4B040            -280.00 MB    2.91 GB
   memory deallocation forced  &h00000000AC03C040            -334.00 MB    2.58 GB
   memory deallocation forced  &h000000009E727040            -217.00 MB    2.37 GB
   memory deallocation forced  &h0000000095413040            -147.00 MB    2.22 GB
   memory deallocation forced  &h000000008DD03040            -119.00 MB    2.11 GB
   memory deallocation forced  &h000000007FFF9040            -221.00 MB    1.89 GB
   memory deallocation forced  &h000000006061B040            -426.00 MB    1.48 GB
   memory deallocation forced  &h000000005A607040             -96.00 MB    1.38 GB
   memory deallocation forced  &h000000004A6FB040            -255.00 MB    1.13 GB
   memory deallocation forced  &h000000002DCE7040            -458.00 MB    0.69 GB
   memory deallocation forced  &h0000000015ED8040            -382.00 MB    0.31 GB
   memory deallocation forced  &h000000000B9BF040            -165.00 MB    0.15 GB
   memory deallocation forced  &h0000000001EA1040            -155.00 MB    0.00 GB
   End program forced

Dialect Differences
   * Only available in the -lang fb dialect.

Differences from QB
   * New to FreeBASIC

See also
   * New Expression
   * Delete Overload
   * Allocate



--------------------------------------------------- KeyPgOpPlacementNew ----
Operator Placement New

Operator to construct an object at a specified memory address.

Syntax
   result = New(address) datatype
      or
   result = New(address) datatype ( initializers, ... )
      or
   result = New(address) datatype[ count ]

Parameters
   address 
      the location in memory to construct. the parenthesis are not 
      optional.
   initializers
      Initial value(s) for the variable.
   datatype
      name of the data type to construct.
   count
      Number of elements to construct.

Return Value
   A pointer of type datatype to the newly constructed data.

Description
   The Placement New operator constructs a specified data type at the 
   specified memory location. 

   For simple types, like integers, an initial value can be given. For 
   types without Constructors, initial values can be specified for each 
   field (either with default initializer at data-field declaration, or 
   with initializer list as in New datatype (initializers, ..) if all type 
   data-fields are numeric primitives only and without any default 
   initializers). For types with at least one constructor, the initialize 
   list (if any) must match an existing constructor. If no initializers are 
   given, the default values for those types will be set.

   Memory is not allocated when using the Placement New operator. Instead, 
   the memory at the specified address is used (the provided memory size 
   must be large enough to contain all the placement).
   It is incorrect to call Delete Statement on the address. The proper way 
   is to only call the destructor if one exists (implicitly or explicitly), 
   with syntax as for a member method by using member access operator.
   See examples below for proper Placement New operator usage.

   Placement New[] operator is the (one-dimensional) array-version of the 
   Placement New operator and constructs the specified number of objects 
   from the specified memory location. The default constructor for the type 
   will be used to set the initial values for each item.

   Specifying an initial value of Any, as in New(address)datatype (Any) or 
   New(address)datatype[count] {Any} will not initialize the data.  This is 
   only valid on data types that do not have constructors (otherwise for 
   data types with constructors, syntax of simple pointer conversion, like 
   Cptr(datatype Ptr, address), can be substituted to the invalid use of 
   New...Any).

   Because it does not provide any dynamic memory allocation process, the 
   Placement New operator (unlike the New Expression operator) does not 
   allow any overloading by a member operator for user-defined types.

   Note: Using pointer = New(address)datatype[count] may be unsafe if 
   pointer was declared with a type different from datatype (for sub-type 
   polymorphism purpose for example), because the pointer arithmetic fails 
   to access the elements if the pointer type size is different from the 
   size of datatype (when using Operator [] (Pointer Index) or adding an 
   offset (element number) to the pointer).

Example
   '' "placement new" example

   Type Rational
      As Integer    numerator, denominator
      Declare Constructor ( ByVal n As Integer, ByVal d As Integer )
      As String ratio = "/"
   End Type

   Constructor Rational ( ByVal n As Integer, ByVal d As Integer )
      This.numerator = n
      This.denominator = d
   End Constructor

   Scope
      
      '' allocate some memory to construct as a Rational
      Dim As Any Ptr ap = CAllocate(Len(Rational))
      
      '' make the placement new call
      Dim As Rational Ptr r = New (ap) Rational( 3, 4 )
      
      '' you can see, the addresses are the same, just having different types in the compiler
      Print ap, r
      
      '' confirm all is okay
      Print r->numerator & r->ratio & r->denominator
      
      '' delete must not be used with placement new
      '' destroying must be done explicitly if a destructor exists (implicitly or explicitly)
      ''   (in this example, the var-string member induces an implicit destructor)
      r->Destructor( )
      
      '' we explicitly allocated, so we explicitly deallocate
      Deallocate( ap )
      
   End Scope

Dialect Differences
   * Only available in the -lang fb dialect.

Differences from QB
   * New to FreeBASIC

See also
   * Destructor
   * New Expression



--------------------------------------------------------- KeyPgOpDelete ----
Operator Delete Statement

Operator to destroy data and free memory allocated with the 
Operator New Expression

Usage
   Delete buf
      or
   Delete[] buf

Parameters
   buf 
      A pointer to memory that has been allocated by New Expression 
      operator or New[] Expression operator, the array-version of 
      New Expression operator (a typed pointer must be provided in 
      accordance to the data type to delete).

Description
   The Delete Statement operator is used to destroy and free the memory of 
   an object created with New Expression operator. When deleting a TYPE, 
   its destructor will be called. Delete Statement operator should only be 
   used with addresses returned from New Expression operator.

   The array version of Delete Statement operator, Delete[] Statement 
   operator, is used to destroy an array of objects previously created with 
   New[] Expression operator, the array-version of New Expression operator. 
   Destructors will be called here as well.

   Delete Statement operator must be used with addresses returned from 
   New Expression operator, and Delete[] Statement operator with New[] 
   Expression operator, the array-version of New Expression operator. You 
   cannot mix and match the different versions of the operators.

   After the memory is deleted, the buf pointer will be pointing at invalid 
   memory. Calling Delete Expression twice on the same pointer value leads 
   to undefined behavior. It may be a good idea to set the buf pointer to 
   null (0), in order to guard against later code using it accidentally, 
   since null pointer dereferences are easier to find and debug.

   Calling Delete Statement operator on a null pointer induces no action.

   The memory deallocation process part provided by the Delete Statement 
   operator can be overloaded for user-defined types as a member operator 
   Delete Overload. The previous process part for data destruction can 
   never be modified.

   Note: Any operator Delete[] Statement (or the only overload operator 
   Delete Statement) is not compatible with sub-type polymorphism, even 
   using Override Virtual Destructor that may in addition induce crashing.
   Instead of having to call such an operator Delete([]) Statement on 
   derived-type pointer, the safest way is to simply call (on base-type 
   pointer) an overridden user Virtual member procedure that will 
   automatically launch the operator Delete([]) Statement at derived-type 
   level.

Example
   Type Rational
      As Integer numerator, denominator
   End Type

   ' Create and initialize a Rational, and store its address.
   Dim p As Rational Ptr = New Rational(3, 4)

   Print p->numerator & "/" & p->denominator

   ' Destroy the rational and give its memory back to the system. 
   Delete p

   ' Set the pointer to null to guard against future accesses
   p = 0

   ' Allocate memory for 100 integers, store the address of the first one.
   Dim p As Integer Ptr = New Integer[100]

   ' Assign some values to the integers in the array.
   For i As Integer = 0 To 99
      p[i] = i
   Next

   ' Free the entire integer array.
   Delete[] p

   ' Set the pointer to null to guard against future accesses
   p = 0

Dialect Differences
   * Only available in the -lang fb dialect.

Differences from QB
   * New to FreeBASIC

See also
   * New Expression
   * Delete Overload
   * Deallocate



------------------------------------------------- KeyPgOpDeleteOverload ----
Operator Delete Overload

Member operator to overload memory deallocation process part provided by 
Operator Delete Statement when applying to a UDT (User Defined Type).

Syntax
   Declare Operator Delete ( buf  As Any Ptr )
   Declare Operator delete[] ( buf  As Any Ptr )

Parameters
   buf 
      A pointer to memory that has been allocated by New Overload operator 
      or New[] Overload operator, the array-version of New Overload 
      operator.

Description
   The member operator Delete Overload overloads the memory deallocation 
   process part provided by the Delete Statement operator when applying to 
   a UDT (User Defined Type). So the user can define its own memory 
   deallocation process part.
   But before that, the UDT instance destruction process part provided by 
   the Delete Statement operator is not modified.

   Delete[] Overload operator is the array-version of Delete Overload 
   operator and overloads the memory deallocation process provided by the 
   Delete[] Statement operator when applying to a UDT (User Defined Type).

   Memory freed with Delete Overload operator must have be allocated by 
   also defining a New Overload operator. Memory freed with Delete[] 
   Overload operator must have been allocated by also defining a New[] 
   Overload operator, the array-version of New Overload operator. You 
   cannot mix and match the different versions of the operators.

   Member operators Delete Overload, and Delete[] Overload are always 
   static, even if not explicitly declared (Static keyword is unnecessary 
   but allowed). Thus, they do not have an implicit This instance argument 
   passed to them (because instance already been destroyed).

Example
   See the New Overload operator examples.

Dialect Differences
   * Only available in the -lang fb dialect.

Differences from QB
   * New to FreeBASIC

See also
   * Delete Statement
   * New Overload
   * Deallocate




============================================================================
    Iterating operators

------------------------------------------------------------ KeyPgOpFor ----
Operator For (Iteration)

Declares or defines operators used by a For...Next loop with user defined 
type variables

Syntax
   { Type | Class | Union } typename
      Declare Operator For ()
      Declare Operator For ( [ ByRef | ByVal ] stp As typename )
      ...
   End { Type | Class | Union }

Usage
   For iterator [ As typename ] = start_value To end_value [ Step 
   step_value ]
      [ ...statements... ]
   Next

Parameters
   typename
      name of the Type, Class, or Union
   stp, step_value
      a typename object used as an incremental value
   iterator
      a typename object used as an iterator
   end_value
      a typename object used as a loop-terminating value
   start_value
      a typename object used to copy construct or assign to the iterator 
      initially

Description
   Operator For, Operator Next and Operator Step can be overloaded in 
   user-defined type definitions to allow objects of that type to be used 
   as iterators and step values in For...Next loops.
   As all non-static member procedures, they have passed a hidden This 
   parameter that allows to access by reference to the iterator object in 
   the code body of the 3 operators.

   Operator For is called immediately after copy constructing or assigning 
   to the iterator object, and allows the object to perform any additional 
   initialization needed in preparation for the loop.

   The first version of Operator For is used if no step value is given in 
   the For...Next statement. If a step value is given, the second version 
   is used and is passed the step value because eventual additional 
   initialization may use it.

Example
   See the Operator Step examples.

Dialect Differences
   * Only available in the -lang fb dialect.

See also
   * Operator Next
   * Operator Step
   * For...Next

   


----------------------------------------------------------- KeyPgOpStep ----
Operator Step (Iteration)

Increments the iterator of a For...Next loop

Syntax
   { Type | Class | Union } typename
      Declare Operator Step ()
      Declare Operator Step ( [ ByRef | ByVal ] stp As typename )
      ...
   End { Type | Class | Union }

Usage
   For iterator [ As typename ] = start_value To end_value [ Step 
   step_value ]
      [ ...statements... ]
   Next

Parameters
   typename
      name of the Type, Class, or Union
   stp, step_value
      a typename object used as an incremental value
   iterator
      a typename object used as an iterator
   end_value
      a typename object used as a loop-terminating value
   start_value
      a typename object used to copy construct or assign to the iterator 
      initially

Description
   Operator For, Operator Next and Operator Step can be overloaded in 
   user-defined type definitions to allow objects of that type to be used 
   as iterators and step values in For...Next loops.
   As all non-static member procedures, they have passed a hidden This 
   parameter that allows to access by reference to the iterator object in 
   the code body of the 3 operators.

   Operator Step is called to increment the iterator object immediately 
   after all statements in the For...Next body are executed, if any.

   The first version of Operator Step is used if no step value is given in 
   the For...Next statement. If a step value is given, the second version 
   is used and is passed the step value to increment the iterator object.

Example
   '' Example Type
   Type T
     '' value is set by the constructor
     value As Double
     Declare Constructor( ByVal x As Double = 0 )

     Declare Operator For( ByRef stp As T )
     Declare Operator Step( ByRef stp As T )
     Declare Operator Next( ByRef cond As T, ByRef stp As T ) As Integer
   End Type

   Constructor T ( ByVal x As Double )
     Print "T iterator constructed with value " & x
     value = x
   End Constructor

   Operator T.for( ByRef stp As T )
   End Operator

   Operator T.step( ByRef stp As T )
     Print " incremented by " & stp.value & " in step."
     value += stp.value
   End Operator

   Operator T.next( ByRef cond As T, ByRef stp As T ) As Integer
     '' iterator's moving from a high value to a low value (step >= 0)
     If( stp.value < 0 ) Then
      Return( value >= cond.value )
     Else
     '' iterator's moving from a low value to a high value (step < 0)
      Return( value <= cond.value )
     End If
   End Operator

   '' Example Usage. It looks like we are working with numbers, but the iterators
   '' have overloaded constructors. The 10, 1, and -1 are all of type T.
   For i As T = 10 To 1 Step -1
     Print i.value;
   Next i

A more practical example demonstrating file iteration based on 
cha0s' file iteration class.
   '' a class which iterates through files
   Type FileIter
      As String pathName, fileName
      Declare Constructor( ByRef pathName As String )

      Declare Operator For()
      Declare Operator Step()
      Declare Operator Next( ByRef endCond As FileIter) As Integer
   End Type

   Constructor FileIter( ByRef pathName As String )   
      this.pathName = pathName
   End Constructor

   Operator FileIter.for( )   
      fileName = Dir(pathName & "/*.*")   
   End Operator

   Operator FileIter.step( )   
      fileName = Dir("")
   End Operator

   Operator FileIter.next( ByRef endCond As FileIter ) As Integer
      Return(fileName <> endCond.pathName)   
      '' the c'tor sets the path name and so we check against that
   End Operator

   '' example code
   '' change it to any directory
   For i As FileIter = "./" To ""
      Print i.fileName
   Next

Another example working with strings:
   Type CharIterator
      '' used to build a step var
      Declare Constructor( ByVal r As ZString Ptr )
      
      '' implicit step versions
      Declare Operator For ( )
      Declare Operator Step( )
      Declare Operator Next( ByRef end_cond As CharIterator ) As Integer
      
      '' explicit step versions
      Declare Operator For ( ByRef step_var As CharIterator )
      Declare Operator Step( ByRef step_var As CharIterator )
      Declare Operator Next( ByRef end_cond As CharIterator, ByRef step_var As CharIterator ) As Integer
      
      '' give the current "value"    
      Declare Operator Cast( ) As String
      
      Private:   
         '' data
         value As String
         
         '' This member isn't necessary - we could use
         '' the step variable on each iteration - 
         '' but we choose this method, since we have
         '' to compare strings otherwise. See below.
         is_up As Integer
   End Type

   Constructor CharIterator( ByVal r As ZString Ptr )
      value = *r
   End Constructor

   Operator CharIterator.cast( ) As String
      Operator = value
   End Operator

   '' implicit step versions
   '' 
   '' In this example, we interpret implicit step
   '' to always mean 'up'
   Operator CharIterator.for( )
      Print "implicit step"
   End Operator

   Operator CharIterator.step( )
      value[0] += 1
   End Operator 

   Operator CharIterator.next( ByRef end_cond As CharIterator ) As Integer
      Return this.value <= end_cond.value
   End Operator

   '' explicit step versions
   '' 
   '' In this example, we calculate the direction
   '' at FOR, but since the step var is passed to
   '' each operator, we have the choice to also calculate
   '' it "on-the-fly". For strings such as this, repeated comparison
   '' may penalize, but if you're working with simpler types,
   '' then you may prefer to avoid the overhead of 
   '' an 'is_up' variable.
   Operator CharIterator.for( ByRef step_var As CharIterator )
      Print "explicit step"
      is_up = (step_var.value = "up")
   End Operator

   Operator CharIterator.step( ByRef step_var As CharIterator )
      If( is_up ) Then
         value[0] += 1
      Else
         value[0] -= 1
      End If
   End Operator 

   Operator CharIterator.next( ByRef end_cond As CharIterator, ByRef step_var As CharIterator ) As Integer
      If( this.is_up ) Then
         Return this.value <= end_cond.value
      Else
         Return this.value >= end_cond.value
      End If
   End Operator

   For i As CharIterator = "a" To "z"
      Print i; " ";
   Next
   Print "done"

   For i As CharIterator = "a" To "z" Step "up"
      Print i; " ";
   Next
   Print "done"

   For i As CharIterator = "z" To "a" Step "down"
      Print i; " ";
   Next
   Print "done"

   For i As CharIterator = "z" To "a" Step "up"
      Print i; " ";
   Next
   Print "done"

Iterating with fractions:
   Type fraction
      '' Used to build a step var
      Declare Constructor( ByVal n As Integer, ByVal d As Integer )

      '' Implicit step versions
      Declare Operator For ( )
      Declare Operator Step( )
      Declare Operator Next( ByRef end_cond As fraction ) As Integer

      '' Explicit step versions
      Declare Operator For ( ByRef step_var As fraction )
      Declare Operator Step( ByRef step_var As fraction )
      Declare Operator Next( ByRef end_cond As fraction, ByRef step_var As fraction ) As Integer

      '' Give the current "value"    
      Declare Operator Cast( ) As Double
      Declare Operator Cast( ) As String

      Private:
         As Integer num, den
   End Type

   Constructor fraction( ByVal n As Integer, ByVal d As Integer )
      this.num = n : this.den = d
   End Constructor

   Operator fraction.cast( ) As Double
      Operator = num / den
   End Operator

   Operator fraction.cast( ) As String
      Operator = num & "/" & den
   End Operator

   '' Some fraction functions
   Function gcd( ByVal n As Integer, ByVal m As Integer ) As Integer
      Dim As Integer t
         While m <> 0
            t = m
            m = n Mod m
            n = t
         Wend
      Return n
   End Function

   Function lcd( ByVal n As Integer, ByVal m As Integer ) As Integer
      Return (n * m) / gcd( n, m )
   End Function

   ''
   '' Implicit step versions
   '' 
   '' In this example, we interpret implicit step
   '' to mean 1
   ''
   Operator fraction.for( )
      Print "implicit step"
   End Operator

   Operator fraction.step( )
      Var lowest = lcd( this.den, 1 )

      Var mult_factor = this.den / lowest
      Dim As fraction step_temp = fraction( 1, 1 )
      
      this.num *= mult_factor
      this.den *= mult_factor
      
      step_temp.num *= lowest
      step_temp.den *= lowest
      
      this.num += step_temp.num
   End Operator 

   Operator fraction.next( ByRef end_cond As fraction ) As Integer
      Return This <= end_cond
   End Operator

   ''
   '' Explicit step versions
   '' 
   Operator fraction.for( ByRef step_var As fraction )
      Print "explicit step"
   End Operator

   Operator fraction.step( ByRef step_var As fraction )
      Var lowest = lcd( this.den, step_var.den )
      Var mult_factor = this.den / lowest
      Dim As fraction step_temp = step_var

      this.num *= mult_factor
      this.den *= mult_factor

      mult_factor = step_temp.den / lowest

      step_temp.num *= mult_factor
      step_temp.den *= mult_factor

      this.num += step_temp.num
   End Operator 

   Operator fraction.next( ByRef end_cond As fraction, ByRef step_var As fraction ) As Integer
      If(( step_var.num < 0 ) Or ( step_var.den < 0 ) ) Then
         Return This >= end_cond
      Else
         Return This <= end_cond
      End If
   End Operator

   For i As fraction = fraction(1,1) To fraction(4,1)
      Print i; " ";
   Next
   Print "done"

   For i As fraction = fraction(1,4) To fraction(1,1) Step fraction(1,4)
      Print i; " ";
   Next
   Print "done"

   For i As fraction = fraction(4,4) To fraction(1,4) Step fraction(-1,4)
      Print i; " ";
   Next
   Print "done"

   For i As fraction = fraction(4,4) To fraction(1,4)
      Print i; " ";
   Next
   Print "done"

Dialect Differences
   * Only available in the -lang fb dialect.

See also
   * Operator For
   * Operator Next
   * For...Next



----------------------------------------------------------- KeyPgOpNext ----
Operator Next (Iteration)

Determines if a For...Next loop should be terminated

Syntax
   { Type | Class | Union } typename
      Declare Operator Next ( [ ByRef | ByVal ] cond As typename ) As 
      Integer
      Declare Operator Next ( [ ByRef | ByVal ] cond As typename, [ ByRef | 
      ByVal ] stp As typename ) As Integer
      ...
   End { Type | Class | Union }

Usage
   For iterator [ As typename ] = start_value To end_value [ Step 
   step_value ]
      [ ...statements... ]
   Next

Parameters
   typename
      name of the Type, Class, or Union
   cond, end_value
      a typename object used as a loop-terminating value
   stp, step_value
      a typename object used as an incremental value
   iterator
      a typename object used as an iterator
   start_value
      a typename object used to copy construct or assign to the iterator 
      initially

Description
   Operator For, Operator Next and Operator Step can be overloaded in 
   user-defined type definitions to allow objects of that type to be used 
   as iterators and step values in For...Next loops.
   As all non-static member procedures, they have passed a hidden This 
   parameter that allows to access by reference to the iterator object in 
   the code body of the 3 operators.

   Operator Next is called every time the iterator object needs to be 
   checked against the end value. This happens immediately after the call 
   to its Operator For, and immediately after any calls to its Operator Step
   . Operator Next should return zero (0) if the loop should be terminated, 
   or non-zero if the loop should continue iterating. The first time 
   Operator Next is called, no statements in the For...Next body, if any, 
   have been executed yet.

   The first version of Operator Next is used if no step value is given in 
   the For...Next statement. If a step value is given, the second version 
   is used and is passed the step value because testing for iterating end 
   may depend on it.

Example
   See the Operator Step examples.

Dialect Differences
   * Only available in the -lang fb dialect.

See also
   * Operator For
   * Operator Step
   * For...Next



---------------------------------------------------------- OpPrecedence ----
Operator Precedence

   When several operations occur in a single expression, each operation is 
   evaluated and resolved in a predetermined order. This is called the 
   order of operation or operator precedence. 

   If an operator in an expression has a higher precedence, it is evaluated 
   before an operator of lower precedence. 

   If operators have equal precedence, they then are evaluated in the order 
   in of their associativity.  The associativity may be Left-to-Right or 
   Right-to-Left order.

   As a rule, binary operators (such as +, ^) and unary postfix operators 
   (such as (), ->) are evaluated Left-to-Right, and unary prefix operators 
   (such as Not, @) are evaluated Right-to-Left.

   Operators that have an associativity of "N/A" indicate that there is no 
   expression in which the operator can be used where its order of 
   operation would need to be checked, either by precedence or by 
   associativity.  Function-like operators such as Cast are always the 
   first to be evaluated due to the parentheses required in their syntax.  
   And assignment operators are always the last to be evaluated.

   Parentheses can be used to override operator precedence. Operations 
   within parentheses are performed before other operations. Within the 
   parentheses normal operator precedence is used.

   The following table lists operator precedence from highest to lowest.  
   Breaks in the table mark the groups of operators having equal 
   precedence.

Highest Precedence

      +--------+-----------------------------------+-------------+
      |Operator|Description                        |Associativity|
      |        |                                   |             |
      |CAST    |Type Conversion                    |N/A          |
      |PROCPTR |Procedure pointer                  |N/A          |
      |STRPTR  |String pointer                     |N/A          |
      |VARPTR  |Variable pointer                   |N/A          |
      |        |                                   |             |
      |[]      |String index                       |Left-to-Right|
      |[]      |Pointer index                      |Left-to-Right|
      |()      |Array index                        |Left-to-Right|
      |()      |Function Call                      |Left-to-Right|
      |.       |Member access                      |Left-to-Right|
      |->      |Pointer to member access           |Left-to-Right|
      |        |                                   |             |
      |@       |Address of                         |Right-to-Left|
      |*       |Value of                           |Right-to-Left|
      |New     |Allocate Memory                    |Right-to-Left|
      |Delete  |Deallocate Memory                  |Right-to-Left|
      |        |                                   |             |
      |^       |Exponentiate                       |Left-to-Right|
      |        |                                   |             |
      |-       |Negate                             |Right-to-Left|
      |        |                                   |             |
      |*       |Multiply                           |Left-to-Right|
      |/       |Divide                             |Left-to-Right|
      |        |                                   |             |
      |\       |Integer divide                     |Left-to-Right|
      |        |                                   |             |
      |MOD     |Modulus                            |Left-to-Right|
      |        |                                   |             |
      |SHL     |Shift left                         |Left-to-Right|
      |SHR     |Shift right                        |Left-to-Right|
      |        |                                   |             |
      |+       |Add                                |Left-to-Right|
      |-       |Subtract                           |Left-to-Right|
      |        |                                   |             |
      |&       |String concatenation               |Left-to-Right|
      |        |                                   |             |
      |Is      |Run-time type information check    |N/A          |
      |        |                                   |             |
      |=       |Equal                              |Left-to-Right|
      |<>      |Not equal                          |Left-to-Right|
      |<       |Less than                          |Left-to-Right|
      |<=      |Less than or equal                 |Left-to-Right|
      |>=      |Greater than or equal              |Left-to-Right|
      |>       |Greater than                       |Left-to-Right|
      |        |                                   |             |
      |NOT     |Complement                         |Right-to-Left|
      |        |                                   |             |
      |AND     |Conjunction                        |Left-to-Right|
      |        |                                   |             |
      |OR      |Inclusive Disjunction              |Left-to-Right|
      |        |                                   |             |
      |EQV     |Equivalence                        |Left-to-Right|
      |IMP     |Implication                        |Left-to-Right|
      |XOR     |Exclusive Disjunction              |Left-to-Right|
      |        |                                   |             |
      |ANDALSO |Short Circuit Conjunction          |Left-to-Right|
      |ORELSE  |Short Circuit Inclusive Disjunction|Left-to-Right|
      |        |                                   |             |
      |=[>]    |Assignment                         |N/A          |
      |&=      |Concatenate and Assign             |N/A          |
      |+=      |Add and Assign                     |N/A          |
      |-=      |Subtract and Assign                |N/A          |
      |*=      |Multiply and Assign                |N/A          |
      |/=      |Divide and Assign                  |N/A          |
      |\=      |Integer Divide and Assign          |N/A          |
      |^=      |Exponentiate and Assign            |N/A          |
      |MOD=    |Modulus and Assign                 |N/A          |
      |AND=    |Conjunction and Assign             |N/A          |
      |EQV=    |Equivalence and Assign             |N/A          |
      |IMP=    |Implication and Assign             |N/A          |
      |OR=     |Inclusive Disjunction and Assign   |N/A          |
      |XOR=    |Exclusive Disjunction and Assign   |N/A          |
      |SHL=    |Shift Left and Assign              |N/A          |
      |SHR=    |Shift Right and Assign             |N/A          |
      |LET     |Assignment                         |N/A          |
      |        |                                   |             |
      |LET()   |Assignment                         |N/A          |
      +--------+-----------------------------------+-------------+

In some cases, the order of precedence can cause confusing or 
counter-intuitive results.  Here are some examples:
   '' trying to raise a negated number to a power
   -2 ^ 2
   Desired result: (-2) ^ 2 = 4
   Actual result:   -(2 ^ 2) = -4

   '' trying to test a bit in a number
   n And 1  <>  0
   Desired result: (n And 1) <> 0
   Actual result:   n And (1 <> 0)

   '' trying to shift a number by n+1 bits
   a Shl n+1
   Desired result: a Shl (n + 1)
   Actual result: (a Shl n) + 1

For expressions where the operator precedence may be ambiguous, it is 
recommended to wrap parts of the expression in parentheses, in order both 
to minimise the possibility of error and to aid comprehension for people 
reading the code.

See also
   * Operators



-------------------------------------------------------------- TblTruth ----
Bitwise Operators Truth Tables

Computed values for the bitwise logical operators.

Binary operators
   Operators that take two operands.
Unary operator
   Operator that take a single operand.

   These logical operators return a value based on the value of their 
   operand(s). For the binary operators, each bit in the left-hand side 
   value is applied logically to the corresponding bit in the right-hand 
   side value. The result of this operation is returned. For the unary 
   operator, (Operator Not), the logic is applied to its right-hand side 
   operand only.

Binary operators

   Operator And (Conjunction)
      Bits in the result are set if and only if both of the corresponding 
      bits in the left and right-hand side operands are set.

         +------+-+-+-+-+
         |Lhs   |0|0|1|1|
         |Rhs   |0|1|0|1|
         |Result|0|0|0|1|
         +------+-+-+-+-+

   Operator Eqv (Equivalence)
      Bits in the result are set if and only if both of the corresponding 
      bits in the left and right-hand side operands are both either set or 
      unset.

         +------+-+-+-+-+
         |Lhs   |0|0|1|1|
         |Rhs   |0|1|0|1|
         |Result|1|0|0|1|
         +------+-+-+-+-+

   Operator Imp (Implication)
      Bits in the result are set if and only if the corresponding bit in 
      the left-hand side operand implies the bit in the right-hand side 
      operand.

         +------+-+-+-+-+
         |Lhs   |0|0|1|1|
         |Rhs   |0|1|0|1|
         |Result|1|1|0|1|
         +------+-+-+-+-+

   Operator Or (Inclusive Disjunction)
      Bits in the result are set if either of the corresponding bits in the 
      left and right-hand side operands are set.

         +------+-+-+-+-+
         |Lhs   |0|0|1|1|
         |Rhs   |0|1|0|1|
         |Result|0|1|1|1|
         +------+-+-+-+-+

   Operator Xor (Exclusive Disjunction)
      Bits in the result are set if and only if one of the corresponding 
      bits in the left and right-hand side operands is set.

         +------+-+-+-+-+
         |Lhs   |0|0|1|1|
         |Rhs   |0|1|0|1|
         |Result|0|1|1|0|
         +------+-+-+-+-+

Unary operators

   Operator Not (Complement)
      Bits in the result are set if the corresponding bits in the 
      right-hand side operand are unset, and unset if they are set.

         +------+-+-+
         |Rhs   |0|1|
         |Result|1|0|
         +------+-+-+




============================================================================
    Statements

------------------------------------------------------ CatPgControlFlow ----
Control Flow Statements

Statements that direct the flow of program execution.

Transferring Statements
   Statements that transfer control to another part of a program.
Branching Statements
   Statements that execute one of a number of code branches.
Looping Statements
   Statements that execute code repeatedly.

Transferring Statements
   Goto
      Transfers execution to another point in code defined by a text label.
   GoSub
      Temporarily transfers execution to another point in code, defined by 
      a text label.
   On Goto
      Transfers execution to one of a number of points in code defined by 
      text labels, based on the value of an expression.
   On Gosub
      Temporarily transfers execution to one of a number of points in code 
      defined by text labels, based on the value of an expression.
   Return
      Returns from a call using GoSub or from a procedure returning a 
      value.
   Exit Sub, Exit Function, Exit Operator,
   Exit Constructor, Exit Destructor and Exit Property
      Prematurely leaves a procedure code block.

Branching Statements
   If..End If
      Executes a block of statements if a condition is met.
   ..Else If..
      Executes a block of code if a condition is met and all previous 
      conditions weren't met.
   ..Else..
      Executes a block of code if all previous conditions weren't met.
   Select..End Select
      Executes one of a number of statement blocks using a set of 
      conditions.
   ..Case..
      Executes a block of code if a condition is met.
   ..Case Else..
      Executes a block of code if all previous conditions weren't met.

   Intra-branch control
      Exit Select
         Prematurely breaks out of a Select..End Select statement.
Looping Statements
   While..Wend
      Executes a block of statements while a condition is met.
   For..Next
      Executes a block of statements while an iterator is less than or 
      greater than an expression.
   Do..Loop
      Executes a block of statements while or until a condition is met.

   Intra-loop control
      Continue While, Continue For and Continue Do
         Prematurely re-enters a loop.
      Exit While, Exit For and Exit Do
         Prematurely breaks out of a loop.



------------------------------------------------------- CatPgProcedures ----
Procedures

Keywords that work with procedures.

Description
   These keywords control the declaration and definition of both 
   module-level procedures and member procedures, how they are called, how 
   arguments are passed and how their names are seen externally to other 
   modules. Procedures can also be declared to be executed automatically 
   before any module-level code is executed.

Declaration
   Keywords that declare and define procedures.
Linkage
   Keywords that specify how procedure names are seen by external modules.
Calling conventions
   Keywords that specify how arguments are used when calling procedures.
Parameter passing conventions
   Keywords that specify how arguments are passed to procedures.
Variadic Procedures
   Macros that allow for an arbitrary number of arguments to be passed to a 
   procedure.
Automatic execution
   Keywords that specify automatic execution of procedures.
Miscellaneous
   Miscellaneous keywords.

Declaration
   Declare
      Declares a module-level or member procedure.
   Sub
      Specifies a procedure that does not return an argument.
   Function
      Specifies a procedure that returns an argument.
   Overload
      Specifies that the procedure name can be used in other procedure 
      declarations.
   Static
      Specifies static storage for all variables and objects in the 
      procedure body.
   Const (Member)
      Specifies a const member procedure in user-defined type definitions.
   Static (Member)
      Specifies a static member procedure in user-defined type definitions.

Linkage
   Public
      Specifies external linkage for a procedure.
   Private
      Specifies internal linkage for a procedure.
   Alias
      Specifies an alternate external name for a procedure.
   Export
      Specifies a procedure is to be exported from a shared library.
   Lib
      Specifies automatic loading of a library.

Calling conventions
   stdcall
      Specifies the standard calling convention for BASIC languages, 
      including FreeBASIC.
   cdecl
      Specifies the standard calling convention in the C and C++ languages.
   pascal
      Specifies the standard calling convention in the Fortran, Pascal and 
      Microsoft QuickBASIC/QBasic languages.
Parameter passing conventions
   ByRef
      Specifies passing an argument by reference.
   ByVal
      Specifies passing an argument by value.
   Any
      Disables type-checking on arguments.

Variadic Procedures
   ... (Ellipsis)
      Indicates a variadic procedure in a declaration.
    Cva_Arg
      Macro to obtain the next argument from a variadic argument list 
      object
    Cva_Copy
      Macro to copy a variadic argument list object variable
    Cva_End
      Macro to end using a variadic argument list object variable
    Cva_List
      Variadic argument list object type 
    Cva_Start
      Macro to initialize variadic argument list object variable
   va_first
      Macro to obtain the argument list in a variadic procedure.
   va_arg
      Macro to obtain the current argument in a variadic procedure.
   va_next
      Macro to move to the next argument in a variadic procedure.

Automatic execution
   Constructor (Module)
      Indicates a procedure is to be executed before module-level code.
   Destructor (Module)
      Indicates a procedure is to be executed after module-level code.

Miscellaneous
   Byref (Function Results)
      Specifies that a function returns by reference rather than by value.
   Call
      Invokes a procedure.
   Naked
      Specifies that a function body is not to be given any prolog/epilog 
      code



----------------------------------------------------- CatPgModularizing ----
Modularizing

Keywords helpful when writing modular programs.

   * Common
   * DyLibFree
   * DyLibLoad
   * DyLibSymbol
   * Export
   * Extern

   * Extern...End Extern
   * Import
   * Namespace
   * Private
   * Public
   * Using (Namespaces)




============================================================================
    Other

------------------------------------------------------- CatPgPreProcess ----
Preprocessor

Commands that control the preprocessor.

Description
   Preprocessor commands are sent to the compiler to control what gets 
   compiled and how. They can be used to choose to compile one block of 
   code rather than another for cross-platform compatibility, include 
   headers or other source files, define small inline functions called 
   macros, or alter how the compiler handles variables.

Conditional Compilation
   Commands that allow for branches in compilation based on conditions.
Text Replacement
   Commands that create text-replacement macros.
File Directives
   Commands that indicate to the compiler how other files relate to the 
   source file.
Control Directives
   Commands that set compile options, control compilation, and report 
   compile time information.
Metacommands
   Commands that are kept for backward compatibility.

Conditional Compilation
   #if
      Compiles the following code block based on a condition.
   #ifdef
      Compiles the following code block if a symbol is defined.
   #ifndef
      Compiles the following code block if a symbol is not defined.
   #elseif
      Compiles the following code block if a condition is true and the 
      previous conditions was false.
   #else
      Compiles the following code block if previous conditions were false.
   #endif
      Signifies the end of a code block.
   defined
      Returns "-1" if a symbol is defined, otherwise "0".

Text Replacement
   #define
      Creates a single-line text-replacement macro.
   #macro and #endmacro
      Creates a multi-line text-replacement macro.
   #undef
      Undefines a symbol.
   # Preprocessor Stringize
      Converts text into a string literal.
   ## Preprocessor Concatenate
      Concatenates two pieces of text.
   ! Escaped String Literal
      Indicates string literal immediately following must be processed for 
      escape sequences.
   $ Non-Escaped String Literal
      Indicates string literal immediately following must not be processed 
      for escape sequences.
File Directives
   #include
      Inserts text from a file.
   #inclib
      Includes a library in the linking processes.
   #libpath
      Includes a path to search for libraries in the linking process.

Control Directives
   #pragma
      Sets compiling options.
   #lang
      Sets dialect from source.
   #print
      Outputs a messages to standard output while compiling.
   #error
      Outputs a messages to standard output and stops compilation.
   #assert
      Stops compilation with an error message if a given condition is 
      false.
   #line
      Sets the current line number and file name.

Metacommands
   '$Include
      Alternate form of the #include directive.
   '$Dynamic
      Alternate form of the Option Dynamic statement.
   '$Static
      Alternate form of the Option Static statement.
   '$Lang
      Alternate form of the #lang directive.

See also
   * Intrinsic Defines



---------------------------------------------------- TblEscapeSequences ----
Escape Sequences

Escape sequences can be used in string literals by using the operator ! .

Usage
result = !"text"

Description
   The accepted escape sequences in text  are:
      +-----------+---------------------+
      |\a         |beep                 |
      |\b         |backspace            |
      |\f         |formfeed             |
      |\l or \n   |newline              |
      |\r         |carriage return      |
      |\t         |tab                  |
      |\unnnn     |unicode char in hex  |
      |\v         |vertical tab         |
      |\nnn       |ascii char in decimal|
      |\&hnn      |ascii char in hex    |
      |\&onnn     |ascii char in octal  |
      |\&bnnnnnnnn|ascii char in binary |
      |\\         |backslash            |
      |\"         |double quote         |
      |\'         |single quote         |
      +-----------+---------------------+
 

Note: The zero-character (\000 = \&h00 = \&o000 = \&b00000000) is the null 
terminator. Only characters before the first null terminator can be seen 
when the literal is used as a String. To get a zero character in a string 
use Chr(0) instead.

See also
   * Operator ! (Escaped String)
   * Operator $ (Non-Escaped String)
   * Option Escape
   * String
   * Chr
   * Literals



------------------------------------------------- CatPgCompilerSwitches ----
Compiler Switches

Statements that affect how code is compiled.

Description
   These statements affect how the compiler declares variables, arrays and 
   procedures, parses string literals, passes procedure parameters and 
   more.

Metacommands
   * '$Dynamic
   * '$Include
   * '$Static
   * '$Lang

Compiler Options
   * Option Base
   * Option ByVal
   * Option Dynamic
   * Option Escape
   * Option Explicit
   * Option Gosub
   * Option Nogosub
   * Option NoKeyword
   * Option Private
   * Option Static
Set Default Datatypes
   * DefByte
   * DefDbl
   * DefInt
   * DefLng
   * DefLongInt
   * DefShort
   * DefSng
   * DefStr
   * DefUByte
   * DefUInt
   * Defulongint
   * DefUShort

Dialect Differences
   * DefLongInt and Defulongint available only in the -lang fblite 
     dialect.
   * OPTION statements are available only in the -lang fblite and -lang qb 
     dialects only.

See also
   * Preprocessor



-------------------------------------------------------- CatPgDddefines ----
Intrinsic Defines

Preprocessor symbols defined by the compiler.

Description
   Intrinsic defines are set by the compiler and may be used as any other 
   defined symbol.  Intrinsic defines often convey information about the 
   state of the compiler, either in general or at a specific point in the 
   compilation process.  Most intrinsic defines are associated with a 
   value.

Platform Information
   Defines that provide information on the system.
Version Information
   Defines that provide information on the fbc compiler version being used.
Command-line switches
   Defines that provide information with the command-line switches used 
   with fbc.
Environment Information
   Defines that provide information about the operating system environment.
Context-specific Information
   Defines that provide context information about the compilation process.
Constants
   Built-in constants.

Platform Information
   __FB_WIN32__
      Defined if compiling for Windows.
   __FB_LINUX__
      Defined if compiling for Linux.
   __FB_DOS__
      Defined if compiling for DOS.
   __FB_CYGWIN__
      Defined if compiling for Cygwin.
   __FB_FREEBSD__
      Defined if compiling for FreeBSD.
   __FB_NETBSD__
      Defined if compiling for NetBSD.
   __FB_OPENBSD__
      Defined if compiling for OpenBSD.
   __FB_DARWIN__
      Defined if compiling for Darwin.
   __FB_XBOX__
      Defined if compiling for Xbox.
   __FB_BIGENDIAN__
      Defined if compiling on a system using big-endian byte-order.
   __FB_PCOS__
      Defined if compiling for a common PC OS (e.g. DOS, Windows, OS/2).
   __FB_UNIX__
      Defined if compiling for a Unix-like OS.
   __FB_64BIT__
      Defined if compiling for a 64bit target.
   __FB_ARM__
      Defined if compiling for the ARM architecture.

Version Information
   __FB_VERSION__
      Defined as a string literal of the compiler version.
   __FB_VER_MAJOR__
      Defined as an integral literal of the compiler major version number.
   __FB_VER_MINOR__
      Defined as an integral literal of the compiler minor version number.
   __FB_VER_PATCH__
      Defined as an integral literal of the compiler patch number.
   __FB_MIN_VERSION__
      Macro to check for a minimum compiler version.
   __FB_BUILD_DATE__
      Defined as a string literal of the compiler build date.
   __FB_SIGNATURE__ 
      Defined as a string literal of the compiler signature.

Command-line switches
   __FB_ASM__
      Defined to either "intel" or "att" depending on -asm.
   __FB_BACKEND__
      Defined to either "gas" or "gcc" depending on -gen.
   __FB_GCC__
      True (-1) if -gen gcc is used, false (0) otherwise.
   __FB_GUI__
      True (-1) if the "-s gui" switch was used, false (0) otherwise.
   __FB_MAIN__
      Defined if compiling a module with an entry point.
   __FB_DEBUG__
      True (-1) if the "-g" switch was used, false (0) otherwise.
   __FB_ERR__
      Zero (0) if neither the "-e", "-ex" or "-exx" switches were used.
   __FB_FPMODE__
      Defined as "fast" if compiling for fast SSE math, "precise" 
      otherwise.
   __FB_FPU__
      Defined as "sse" if compiling for SSE floating point unit, or "x87" 
      for normal x87 floating-point unit.
   __FB_LANG__
      Defined to a string literal of the "-lang" dialect used.
   __FB_MT__
      True (-1) if the "-mt" switch was used, false (0) otherwise.
   __FB_OUT_DLL__
      True (-1) in a module being compiled and linked into a shared 
      library, false (0) otherwise.
   __FB_OUT_EXE__
      True (-1) in a module being compiled and linked into an executable, 
      false (0) otherwise.
   __FB_OUT_LIB__
      True (-1) in a module being compiled and linked into a static 
      library, zero (0) otherwise.
   __FB_OUT_OBJ__
      True (-1) in a module being compiled only, zero (0) otherwise.
   __FB_SSE__
      Defined if compiling for SSE floating point unit.
   __FB_VECTORIZE__
      Defined as the level of automatic vectorization (0 to 2)
Environment Information
   __FB_ARGC__
      Defined as an integer literal of the number of command-line arguments 
      passed to the program.
   __FB_ARGV__
      Defined as a ZString Ptr Ptr to the command line arguments passed to 
      the program.
   __DATE__
      Defined as a string literal of the compilation date in "mm-dd-yyyy" 
      format.
   __DATE_ISO__
      Defined as a string literal of the compilation date in "yyyy-mm-dd" 
      format.
   __TIME__
      Defined as a string literal of the compilation time.
   __PATH__
      Defined as a string literal of the absolute path of the module.

Context-specific Information
   __FILE__ and __FILE_NQ__
      Defined as the name of the module.
   __FUNCTION__ and __FUNCTION_NQ__
      Defined as the name of the procedure where it's used.
   __LINE__
      Defined as an integer literal of the line of the module where it's 
      used.
   __FB_OPTION_BYVAL__
      True (-1) if parameters are declared by value by default, zero (0) 
      otherwise.
   __FB_OPTION_DYNAMIC__
      True (-1) if all arrays are variable-length, zero (0) otherwise.
   __FB_OPTION_ESCAPE__
      True (-1) if string literals are processed for escape sequences, zero 
      (0) otherwise.
   __FB_OPTION_GOSUB__
      True (-1) if gosub support is enabled, zero (0) otherwise.
   __FB_OPTION_EXPLICIT__
      True (-1) if variables and objects need to be explicitly declared, 
      zero (0) otherwise.
   __FB_OPTION_PRIVATE__
      True (-1) if all procedures are private by default, zero (0) 
      otherwise.

Constants
   False and True
      Intrinsic constants for the Boolean data type.



---------------------------------------------------- ProPgErrorHandling ----
Error Handling

Handling runtime errors.

   FreeBASIC can handle the errors in the following ways:
   * By default the program does nothing with the errors - they are 
     silently ignored and code continues. In this case code should process 
     possible errors in the next line by using the Err function.
   * If compiled with -e, -ex or -exx options, FreeBASIC uses QB-like 
     error handling.
   * Future OOP versions of FreeBASIC may have a java-like 
     TRY..CATCH...FINALLY exception handler implemented.

   NOTE: The following information is valid unless the error produces an OS 
   General Protection Fault (for example if the program writes outside the 
   process memory area). In these cases the OS will immediately stop the 
   program and issue an error: nothing can avoid it from inside FreeBASIC.

Default error handling
   The default FreeBASIC behavior is to set the ERR variable and continue. 

   Dim As Integer e
   Open "xzxwz.zwz" For Input As #1
   e = Err
   Print e
   Sleep

   (The example program supposes there is no xzxwz.zwz file). The program 
   does not stop; it sets the ERR variable and continues. The error can be 
   processed in the next line.

   Some IO functions such as Open and Put #... can be used in function 
   form, returning an error number or zero if successful.

   Print Open ("xzxwz.zwz" For Input As #1)
   Sleep

QuickBASIC-like error handling
   If the  -e, -ex or -exx switch is used at compile time, the program is 
   expected to have a QB-like error handler enabled. If no handler 
   processes the error, the program stops with an error.

   Notice: if QB-Like error handling is used, the programmer should be 
   prepared to handle all error conditions.

   '' Compile with QB (-lang qb) dialect

   '$lang: "qb"

   On Error Goto FAILED
   Open "xzxwz.zwz" For Input As #1
   On Error Goto 0
   Sleep
   End

   FAILED:
   Dim e As Integer
   e = Err
   Print e
   Sleep
   End

   On Error sets an error handling routine which the program will jump to 
   when an error is found. On Error Goto 0 disables the error handling.

   If an error handling routine is not set when an error occurs, the 
   program will stop and send the console an error message.

   Aborting program due To runtime Error 2 (file Not found)

   The error handler routine can be at the end of the program, as in QB. 
   The On Local Error statement allows the setting of a local error handler 
   routine at the end of the same Sub or Function in which the error 
   occurs.

   '' Compile with -e
   '' The -e command line option is needed to enable error handling.

   Declare Sub foo
     foo
   Sleep

   Sub foo
      
      Dim filename As String
      Dim errmsg As String
      filename = ""
      On Local Error Goto fail
     Open filename For Input Access Read As #1
      Print "No error"
      On Local Error Goto 0
      Exit Sub
      
     fail:
     errmsg = "Error " & Err & _
            " in function " & *Erfn & _
            " on line " & Erl
     Print errmsg
      
   End Sub

   If the -e switch is used (whatever the -lang dialect), the error handler 
   must terminate the program. 
   With (-ex or -exx) and -lang qb dialect only, the error routine can end 
   by using Resume (retries the statement that caused the error) or 
   Resume Next (continues at the next instruction) .

Error codes
   See Runtime Error Codes for a listing of runtime error numbers and their 
   associated meaning.

   No user error code range is defined. If Error is used to set an error 
   code it is wise to use high values to avoid collisions with the list of 
   built-in error codes. (This built-in list may be expanded later.)

See also
   * Error Handling Functions
   * Runtime Error Codes



-------------------------------------------------------------- KeyPgAsm ----
Asm

Code block that allows the use of architecture-specific instructions.

Syntax
   Asm
      architecture-dependent instructions
   End Asm

      Or

   Asm architecture-dependent instructions

Description
   The Asm block is used to insert specific machine-code instructions in a 
   program in order to perform operations that cannot be carried out using 
   the features of the language or to hand-optimize performance-sensitive 
   sections of code.

   The current FreeBASIC compiler currently only produces code for Intel 
   80x86-based machines; however, in the future, the compiler might be 
   ported to a platform which does not support the same instruction set.  
   Therefore, Asm blocks should only be used when necessary, and a 
   FreeBASIC-only alternative should be provided if possible.

   The return value of a function may be set by using the Function keyword 
   within brackets as shown in the example below.

   Asm block comments have the same syntax as usual FreeBASIC Comments  - 
   use FreeBASIC-like " ' " comments, not " ; " as usual in assembly code. 

   x86 Specific:

      Syntax
         The syntax of the inline assembler is a simplified form of Intel 
         syntax.  Intel syntax is used by the majority of x86 assemblers, 
         such as MASM, TASM, NASM, YASM and FASM. In general, the 
         destination of an instruction is placed first, followed by the 
         source. Variables and functions defined by a program may be 
         referenced in an Asm block.  The assembler used by FreeBASIC is 
         GAS, using the .intel_syntax noprefix directive, and Asm blocks 
         are passed through unmodified, except for the substitution of 
         local variable names for stack frame references, and commenting 
         removal.

         Instruction syntax is mostly the same as FASM uses, one important 
         difference is that GAS requires size settings to be followed by 
         the word "ptr".

   ' Assuming "n" is a FB global or local ULONG variable
   mov  eax, [n]        ' OK: size is apparent from eax
   inc  [n]             ' Not OK: size is not given
   inc  dword [n]       ' Not OK: size given, but still not accepted by GAS
   inc  dword Ptr [n]   ' OK: "ptr" is needed by GAS here

      Register Preservation
         When an Asm block is opened, the registers ebx, esi, and edi are 
         pushed to the stack, when the block is closed, these registers are 
         popped back from the stack.  This is because these registers are 
         required to be preserved by most or all OS's using the x86 CPU.  
         You can therefore use these registers without explicitly 
         preserving them yourself. You should not change esp and ebp, since 
         they are usually used to address local variables. 

      Register Names
         The names of the registers for the x86 architecture are written as 
         follows in an Asm block:
         * 4-byte integer registers: eax, ebx, ecx, edx, ebp, esp, edi, 
           esi
         * 2-byte integer registers: ax, bx, cx, dx, bp, sp, di, si (low 
           words of 4-byte e- registers)
         * 1-byte integer registers: al, ah, bl, bh, cl, ch, dl, dh (low 
           and high bytes of 2-byte -x registers)
         * Floating-point registers: st(0), st(1), st(2), st(3), st(4), 
           st(5), st(6), st(7)
         * MMX registers (aliased onto floating-point registers): mm0, mm1
           , mm2, mm3, mm4, mm5, mm6, mm7
         * SSE registers: xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7

      Instruction Set

      See these external references:
         * Original Intel 80386 manual from 1986
         * Latest Intel Pentium 4 manuals
         * NASM x86 Instruction Reference (Please note that NASM is not 
           the assembler used by FreeBASIC, but this page provides a good 
           overview of x86 instructions)

      Unsafe instructions
         Note that the FreeBASIC compiler produces 32-bit protected-mode 
         code for the x86 which usually runs in an unprivileged user level; 
         therefore, privileged and sensitive instructions will assemble 
         fine, but possibly won't work correctly or cause a runtime 
         "General Protection Fault", "Illegal instruction", or SIGILL 
         error. The following are the privileged and sensitive instructions 
         as of the Intel Pentium 4 and Xeon:

         * cli *1
         * clts
         * hlt
         * in *1
         * ins *1
         * int *1               
         * into *1               
         * invd
         * invlpg
         * lgdt
         * lidt
         * lldt
         * lmsw
         * ltr
         * mov to/from CRn, DRn, TRn
         * out *1
         * outs *1
         * rdmsr
         * rdpmc *2
         * rdtsc *2
         * sti *1
         * str
         * wbinvd
         * wrmsr
         * all SSE2 and higher instructions *2

          *1: sensitive to IOPL, fine in DOS 
          *2: sensitive to permission bits in CR4, see below

   The privileged instructions will work "correctly" in DOS when running on 
   a Ring 0 DPMI kernel, like the (non-default) Ring 0 version of CWSDPMI, 
   WDOSX or D3X, nevertheless most of them are not really useful and 
   dangerous when executed from DPMI code. RDTSC (Read Time Stamp Counter) 
   has been shown to be allowed by most, or all OS'es.

   However the usefulness of RDTSC has been diminished with the advent of 
   multi-core and hibernating CPUs. SSE2 and higher instructions are 
   disabled "by default" after CPU initialization, Windows and Linux 
   usually do enable them, in DOS it is business of the DPMI host: HDPMI32 
   will enable them, CWSDPMI won't. The INT instruction is usable in the 
   DOS version/target only, note that it works slightly differently from 
   real mode DOS, see also FaqDOS.

   The segment registers (cs, ds, es, fs, gs) should not be changed from an 
   Asm block, except in certain cases with the DOS port (note that they do 
   NOT work the same way as in real-mode DOS, see also FaqDOS). The 
   operating system or DPMI host is responsible for memory management; the 
   meaning of segments (selectors) in protected mode is very different from 
   real-mode memory addressing.

   Note that those "unsafe" instructions are not guaranteed to raise a 
   "visible" crash even when ran with insufficient privilege - the OS or 
   DPMI host can decide to "emulate" them, either functionally (reading 
   from some CRx works under HDPMI32), or "dummy" (nothing happens, 
   instruction will pass silently, like a NOP).

Example
   '' This is an example for the x86 architecture.
   Function AddFive(ByVal num As Long) As Long
      Asm
         mov eax, [num]
         Add eax, 5
         mov [Function], eax
      End Asm
   End Function

   Dim i As Long = 4

   Print "4 + 5 ="; AddFive(i)

   4 + 5 = 9

   FreeBASIC's Assembler is AS / GAS, the assembler of GCC, so an external 
   program. Some quirks apply:
      * The error lines  returned by FBC for Asm blocks are not related 
        the FB source file. As FBC simply displays the errors returned by 
        AS , the lines are related to the assembly file. To make FreeBASIC 
        preserve them, the compiler must be invoked with the -R option 
        ("don't delete ASM files").
      * The label names are case sensitive inside Asm blocks.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Asm.

Differences from QB
   * New to FreeBASIC

See also
   * Function
   * Naked





============================================================================
  RUNTIME LIBRARY REFERENCE
  -------------------------


------------------------------------------------------------ CatPgArray ----
Array Functions

Statements and procedures for working with arrays.

Defining Arrays
   Statements that create arrays.
Clearing Array Data
   Procedures that work with array memory.
Retrieving Array Size
   Procedures that return bounds of an array's dimension.

Defining Arrays
   Option Dynamic
      Forces arrays to be defined as variable-length arrays.
   '$Dynamic
      Alternate form of the Option Dynamic statement.
   Option Static
      Reverts a previous Option Dynamic command.
   '$Static
      Alternate form of the Option Static statement.
   ReDim
      Defines and resizes variable-length arrays.
   Preserve
      Preserves array contents when used with ReDim.
Clearing Array Data
   Erase
      Destroys variable-length array elements and initializes fixed-length 
      array elements.

Retrieving Array Size
   LBound
      Returns the lower bound of an array's dimension.
   UBound
      Returns the upper bound of an array's dimension.
 



------------------------------------------------------------- CatPgBits ----
Bit Manipulation

Macros that work with the bits and bytes of numbers.

Description
   The macros documented here provide access to the individual bits, bytes 
   and words of integer values.

Byte Manipulation Macros
   Gets the value of individual bytes or words of UInteger values.
Bit Manipulation Macros
   Gets the state of individual bits of numeric values.

Byte Manipulation Macros
   LoByte
      Gets the least significant byte (LSB, or lo-byte) value of an UInteger
      value.
   HiByte
      Gets the most significant byte (MSB, or hi-byte) value of the least 
      significant word (LSW, or lo-word) of an UInteger value.
   LoWord
      Gets the least significant word (LSW, or lo-word) value of an UInteger
      value.
   HiWord
      Gets the most significant word (LSW, or hi-word) value of an UInteger 
      value.
Bit Manipulation Macros
   Bit
      Gets the state of an individual bit in an integer value.
   BitReset
      Gets the value of an integer with a specified bit cleared.
   BitSet
      Gets the value of an integer with a specified bit set.



---------------------------------------------------------- CatPgConsole ----
Console Functions

Procedures that work with the console.

Description
   These procedures provide ways to output text to the console, as well as 
   control where and how text is output.

Configuring the Console
   Statements that affect how text is displayed.
Cursor Color and Positioning
   Procedures that move the cursor and change its color.
Writing Text to the Console
   Procedures that output text to the console.

Configuring the Console
   Cls
      Clears the entire screen or text viewport.
   Width
      Sets or returns the number of rows and columns of the console 
      display.
   View Print
      Sets the printable area of the console screen.

Cursor Color and Positioning
   Color
      Changes the foreground and background color of text to be written.
   CsrLin
      Returns the row position of the cursor.
   Pos
      Returns the column position of the cursor.
   Locate
      Sets the row and column position of the cursor and its visibility.
   Screen (Console)
      Gets the character or color attribute at a given location.
Writing Text to the Console
   Print
   ? (Shortcut For 'Print')
      Writes text to the console.
   Print Using
   ? Using (Shortcut For 'Print Using')
      Writes formatted text to the console.
   Write
      Writes a list of items to the console.
   Spc
      Skips a number of spaces when writing text.
   Tab
      Skips to a certain column when writing text.



------------------------------------------------------------- CatPgDate ----
Date and Time Functions

Procedures that work with dates and time.

Description
   These procedures provide ways to deal with date and time intervals in a 
   consistent way. Additional procedures are provided to set and get the 
   current system date and time, and to retrieve a time stamp for sensitive 
   timing algorithms.

VisualBasic compatible procedures
   Procedures for working with so-called date serials, similar to those 
   used in Visual Basic(r).
Date and time procedures
   Procedures for working with the system date and time.

VisualBasic compatible procedures
   Now
      Gets a date serial of the current date and time.

   Creating Date serials
      DateSerial
         Gets the date serial representation of a date.
      TimeSerial
         Gets the date serial representation of a time.
      DateValue
         Gets the date serial representation of a date expressed as a String
         .
      TimeValue
         Gets the date serial representation of a time expressed as a String
         .

   Extracting information from Date serials
      Second
         Gets the seconds of the hour from a date serial.
      Minute
         Gets the minutes of the hour from a date serial.
      Hour
         Gets the hour of the day from a date serial.
      Day
         Gets the day of the month from a date serial.
      Weekday
         Gets the day of the week from a date serial.
      Month
         Gets the month of the year from a date serial.
      Year
         Gets the year from a date serial.
      DatePart
         Gets a time interval from a date serial.

   Extracting information from Date serials
      DateAdd
         Gets the result of a time interval added to a date serial.
      DateDiff
         Gets a time interval between two date serials.

   Miscellaneous
      IsDate
         Tests if a String can be converted to a date serial.
      MonthName
         Gets the month name of its integer representation.
      WeekdayName
         Gets the weekday name of its integer representation.
Date and time procedures
   Date
      Gets the String representation of the current system date.
   Time
      Gets the String representation of the current system time.
   SetDate
      Sets the current system date.
   SetTime
      Sets the current system time.
   Timer
      Gets a counter expressed in seconds.



------------------------------------------------------------ CatPgError ----
Error Handling Functions

Statements and procedures that provide runtime error-handling capabilities.

Description
   These statements and procedures provide ways of dealing with runtime 
   errors. Specific modules, procedures and source code lines can be 
   retrieved, and error handlers can be set up.

Determining Errors
   Procedures that retrieve information about an error.
Handling Errors
   Statements that allow handling of errors.

Determining Errors
   Erl
      Gets the line in source code where the error occurred.
   Erfn
      Gets the name of the function where the error occurred.
   Ermn
      Gets the name of the source file where the error occurred.
   Err
      Gets the error number of the last error that occurred.
   Error
      Generates an error using an error number.
Handling Errors
   On Error
      Sets a global error handler using a label.
   On Local Error
      Sets a local error handler using a label.
   Resume
      Resumes execution at the line where the error occurred.
   Resume Next
      Resumes execution at the line after where the error occurred.

See also
   * Error Handling
   * Runtime Error Codes



------------------------------------------------------------- CatPgFile ----
File I/O Functions

Statements and procedures for working with files and devices.

Description
   These statements and procedures provide file and device i/o 
   capabilities. So called file numbers can be bound to files or devices, 
   which can be read or written to using formatted (text mode) or 
   unformatted (binary mode) data. In binary mode, files and devices can be 
   read from or written to in arbitrary locations. For multithreaded 
   applications, files and devices can also be locked.

Opening Files or Devices
   Procedures and other keywords that provide read or write access to a 
   file or device.
Reading from and Writing to Files or Devices
   Procedures that read and write data to an opened file or device.
File Position and other Info
   Procedures that determine where reading and writing will take place 
   within an opened file.

Opening Files or Devices
   FreeFile
      Gets an available file number that can be used to read or write from 
      files or devices.
   Open
      Binds a file number to a physical file to provide reading and writing 
      capabilities.
   Open Com
      Binds a file number to a communications port.
   Open Cons
      Binds a file number to the standard input and output streams.
   Open Err
      Binds a file number to the standard input and error streams.
   Open Lpt
      Binds a file number to a printer device.
   Open Pipe
      Binds a file number to the input and output streams of a process.
   Open Scrn
      Binds a file number directly to the console.
   Close
      Unbinds a file number from a file or device.
   Reset
      Unbinds all active file numbers.

   File I/O modes
      Input (File Mode)
         Text data can be read from the file.
      Output
         Text data can be written to the file.
      Append
         Text data is added to the end of a file when output.
      Binary
         Arbitrary data can be read from or written to the file.
      Random
         Blocks of data of certain size can be read from and written to the 
         file.

   File access privileges
      Access
         An overview of file access privileges.
      Read (File Access)
         Binary data can only be read from the file.
      Write (File Access)
         Binary data can only be written to the file.
      Read Write(File Access)
         Binary data can be read from and written to the file.

   Character encoding
      Encoding
         Specifies the character encoding of a file.
Reading from and Writing to Files or Devices
   Input #
      Reads a list of values from a file or device.
   Write #
      Writes a list of values to a file or device.
   Input()
      Reads a number of characters from a file or device.
   Winput()
      Reads a number of wide characters from a file or device.
   Line Input #
      Reads a line of text from a file or device.
   Print #
   ? # (Shortcut For 'Print #')
      Writes text data to a file or device.
   Put #
      Writes arbitrary data to a file or device.
   Get #
      Reads arbitrary data from a file or device.

File Position and other Info
   LOF
      Gets the length (in bytes) of a file.
   LOC
      Gets the file position of the last read or write operation.
   EOF
      Returns true if all of the data has been read from a file.
   Seek (Statement)
      Sets the file position of the next read or write operation.
   Seek (Function)
      Gets the file position of the next read or write operation.
   Lock
      Restricts read or write access to a file or portion of a file.
   Unlock
      Remove read or write restrictions from a previous Lock command.



------------------------------------------------------------- CatPgMath ----
Mathematical Functions

Procedures that work with numbers mathematically.

Description
   This set of procedures provide basic algebraic and trigonometric 
   function. Random numbers can also be retrieved, using a variety of 
   random number generators.

Algebraic Procedures
   Absolute values, logarithms, square roots and more.
Trigonometry Procedures
   Sine, Cosine and other trigonometry-related procedures.
Miscellaneous Procedures
   Miscellaneous procedures.

Algebraic Procedures
   Abs
      Returns the absolute value of a number.
   Exp
      Returns e raised to some power.
   Log
      Returns the natural logarithm of a number.
   Sqr
      Returns the square root of a number.
   Fix
      Returns the integer part of a number.
   Frac
      Returns the fractional part of a number.
   Int
      Returns the largest integer less than or equal to a number.
   Sgn
      Returns the sign of a number.
Trigonometric Procedures
   Sin
      Returns the sine of an angle.
   Asin
      Returns the arcsine of a number.
   Cos
      Returns the cosine of an angle.
   Acos
      Returns the arccosine of a number.
   Tan
      Returns the tangent of an angle.
   Atn
      Returns the arctangent of a number.
   Atan2
      Returns the arctangent of the ratio between two numbers.

Miscellaneous Procedures
   Randomize
      Seeds the random number generator used by Rnd.
   Rnd
      Returns a random Double in the range [0, 1).



----------------------------------------------------------- CatPgMemory ----
Memory Functions

Procedures that work with static and dynamic memory.

Description
   These procedures provide access to the free store, or heap. Memory from 
   the free store can be reserved and freed, and procedures are provided to 
   read and write directly to that memory.

Working with Dynamic Memory
   Procedures that reserve, resize or free dynamic memory.
Miscellaneous Procedures
   Procedures that read or write values to and from addresses in memory.

Working with Dynamic Memory
   Allocate
      Reserves a number of bytes of uninitialized memory and returns the 
      address.
   CAllocate
      Reserves a number of bytes of initialized (zeroed) memory and returns 
      the address.
   Reallocate
      Changes the size of reserved memory.
   Deallocate
      Returns reserved memory back to the system.
Miscellaneous Procedures
   Peek
      Reads some type of value from an address.
   Poke
      Writes some type of value to an address.
   Clear
      Clears data in an array with a specified value.
   Swap
      Exchange the contents of two variables.
   SAdd
      Returns the address for the data in a zstring variable.

See also
   * Memory Operators



------------------------------------------------------------ CatPgOpsys ----
Operating System Functions

Statements and procedures for working with files, directories and the 
system.

Description
   The statements and procedures listed here provide access to the 
   operating system environment. They transfer execution to external 
   programs, get information about files and directories, manipulate the 
   file system and send commands to the command shell.

Working with Files
   Procedures that deal with files.
Working with Directories
   Various directory management procedures.
File Properties
   Get information about files.
System Procedures
   Procedures for working with the environment.

Working with Files
   Exec and Chain
      Temporarily transfers control to another program.
   Run
      Transfers control to another program.
   Kill
      Deletes an existing file.
   Name
      Renames an existing file.

Working with Directories
   CurDir
      Gets the current working directory.
   ChDir
      Sets the current working directory.
   Dir
      Gets the names of files or directories matching certain attributes.
   ExePath
      Gets the directory of the current running program.
   MkDir
      Creates a new directory.
   RmDir
      Deletes an existing directory.
File Properties
   FileAttr
      Gets information about a file bound to a file number.
   FileCopy
      Copies a file.
   FileDateTime
      Gets the last modified date and time of a file.
   FileExists
      Tests for the existence of a file.
   FileLen
      Gets the length (in bytes) of a file.

System Procedures
   Fre
      Gets the amount of free memory (in bytes) available.
   Command
      Gets the command-line parameters passed to the program.
   Environ
      Gets the value of an environment variable.
   IsRedirected
      Checks whether stdin or stdout is redirected to a file or not.
   SetEnviron
      Sets the value of an environment variable.
   Shell
      Sends a command to the system command interpreter.
   System
      Closes all open files and exits the program.



----------------------------------------------------------- CatPgString ----
String Functions

Statements and Procedures that work with strings.

Description
   These statements and procedures provide many ways to create and 
   manipulate strings and substrings. Numbers can be converted to strings 
   and vice-versa. Procedures are also provided to aid in serialization of 
   numeric data, perhaps for persistent storage.

Creating Strings
   String data types and procedures that create new strings.
Character Conversions
   Procedures that convert from character codes to strings and back.
Numeric/Boolean to String Conversions
   Procedures that convert numeric values to strings.
String to Numeric Conversions
   Procedures that convert strings to numeric values.
Numeric Serializations
   Procedures that convert raw numeric data to and from strings suitable 
   for storage.
Working with Substrings
   Procedures that return subsets of strings, or that modify subsets of 
   strings.

Creating Strings
   String
      Standard data type: 8 bit character string.
   String (Function)
      Returns a String of multiple characters.
   ZString
      Standard data type: null terminated 8 bit character string.
   WString
      Standard data type: wide character string.
   Wstring (Function)
      Returns a WString of multiple characters.
   Space
      Returns a String consisting of spaces.
   WSpace
      Returns a WString consisting of spaces.
   Len
      Returns the length of a string in characters.

Character Conversion
   Asc
      Returns an Integer representation of an character.
   Chr
      Returns a string of one or more characters from their ASCII Integer 
      representation.
   WChr
      Returns a WString of one or more characters from their Unicode Integer
      representation.

Numeric/Boolean to String Conversions
   Bin
      Returns a binary String representation of an integral value.
   WBin
      Returns a binary WString representation of an integral value.
   Hex
      Returns a hexadecimal String representation of an integral value.
   WHex
      Returns a hexadecimal WString representation of an integral value.
   Oct
      Returns an octal String representation of an integral value.
   WOct
      Returns an octal WString representation of an integral value.
   Str
      Returns the String representation of numeric value or boolean.
   WStr
      Returns the WString representation of numeric value.
   Format
      Returns a formatted String representation of a Double.

String to Numeric Conversions
   Val
      Returns the Double conversion of a numeric string.
   ValInt
      Returns the Integer conversion of a numeric string.
   ValLng
      Returns the Long conversion of a numeric string.
   ValUInt
      Returns the UInteger conversion of a numeric string.
   ValULng
      Returns the ULong conversion of a numeric string.
Numeric Serialization
   MKD
      Returns an eight character String representation of a Double.
   MKI
      Returns a four character String representation of a Integer.
   MKL
      Returns a four character String representation of a Long.
   MKLongInt
      Returns an eight character String representation of a LongInt.
   MKS
      Returns a four character String representation of a Single.
   MKShort
      Returns a two character String representation of a Short.
   CVD
      Returns a Double representation of an eight character String.
   CVI
      Returns an Integer representation of a four character String.
   CVL
      Returns a Long representation of a four character String.
   CVLongInt
      Returns a LongInt representation of an eight character String.
   CVS
      Returns a Single representation of a four character String.
   CVShort
      Returns a Short representation of a two character String.

Working with Substrings
   Left
      Returns a substring of the leftmost characters in a string.
   Mid (Function)
      Returns a substring of a string.
   Right
      Returns a substring of the rightmost characters in a string.
   LCase
      Returns a copy of a string converted to lowercase alpha characters.
   UCase
      Returns a copy of a string converted to uppercase alpha characters.
   LTrim
      Removes surrounding substrings or characters on the left side of a 
      string.
   RTrim
      Removes surrounding substrings or characters on the right side of a 
      string.
   Trim
      Removes surrounding substrings or characters on the left and right 
      side of a string.
   InStr
      Returns the first occurrence of a substring or character within a 
      string.
   InStrRev
      Returns the last occurrence of a substring or character within a 
      string.
   Mid (Statement)
      Copies a substring to a substring of a string.
   LSet
      Left-justifies a string.
   RSet
      Right-justifies a string.



-------------------------------------------------------- CatPgThreading ----
Threading Support Functions

Procedures for working with multithreaded applications.

Description
   These procedures allow for multithreaded programming. Threads and 
   conditional variables can be created and destroyed, and so-called 
   mutexes can be obtained to protect thread-sensitive data.

Threads
   Procedures that start and wait for threaded procedures.
Mutexes
   Procedures that deal with mutexes.
Conditional Varables
   Procedures that create and signal conditional variables.

Threads
   ThreadCall
      Starts a procedure with parameters in a separate thread of execution.
   ThreadCreate
      Starts a procedure in a separate thread of execution.
   ThreadWait
      Waits for a thread to finish and releases the thread handle.
   ThreadDetach
      Releases a thread handle without waiting for the thread to finish.

Mutexes
   MutexCreate
      Creates a mutex.
   MutexLock
      Acquires a lock on a mutex.
   MutexUnlock
      Releases a lock on a mutex.
   MutexDestroy
      Destroys a mutex that is no longer needed.
Conditional Variables
   CondCreate
      Creates a conditional variable.
   CondWait
      Pauses execution of a threaded procedure.
   CondSignal
      Resumes execution of a threaded procedure waiting for a conditional.
   CondBroadcast
      Resumes all threaded procedures waiting for a conditional.
   CondDestroy
      Destroys a conditional variable that is no longer needed.

Platform Differences
   * These procedures are not supported in DOS.



------------------------------------------------------------ CatPgInput ----
User Input (Runtime Library)

Statements and procedures (from runtime library) that get input from the 
user.

Description
   These statements and procedures allow access to the keyboard buffer, and 
   provide ways of getting input from the user.

Reading keys from the keyboard buffer
   Procedures that read individual keys from the keyboard buffer.
Reading values from the keyboard buffer
   Procedures that read characters and values from the keyboard buffer.

Reading values from the keyboard buffer
   Input
      Reads values from the keyboard buffer.
   Line Input
      Reads a line of text from the keyboard buffer.
   Input()
      Reads a number of characters from the keyboard buffer, file or 
      device.
   Winput()
      Reads a number of wide characters from the keyboard buffer, file or 
      device.
Reading keys from the keyboard buffer
   Inkey
      Gets the first key, if any, waiting in the keyboard buffer.
   GetKey
      Gets and waits for the first key in the keyboard buffer.





============================================================================
  GRAPHICS LIBRARY REFERENCE
  --------------------------


------------------------------------------------------------ CatPgGfx2D ----
2D Drawing Functions

Statements and procedures for working with 2D graphics.

Description
   The statements and procedures listed here provide ways of drawing to the 
   screen. Image buffers can be created and blitted to the screen using a 
   variety of blending methods. Palette colors can be retrieved or set in 
   graphics modes that support them.

Working with Color
   Procedures that control the color used by other drawing procedures.
Drawing to Image Buffers
   Procedures that draw shapes and text onto image buffers or to the 
   screen.
Image Buffer Creation
   Procedures that create, free and save image buffers.
Blitting Image Buffers
   Procedures that draw image buffers onto other image buffers or to the 
   screen.

Working with Color
   Color
      Sets the foreground and background color to use with the drawing 
      procedures.
   Palette
      Gets or sets color table information in paletted modes.
   RGB
      Returns a color value for hi/truecolor modes.
   RGBA
      Returns a color value including alpha (transparency) for hi/truecolor 
      modes.
   Point
      Gets a pixel value from an image buffer or screen.

Drawing to Image Buffers
   PSet and PReset
      Plots a single pixel on an image buffer or screen.
   Line (Graphics)
      Plots a line of pixels on an image buffer or screen.
   Circle
      Plots circles and ellipses on an image buffer or screen.
   Draw
      Draws in a sequence of commands on an image buffer or screen.
   Draw String
      Writes text to an image buffer or screen.
   Paint
      Fills an area with color on an image buffer or screen.

Image Buffer Creation
   Get (Graphics)
      Creates an image buffer from a portion of another image buffer or 
      screen.
   ImageCreate
      Creates an image buffer of a certain size and pixel depth.
   ImageDestroy
      Frees an image buffer resource.
   ImageConvertRow
      Converts a row of pixels in an image buffer to a different color 
      depth.
   ImageInfo
      Retrieves useful information about an image buffer
   BLoad
      Creates an image buffer from a file.
   BSave
      Saves an image buffer to a file.
Blitting Image Buffers
   Put (Graphics)
      Blits an image buffer to another image buffer or screen.

   Blending Methods
      Add
         Saturated addition of the source and target components.
      Alpha
         Blend using a uniform transparency or the image buffer's alpha 
         channel.
      And
         Combine the source and target components using a bitwise And
      Or
         Combine the source and target components using a bitwise Or
      PSet
         Directly copy pixel colors from the source to the destination.
      Trans
         Pixels matching the transparent mask color are not blitted.
      Custom
         Allows a custom blending procedure to be used.
      Xor
         Combine the source and target components using a bitwise Xor



--------------------------------------------------------- CatPgGfxInput ----
User Input Functions (Graphics Library)

Procedures (from graphics library) for working with mice, gaming devices 
and keyboards.

Description
   These procedures provide access to external devices such as keyboards, 
   mice and gamepads.

Mouse and Joystick Input
   Procedures that provide state information of the mouse or joystick.
Keyboard Input
   Procedures that provide keyboard state information.

Mouse and Joystick Input
   GetMouse
      Gets button and axis information for the mouse.
   SetMouse
      Sets position and visibility of the mouse cursor.
   GetJoystick
      Gets button and axis information for gaming devices.
   Stick
      Gets axis position for gaming devices.
   Strig
      Gets button state for gaming devices.
Keyboard Input
   MultiKey
      Gets key information for the keyboard.



-------------------------------------------------------- CatPgGfxScreen ----
Screen Functions

Statements and procedures that work with the graphics display.

Description
   These statements and procedures control the graphics capabilities of the 
   FreeBASIC graphics library. Screen modes can be set with varying 
   resolutions and color depths, window events can be handled, and specific 
   OpenGL procedures can be retrieved.

Working with screen modes
   Procedures for setting and retrieving information about screen modes.
Working with pages
   Procedures that manipulate screen pages.
Working video memory
   Procedures that provide direct access to framebuffer memory.
Screen Metrics
   Procedures that control the way coordinates are interpreted.
Screen Data Types
   Data types and data definitions for screen functions.

Working with screen modes
   ScreenList
      Gets the available fullscreen resolutions.
   Screen and ScreenRes
      Sets a new graphics display mode.
   ScreenInfo
      Gets information about the system desktop or current display mode.
   ScreenControl
      Gets or sets internal graphics library settings.
   ScreenEvent
      Gets system events.
   ScreenGLProc
      Returns the address of an OpenGL procedure.
   WindowTitle
      Sets the running program's window caption.

Working with pages
   Cls
      Clears the entire screen or viewport.
   ScreenSet
      Sets the current work and visible pages.
   ScreenCopy and PCopy and Flip
      Copies pixel data from one page to another.
   ScreenSync
      Waits for the vertical refresh of the monitor.
Working video memory
   ScreenPtr
      Gets the address of the working page's framebuffer.
   ScreenLock
      Locks the current working page's framebuffer for direct access.
   ScreenUnlock
      Reverts a previous ScreenLock command.

Screen Metrics
   View (Graphics)
      Sets a clipping region for all drawing and blitting procedures.
   Window
      Sets a new coordinate mapping for the current viewport.
   PMap
      Converts coordinates between physical and view mappings.
   PointCoord
      Queries Draw's pen position.

Screen Data Types
   Event
      Data type for ScreenEvent function.



---------------------------------------------------------------- GfxLib ----
GfxLib - FreeBASIC graphics library overview

The libary named GfxLib is the built-in graphics library included in FreeBAS
IC. As well as re-creating every QuickBASIC graphics command, GfxLib has 
built-in commands to handle input from the keyboard and mouse. Major 
contributors of the library are Lillo, coderJeff and DrV.

The library supports various drivers depending on the platform: 

   * All:
      * Null Does nothing, allows to use graphics functions on in-memory 
        buffers and such, without anything being displayed in a graphics 
        window.  (gfxlib2/gfx_driver_null.c)

   * Win32:
      * DirectX The default selection of FB GfxLib. May not be available 
        on old Windows installations. (gfxlib2/win32/gfx_driver_ddraw.c)
      * GDI The "safest" one, available in all Win32 versions. Bug note: 
        broken in FB versions 0.20 to 0.24 (crash), and minor problems 
        0.18.5, and 0.90.x and 1.xx ("banding effects", try extra 
        SCREENUNLOCK), (forum discussion: p=106600) 
        (gfxlib2/win32/gfx_driver_gdi.c)
      * OpenGL (gfxlib2/win32/gfx_driver_opengl.c)

   * Linux & others:
      * X11 The default on Unix systems  (gfxlib2/unix/gfx_driver_x11.c)
      * OpenGL (on top of X11) (gfxlib2/unix/gfx_driver_opengl_x11.c)
      * FBDev Linux framebuffer device -- fallback in case X11 is disabled 
        (gfxlib2/linux/gfx_driver_fbdev.c)

   * DOS:
      * BIOS (gfxlib2/dos/gfx_driver_bios.c)
      * ModeX "tuned" 320x240x8bpp VGA mode 
        (gfxlib2/dos/gfx_driver_modex.c)
      * VESA banked compatible with very old VESA 1.x implementations 
        (gfxlib2/dos/gfx_driver_vesa_bnk.c)
      * VESA linear needs VESA version at least 2.0, usually faster than 
        banked VESA (gfxlib2/dos/gfx_driver_vesa_lin.c)
      * VGA (gfxlib2/dos/gfx_driver_vga.c)
      * Bug note: Palette doesn't work well 
        (forum discussion: t=12691 2008) (forum discussion: t=19980 2012)

ScreenControl can be used (SET_DRIVER_NAME 103) to override the default 
driver preferences.

Platform Differences
   * In DOS, GfxLib will create and "manage" a mouse arrow if a mouse 
     driver is detected. There is no "official" way to disable this. Also 
     note that the arrow doesn't react to mouse movements while the screen 
     is locked.
   * In DOS, Windowing and OpenGL related commands and switches are not 
     available (they exist but do nothing, or return some values with no 
     meaning)
   * In DOS, the refresh rate setting is not available (some VESA cards do 
     support it, but FreeBASIC for now doesn't)
   * In DOS, the resolution must match one supported by the graphics card. 
     GfxLib will try to find an appropriate mode from VGA modes, ModeX or 
     VESA, preferring VESA LFB interface if available, or banked VESA 
     otherwise. Unsupported resolutions may currently crash the program (if 
     you fail to check SCREENPTR for ZERO before using it), though in 
     future GfxLib may try to find a close match instead. For optimal 
     compatibility, you should support "safe" resolutions like 640x480 and 
     800x600, and maybe 1024x768. There are various additional modes like 
     768x576 around, but they are vendor specific and lacking on many other 
     cards. Also modes 1024x768 and above are not available on older cards 
     and laptops.
   * It has been observed that SCREEN and SCREENRES may fail to clear the 
     screen in DOS, actually this is probably a BIOS bug that GfxLib 
     currently doesn't workaround.

Differences from QB
   * Graphics support was internally redesigned. QB used VGA graphics 
     modes, and wrote directly into the VGA RAM. Multiple pages were 
     available as long as the card supported them. FB uses backbuffers, one 
     per defined page, and copies them to the video RAM (VGA (DOS), VESA 
     (DOS), DirectX (Win32), ...) in the background. Graphics commands do 
     work as they used to in QB, but a few notable differences are present:
      * The background screen updating eats a considerable amount of CPU 
        performance.
      * There is a thread (Win32 and Linux) or ISR (DOS, uses the PIT) 
        active for this.
      * Mixing FB's graphics support with low-level screen accesses (VGA) 
        is not supported, even in DOS. However direct screen memory access 
        is possible using Screenptr and Screenlock and is fully portable. 
        In DOS VGA and VESA are still available, but can't be mixed with 
        FB's graphics support.

See also
   * GFX Functions Index
   * Screen The QB-like way to set graphics mode
   * ScreenRes More flexible alternative to Screen
   * ScreenList Check display modes available for FB GfxLib to use
   * ScreenControl Select driver and more 
   * ScreenLock
   * ScreenUnlock
   * ScreenPtr Semi-low level access
   * ScreenSet
   * ScreenCopy
   * ScreenInfo
   * ScreenGLProc
   * Internal pixel formats



---------------------------------------------------------- GfxScancodes ----
DOS Keyboard Scancodes

Listing of keyboard scancodes.

Description
Here follows a list of hardware keyboard scancodes accepted by the MultiKey 
function. These are equal to DOS scancodes, and are guaranteed to be always 
recognized on all platforms.

These constants are also defined in the fbgfx.bi include file you can use 
in your programs. If you are using the lang fb dialect then everything 
inside fbgfx.bi is enclosed in the FB Namespace. To use these constants in 
lang fb, either prepend "FB." to the constant name, or put "Using FB" after 
the #include line.
The hexadecimal code is not required and provided only for reference.

   SC_ESCAPE       &h01
   SC_1            &h02
   SC_2            &h03
   SC_3            &h04
   SC_4            &h05
   SC_5            &h06
   SC_6            &h07
   SC_7            &h08
   SC_8            &h09
   SC_9            &h0A
   SC_0            &h0B
   SC_MINUS        &h0C
   SC_EQUALS       &h0D
   SC_BACKSPACE    &h0E
   SC_TAB          &h0F
   SC_Q            &h10
   SC_W            &h11
   SC_E            &h12
   SC_R            &h13
   SC_T            &h14
   SC_Y            &h15
   SC_U            &h16
   SC_I            &h17
   SC_O            &h18
   SC_P            &h19
   SC_LEFTBRACKET  &h1A
   SC_RIGHTBRACKET &h1B
   SC_ENTER        &h1C
   SC_CONTROL      &h1D
   SC_A            &h1E
   SC_S            &h1F
   SC_D            &h20
   SC_F            &h21
   SC_G            &h22
   SC_H            &h23
   SC_J            &h24
   SC_K            &h25
   SC_L            &h26
   SC_SEMICOLON    &h27
   SC_QUOTE        &h28
   SC_TILDE        &h29
   SC_LSHIFT       &h2A
   SC_BACKSLASH    &h2B
   SC_Z            &h2C
   SC_X            &h2D
   SC_C            &h2E
   SC_V            &h2F
   SC_B            &h30
   SC_N            &h31
   SC_M            &h32
   SC_COMMA        &h33
   SC_PERIOD       &h34
   SC_SLASH        &h35
   SC_RSHIFT       &h36
   SC_MULTIPLY     &h37
   SC_ALT          &h38
   SC_SPACE        &h39
   SC_CAPSLOCK     &h3A
   SC_F1           &h3B
   SC_F2           &h3C
   SC_F3           &h3D
   SC_F4           &h3E
   SC_F5           &h3F
   SC_F6           &h40
   SC_F7           &h41
   SC_F8           &h42
   SC_F9           &h43
   SC_F10          &h44
   SC_NUMLOCK      &h45
   SC_SCROLLLOCK   &h46
   SC_HOME         &h47
   SC_UP           &h48
   SC_PAGEUP       &h49
   SC_LEFT         &h4B
   SC_RIGHT        &h4D
   SC_PLUS         &h4E
   SC_END          &h4F
   SC_DOWN         &h50
   SC_PAGEDOWN     &h51
   SC_INSERT       &h52
   SC_DELETE       &h53
   SC_F11          &h57
   SC_F12          &h58
   '' Extra scancodes not compatible with DOS scancodes
   SC_LWIN         &h5B
   SC_RWIN         &h5C
   SC_MENU         &h5D

See also
   * MultiKey

   


-------------------------------------------------------- GfxDefPalettes ----
Default Palettes

Default color values for FreeBASIC graphics and text screen modes.

   FreeBASIC initializes the palette indexes with the colors in the tables 
   below. The colors are the same as in QB. Colors in graphics mode can be 
   changed using the Palette statement. There is no portable way of 
   changing the palette in console mode.

Screen mode 1
   4 colors: Black and white, and two others
Screen modes 2, 10 and 11
   Monochromatic: black and white.
Screen modes 7, 8, 9, 12, and Console
   Two sets of 8 colors: normal and intense (bright)
Screen 13 and 8-bit modes
   Multiple color and grayscale bands

Screen mode 1

      +-----+-------+
      |Value|Name   |
      |0    |black  |
      |1    |cyan   |
      |2    |magenta|
      |3    |white  |
      +-----+-------+

Screen modes 2, 10 and 11

      +-----+-----+
      |Value|Name |
      |0    |black|
      |1    |white|
      +-----+-----+

Screen modes 7, 8, 9, 12, and Console

      +------------+-----------+-------------+-------------+
      |Normal Value|Normal Name|Intense Value|Intense Name |
      |0           |black      |8            |dark grey    |
      |1           |blue       |9            |bright blue  |
      |2           |green      |10           |bright green |
      |3           |cyan       |11           |bright cyan  |
      |4           |red        |12           |bright red   |
      |5           |pink       |13           |bright pink  |
      |6           |yellow     |14           |bright yellow|
      |7           |grey       |15           |white        |
      +------------+-----------+-------------+-------------+

Screen 13 and 8-bit modes

   Screen 12 color band

      Colors 0 through 15 are the same as screen 12 mode.

   Grayscale band
      Colors 16 through 31 are grayscale from black to white.

   Brightness/saturation bands
      3 bands of decreasing brightness, each containing 3 bands of 
      decreasing saturation, each containing 24 hues of color starting and 
      ending at blue.

         +-------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
         |Name   |HB/HS|HB/MS|HB/LS|MB/HS|MB/MS|MB/LS|LB/HS|LB/MS|LB/LS|
         |blue   |32   |56   |80   |104  |128  |152  |176  |200  |224  |
         |magenta|36   |60   |84   |108  |132  |156  |180  |204  |228  |
         |red    |40   |64   |88   |112  |136  |160  |184  |208  |232  |
         |yellow |44   |58   |92   |116  |140  |164  |188  |212  |236  |
         |green  |48   |72   |96   |120  |144  |168  |192  |216  |240  |
         |cyan   |52   |76   |100  |124  |148  |172  |194  |220  |244  |
         +-------+-----+-----+-----+-----+-----+-----+-----+-----+-----+

   Black band
      Colors 248 through 255 are black.





============================================================================
  TUTORIALS
  ---------



============================================================================
    Getting Started

------------------------------------------------------- ProPgHelloWorld ----
Hello World

This example is a classic in any programming language.

More as a sanity check than anything else, a good place to start with any 
programming language is to try a very simple program to test that the 
compiler is installed correctly and that a valid executable can be made.

Open up any editor capable of saving text files and type in the following 
source code:
   Print "Hello World"

Save the file with a '.bas' extension.  For example 'hello.bas'

From a command prompt or shell in the directory where 'hello.bas' was 
saved, type the following command:

   fbc hello.bas

Depending on the operating system, this should create an executable file in 
the same directory as 'hello.bas'.  It might be named 'hello.exe' or '
./hello', for example.

Run the executable, and we should have the following output:

   Hello World

See also
   * Freebasic FAQ
   * Main Features
   * Requirements
   * Installing
   * Running



---------------------------------------------------------- ProPgPrimer1 ----
FreeBASIC Primer #1

This primer is intended for beginning beginners, for those who are just 
starting to learn how to program and using FreeBASIC do to it.

Learning the language
   Learning a programming language means learning the words to write it and 
   knowing what they mean when they are written.  We don't need to learn 
   them all at once.  But learning a few important words that do something 
   will help us get started.  Here we are just going to concentrate on 
   these keywords:

   * Dim
   * Print
   * Input
   * For...Next
   * If...Then
   * Do...Loop

Hello World!
   No beginners reference is complete without this example.

   Print "Hello World!"

   The text between the pair of double quotes is a literal string.  The 
   Print statement is used to output text to the display.  If you can edit, 
   compile, and execute this example, you are on your way.

   Note: A program terminates immediately after executing the last line of 
   code. User can add a Sleep statement to induce a pause until pressing 
   any key to complete instruction (see last example for usage).

Using a Variable to Store Data
   Sometimes in a program we will want to store some information somewhere, 
   in memory, and then use it later.  To store something in memory we use a 
   variable.  All variables in FreeBASIC are of some specific type, like a 
   number or a string.  We use the Dim statement to declare a variable name 
   and specify what type of information we want to store in it.

   Dim text As String
   text = "Hello World!"
   Print text

   We are using Dim to let the compiler know that we want to use a variable 
   named text in our program and that we will be putting String data in it. 
   We then assign (copy) "Hello World!" in to the variable.  Finally, we 
   use Print to output it to the display.

Using a Variable in an Expression
   An expression is a generic term for describing a part of the source code 
   that can be evaluated.  After an expression is evaluated, we can then do 
   something with it, like assign (copy) it to a variable.

   Dim As String a, b, text
   a = "Hello"
   b = "World"
   text = a + " " + b + "!"
   Print text

   We are assigning the variables a and b with some data.  We are then 
   using the variables a and b in an expression which is then assigned to 
   text.  Finally, we output the result to the display.

Getting Input from the User
   Often, we have no idea what data is needed for a program unless the user 
   gives it to us.  We can't put it in our source code since we won't know 
   what it is until the user runs the program and tells us what it is.

   Dim answer As String
   Input "Type something and press enter:", answer
   Print "You typed: '"; answer; "'"

   Here the Input statement will first, output some information to the 
   display, and then wait for the user to give the program some data.  In 
   this example, we just output back to the display, exactly what the user 
   typed in.

Doing Some Math
   Variables and expressions are not just limited to strings.  Most early 
   languages didn't handle strings very well if at all.  Writing 
   mathematical expressions is similar to how they might be written with 
   pencil and paper.

   Dim As Integer a, b, c

   a = 5
   b = 7
   c = a + b

   Print "a = "; a
   Print "b = "; b
   Print "a + b = "; c

   We are assigning values to the variables a, b and c.  We are using 
   Integer for the variables' data type.  An integer can be positive or 
   negative, but not have any fractions.

Doing Some Math with Input
   This is similar to the previous example, except we will let the user 
   choose the numbers we are going to add together.

   Dim As Integer a, b, r
   Input "Enter a number:", a
   Input "Enter another number:", b

   r = a + b
   Print "The sum of the numbers is "; r

   Dim lets the compiler know which variable names we want to use and that 
   they are going to hold Integer data.  We are using Input to get the 
   numbers from the user, and Print to display the results.

Doing More Math with Input
   Numeric variables are not limited to just integers.  We can also use  
   Single or Double precision data types which can represent fractions.  In 
   this example we will take some input from the user to convert a weight 
   in pounds to kilograms.

   Dim As Single lb, kg
   Input "Enter a weight in pounds:", lb

   kg = lb * 0.454
   Print lb; " lb. is equal to "; kg; " kg"

Repeating Statements
   Using For...Next statement we can tell the program to do something 
   repeatedly a set number of times.  For example lets say we wanted to add 
   up all the numbers from 1 to 100.

   Dim total As Integer
   Dim number As Integer
   total = 0
   For number = 1 To 100
     total = total + number
   Next
   Print "The sum of number from 1 to 100 is "; total

Making a Decision
   A program can choose which statements to execute using a conditional 
   statement like If...Then.  We can use the value of a variable or the 
   result of an expression to decide if we should, or should not, execute 
   one or more statements.

   Dim number As Integer
   Input "Enter a number : ", number
   Print "Your number is ";
   If number < 0 Then
     Print "negative"
   ElseIf number > 0 Then
     Print "positive"
   Else
     Print "zero"
   End If

   After getting a number from the user, we are going to output a word ( 
   positive, negative, or zero ) based on which condition matches the 
   statement.

Repeating Statements (Again)
   Here we will use another looping structure Do...Loop to repeat some 
   statements.  How will the program know to stop repeating the statements? 
   We will use If...Then to make the decision when to get out of the loop.

   Dim As Single   total, count, number   ' multi variable declaration (same type)
   Dim As String   text

   Print "This program will calculate the sum and average for a"
   Print "list of numbers. Enter an empty value to see results."
   Print

   Do
     Input "Enter a number: ", text       ' get user input
     If text = "" Then Exit Do            ' if empty -> quit Do/Loop
     count += 1                           ' increment count by: 1
     total += Val(text)                   ' add and assign new value
   Loop

   Print
   Print "You entered:    "; count; "  number(s)"
   Print "The sum is:     "; total

   If count > 0 Then Print "The average is: "; total / count

   Print
   Print "Any keypress ends program. ";

   Sleep

See also
   * Dim
   * Print
   * ?
   * Input
   * For...Next
   * If...Then
   * Do...Loop




============================================================================
    Source Files

------------------------------------------------------ ProPgSourceFiles ----
Source Files (.bas)

Text files read by FreeBASIC and compiled into executable code.

A source file is a text file that contains FreeBASIC language statements.  
A program might be made from just one source file or possibly hundreds.  
Source files are read by the compiler and compiled into object code.  
Object code is then linked to create an executable or can be stored for 
later use as a library.

FreeBASIC by default, automatically takes care of compiling sources and 
linking object modules in to executables, so normally it is possible to 
make an executable program by just passing the names of the source files on 
the fbc command line.  For example, assuming we had three source files that 
together made a program, we could create an executable for the program by 
running fbc, the FreeBASIC compiler on a command line as follows:

   fbc myprog.bas tools.bas funcs.bas

Unicode support
   * Besides ASCII files with Unicode escape sequences (\u), FreeBASIC can 
     parse UTF-8, UTF-16LE, UTF-16BE, UTF-32LE and UTF-32BE source (.bas) 
     or header (.bi) files as long as they were saved with Byte Order Mark 
     (BOM), they can be freely mixed with other sources/headers in the same 
     project (also with other ASCII files).
   * Unicode files must be saved with Byte Order Mark (BOM), otherwise fbc 
     does not recognize them as Unicode.
   * Literal strings can be typed in the original non-Latin alphabet, just 
     use a text-editor that supports one of the Unicode formats listed 
     above.

Implicit main()
   Some languages require a special main() procedure be defined as an entry 
   point to the program which define the first statements that will be 
   executed when the program starts.  FreeBASIC allows executable 
   statements in module level code and normally the first source file 
   passed to fbc on the command line will be used as the "main" module.  
   The main module can be explicitly names by passing -m filename on the 
   command line, where filename is the name of the main module without the 
   .bas extension.
      '' sample.bas
      Declare Sub ShowHelp()

      '' This next line is the first executable statement in the program
      If Command(1) = "" Then
         ShowHelp
         End 0
      End If   

      Sub ShowHelp()
         Print "no options specified."   
      End Sub

Header Files
   A header file is a special kind of source file that typically only 
   contains declarations and has a .bi extension. See Header Files (.bi).

See also
   * fbc command-line
   * Header Files (.bi)



------------------------------------------------------ ProPgHeaderFiles ----
Header Files (.bi)

Provides an interface for a module.

A header file is a special kind of source file that typically only contains 
preprocessor statements, defines, declarations, prototypes, constants, 
enumerations, or similar types of statements, however, a header file can 
contain any valid source code if the purpose suits.  What makes them 
different from other module (.bas) source files, is instead of being 
compiled directly, they are included by another source file (module or 
header) using the #include preprocessor directive.  All compiled libraries 
typically have one or more header files that can be included in another 
source file and will introduce to the compiler all the names of the 
procedures usable in a particular library.

FreeBASIC Header Files
   Some of the keywords, constants, and procedures documented in this 
   manual are not normally available when compiling a source code unless a 
   specific header file is included in the source first.
   * datetime.bi
   * dir.bi
   * fbgfx.bi
   * file.bi
   * string.bi
   * vbcompat.bi

Case Sensitivity
   Although the FreeBASIC language itself is not case-sensitive, the file 
   system on which it is running might be.  If a header file can not be 
   found, check that FreeBASIC is searching for it the correct location and 
   ensure that name of both the directory and filename of the header file 
   specified in the #include statement is using the correct upper and lower 
   case letters.

Path Separators
   FreeBASIC will automatically switch backslash ( \ ) and forward slash ( 
   / ) characters as needed for a given platform.  This allows source code 
   to be easily cross compatible.

Including a header only once
   It is common that header files need to #include other header files to 
   compile correctly.  FreeBASIC offers three methods for guarding against 
   including a header file more than once.
   * #ifndef guards in the header file
   * #include Once where the file is included
   * #pragma Once in the header file itself

#ifndef guards in the header file
   The use of #ifndef and #define is a common practice in nearly any 
   language that supports preprocessing.  The first time a file is 
   included, a unique symbol is defined.  The next time the same header 
   file is included, the definition of the symbol is checked, and if it is 
   already defined, the contents of the header file are skipped.
   '' header.bi
   #ifndef __HEADER_BI__
   #define __HEADER_BI__

   #print These statements will only be included Once,
   #print even though header.bi might be included more 
   #print than Once in the same source file.

   #endif

#include once
   At the point in the source code where the header file is included, the 
   optional "once" specifier of the #include directive can tell the 
   compiler to only include the source file one time.
   '' header.bi
   #include Once "fbgfx.bi"

   '' module.bas
   #include Once "fbgfx.bi"
   #include Once "header.bi"

#pragma once
   #pragma Once can be used in a header file to indicate that the header 
   file should only be included once.  
   '' header.bi
   #pragma Once
   #print This header will only ever be included Once per module

See also
   * Source Files (.bas)
   * Header Files Index



------------------------------------------------ ProPgPrebuiltLibraries ----
Using Prebuilt Libraries

FreeBASIC is distributed with many headers for common or popular libraries. 
The headers allow a programmer to use functions available in these existing 
static or shared libraries (DLLs).  

The libraries themselves are not distributed with FreeBASIC, but most can 
be downloaded from the web and readily installed.  Some other libraries may 
need to be first compiled from sources to be used.  Please see the 
documentation for the specific library on how to configure, install, and 
use them.
Note that the system architecture of the library has to match the 
architecture of the application. For example, to successfully use a library 
in a x86 (32-bit) application, a x86 (32-bit) library is required.

Some static or shared libraries (DLLs) may be already present on the system 
since they might be part of FreeBASIC itself or the operating system.

Although many headers can be used on any of the platforms supported by FreeB
ASIC, some headers are platform specific and will not be usable on other 
platforms.

FreeBASIC headers
   There are a few headers that are specific to FreeBASIC and expose some 
   functions that are otherwise not available:
   * datetime.bi - Declarations for DateSerial, DateValue, IsDate, Year, 
     Month, Day, Weekday, TimeSerial, TimeValue, Hour, Minute, Second, Now, 
     DateAdd, DatePart, DateDiff, MonthName, WeekdayName
   * dir.bi - Constants to be used with Dir
   * fbgfx.bi - Additional constants and structures to be used with 
     graphics commands such as MultiKey,  ScreenControl, and ScreenEvent, 
     ImageCreate.
   * file.bi - Declarations for FileCopy, FileAttr, FileLen, FileExists, 
     FileDateTime
   * string.bi - Declarations for Format
   * vbcompat.bi - Includes datetime.bi, dir.bi, file.bi, and string.bi 
     plus additional constants compatible with Microsoft Visual Basic.

C Runtime (CRT)
   Where possible cross-platform compatible headers have been provided for 
   the C runtime (CRT).  For example,
   #include Once "crt.bi"
   printf( !"Hello World\n" )

   To include a specific CRT header, prefix the name of the header file 
   with "crt/".  For example:
   #include Once "crt/stdio.bi"
   Dim f As FILE Ptr
   f = fopen("somefile.txt", "w")
   fprintf( f, "Hello File\n")
   fclose( f )

Windows API
   Many (many) headers for the Windows API are available for inclusion in 
   FreeBASIC source code.  In most cases the only include file needed is 
   "windows.bi".  For example,
   #include Once "windows.bi"
   MessageBox( null, "Hello World", "FreeBASIC", MB_OK )

   To include a specific Windows API header, prefix the name of the header 
   with "win/" for example:
   #include Once "win/ddraw.bi"

   Browse the "inc/win/" directory where FreeBASIC was installed to see all 
   of the available Windows API headers.

Other Headers Provided
   See the External Libraries Index for an overview of the additional 
   headers shipped with FreeBASIC.  The page also describes the file(s) 
   that need to be included to use the library.  Alternatively one can 
   browse the "inc/" directory located where FreeBASIC was installed to 
   find other headers.  It is possible that headers might be available for 
   a library you need to use.  Some headers are located in "inc/" and 
   others might be located in a sub-directory.  To include headers located 
   in a subdirectory of "inc/", prefix the name of the header with the name 
   of the directory where it is located.  For example:
   '' located at inc/curl.bi
   #include Once "curl.bi"

   '' located at inc/GL/gl.bi
   #include Once "GL/gl.bi"

Requirements for Using Prebuilt Static Libraries
   * The source code must include the appropriate headers using #include.
   * The static library must be linked at compile time by using either 
     #inclib in the source code or by using the -l option on the command 
     line to specify the name of the library.

Requirements for Using Prebuilt Shared Libraries
   * The source code must include the appropriate headers using #include.
   * The shared library (.DLL) must be present on the host computer where 
     the compiled program will run.

See also
   * Static Libraries
   * Shared Libraries (DLLs)




============================================================================
    Lexical Conventions

--------------------------------------------------------- ProPgComments ----
Comments

Comments are regions of text that the compiler will ignore but may contain 
information that is useful to the programmer.  One exception are 
metacommands which may appear in certain types of comments.

Single Line comments
   The single quote character (') may be used to indicate a comment and may 
   appear after other keywords on a source line.  The rest of the statement 
   will be treated as a comment.
   ' comment text

The comment statement: Rem
   A source code statement beginning with Rem indicates that the line is 
   comment and will not be compiled.  In FreeBASIC, Rem may also appear 
   after other keywords on a source line and the behavior is the same as 
   above (only the rest of the statement will be treated as a comment).
   Rem comment

Multi-line comments
   Multi-line comments are marked with the tokens /' and '/.  All text 
   between the two markers is considered comment text and is not compiled.

   Multi-line comments can span several lines, and can also be used in the 
   middle of statements.  After the end of the comment, the statement will 
   continue to be parsed as normal (even if the comment crosses line 
   breaks).
   /' Multi-line
      comment '/

   Print "Hello" /' embedded comment'/ " world"

   Note: If FreeBASIC encounters a close-comment marker while it's not in a 
   multi-line comment, it will treat it as a normal single-line comment due 
   to the single quote.

Nested Comments
   A multi-line comment can contain other multi-line comments inside it.  
   Each inner comment has its own open- and close-comment markers.

   /'
   	This is a comment.
   	/'
   	 This is a comment inside a comment
   	'/
      This Is a comment.
   '/

   A multi-line comment can contain unlimited levels of nested comments.  
   FreeBASIC will continue to parse the multi-line comment for more markers 
   until the number of close-comment markers reaches the number of 
   open-comment markers, i.e. when it has closed all the comments it has 
   opened.

Comments after line continuation
   A single-line comment may appear after the line continuation character ( 
   _ ) in a multi-line statement.  FreeBASIC does not parse the text after 
   the line continuation character, though, so you can't open multi-line 
   comments after them.

   Print _ ' line
      "This is part of the previous line's statement"

Metacommands
   Metacommands, such as $Static and $Include, can be placed in single-line 
   comments.  The $ sign and the keyword must be the first two things in 
   the statement, not including white space.

   Rem compile With -lang fblite Or qb

   #lang "fblite"

   Rem $Static
   ' $include: 'vbcompat.bi'

Single-line comment parsing
   When you make a single-line comment, FreeBASIC will parse the comment, 
   to check for a metacommand.  If it finds a multi-line comment, it will 
   treat it as usual, and continue parsing the single-line comment after 
   the close-comment marker.

   If you want to prevent FreeBASIC parsing the single-line comment, put 
   another single quote ('), at the start of the comment.  FreeBASIC will 
   treat the rest of the line, including multi-line comment markers and 
   metacommands, as ordinary text, and will ignore it.  Other words 
   encountered in a comment will also stop the parsing.
      *Note: As of version 0.21.0, this will not longer apply in the 
        -lang fb dialect, and multi-line comment markers will be completely 
        ignored inside single-line comments

   '' $static <-- will not get parsed
   '' this multiline comment marker ("/'") will be ignored
   Print "This line is not a comment."

Example
   /' this is a multi line 
   comment as a header of
   this example '/

   Rem This Is a Single Line comment

   'this is a single line comment

   Dim a As Integer   'comment following a statement

   Dim b As /' can comment in here also '/    Integer

   #if 0
      before version 0.16, This was the
      only way of commenting Out sections
      With multiple lines of code.
   #endif

See also
   * Rem



-------------------------------------------------- ProPgIdentifierRules ----
Identifier Rules

Naming conventions for FreeBASIC symbols.

Description
   An identifier is a symbolic name which uniquely identifies a variable, 
   Type, Union, Enum, Function, Sub, or Property, within its scope or 
   Namespace.

   Identifiers may contain only uppercase and lowercase Latin characters a-
   z and A-Z), digits (0-9), and the underscore character (_). The first 
   character of an identifier must be a letter or underscore, not a digit.

   Identifiers are case-insensitive: FOO and foo (and all other 
   permutations of uppercase and lowercase) refer to the same symbol.

   In the -lang qb and -lang fblite dialects, identifiers may have a type 
   suffix at the end indicating one of the standard data types:

   * % for Integer
   * & for Long
   * ! for Single
   * # for Double
   * $ for String

   The use of these symbols is generally discouraged in and is not allowed 
   in the -lang fb dialect (the default).

   The alternative is to be explicit - for example, Dim As Integer foo or 
   Dim foo As Integer instead of Dim foo%.

   In the -lang qb and -lang fblite dialects, identifiers may contain one 
   or more periods (.).

Dialect Differences
   * Periods in symbol names are only supported in the -lang qb and 
     -lang fblite dialects.

Differences from QB
   * Support for the underscore character (_) in symbol names is new to 
     FreeBASIC.

See also
   * Variables



--------------------------------------------------------- ProPgLiterals ----
Literals

Non-variable compile-time string, numeric values and boolean values.

Literals are numbers, strings of characters or boolean truths specified 
directly in the source code.  Literal values may be used by assigning them 
to a variable or constant, passing them to a procedure, or using them in an 
expression.

Numeric literals come in two forms - integer and floating-point.  

Integer Literals

   Decimal
   Decimal digits ( 0 1 2 3 4 5 6 7 8 9 ).
   Note: to get negative values, a "-" sign (Operator - (Negate)) can be 
   placed before a numeric literal

   Dim x As Integer = 123456
   Dim b As Byte = -128

   Hexadecimal
   "&H", followed by hexadecimal digits ( 0 1 2 3 4 5 6 7 8 9 A B C D E F 
   ).

   Dim x As Integer = &h1E240
   Dim b As Byte = &H80

   Octal
   "&O" ( O as in "Octal" ), followed by octal digits ( 0 1 2 3 4 5 6 7 )

   Dim x As Integer = &O361100
   Dim b As Byte = &O200

   Binary
   "&B", followed by binary digits ( 0 1 )

   Dim x As Integer = &B11110001001000000
   Dim b As Byte = &B10000000

Integer size suffixes
   If an integer literal suffix is not given, the number field size 
   required to hold the literal is automatically calculated.  Specifying a 
   size suffix guarantees that the compiler will consider a number as a 
   specific integer size.

   Integer literals ending with:
   * "%", are considered as signed 32/64 (depending on platform) bit 
     integers. (Integer)
   * "L", "&", are considered as signed 32 bit long integers. (Long)
   * "U", are considered as unsigned 32/64 (depending on platform) bit 
     integers. (UInteger)
   * "UL", are considered as unsigned 32 bit integers. (ULong)
   * "LL", are considered as signed 64 bit integers. (LongInt)
   * "ULL", are considered as unsigned 64 bit integers. (ULongInt)

   Negative (-) and positive (+) signs that prefix a numeric literal, are 
   not part of the numeric literal.  expressions (like "-1L") are parsed as 
   the negate operator applied to the value represented by the positive 
   literal ("1L"), which may involve implicit type conversions.  Same 
   behavior when an explicit "+" sign precedes the integer literal.

   The prefixes, suffixes, and hexadecimal letter digits are all 
   case-insensitive.

   Dim a As Long = 123L
   Dim b As UInteger = &h1234u
   Dim c As LongInt = 76543LL
   Dim d As ULongInt = &b1010101ULL

Floating Point Literals
   Floating point numbers are specified in decimal digits, may be positive 
   or negative, have a fractional portion, and optionally an exponent.  The 
   format of a floating point literal is as follows (without space or 
   parenthesis added):

   number[.[fraction]][(D|E)[+|-][exponent]][suffix]
   or
   .fraction[(D|E)[+|-][exponent]][suffix]

   By default, floating point numbers that do not have either an exponent 
   or a suffix are considered as a double precision floating point value, 
   except in the -lang qb dialect, where numbers of 7 digits or fewer are 
   considered to be single precision.
   Dim a As Double = 123.456
   Dim b As Double = -123.0

   The letter "D" or "E", placed after the number/fraction part, allows the 
   number to be given an exponent.  The exponent may be specified as either 
   positive or negative with a plus ("+") or minus ("-") sign.  Exponents 
   that do not have a sign are positive.
   An exponent value is not required after the letter (or even after the 
   sign), so the letter can be used on its own just to specify the type.  "
   D" specifies a double-precision floating-point number.  "E" specifies a 
   floating-point number using the default precision. When the letter is 
   used on its own in combination with a suffix (see below) the type 
   denoted by the suffix overrules the type specified by the letter.

   Dim a As Double = -123.0d
   Dim b As Double = -123e
   Dim c As Double = 743.1e+13
   Dim d As Double = 743.1D-13
   Dim e As Double = 743.1E13
   Dim f As Single = 743D! 

   A suffix of "!" or "F" on a number specifies a single precision (32 bit 
   total) floating point value.  A suffix of "#" or "D" specifies a double 
   precision float.
   Note that the letter suffixes and exponent specifiers are all 
   case-insensitive.

   Dim a As Single = 3.1!
   Dim b As Single = -123.456e-7f
   Dim c As Double = 0#
   Dim d As Double = 3.141592653589e3#

String Literals
   String literals are a sequence of characters contained between two 
   double quotes.  The sequence of characters escaped or non-escaped.

   Double quotes can be specified in the string literal by using two double 
   quotes together.
   Print "Hello World!"
   Print "That's right!"
   Print "See the ""word"" contained in double quotes."

   String literals can contain escape sequences if the string literal is 
   prefixed by the ! Operator (Escaped String Literal).  See 
   Escape Sequences for a list of accepted escape sequences.
   Print !"Hello\nWorld!"

   By default, string literals are non-escaped unless Option Escape was 
   used in the source in which case all string literals following are by 
   default escaped.

   A string may be explicitly specified as non-escaped when prefixed by the 
   $ Operator (Non-Escaped String Literal).
   Print $"C:\temp"

   Besides ASCII files with Unicode escape sequences (\u), FreeBASIC can 
   parse UTF-8, UTF-16LE, UTF-16BE, UTF-32LE and UTF-32BE source files as 
   long as they were saved with Byte Order Mark (BOM), allowing unicode 
   characters directly in the string literal.

   String literals in an ASCII file are treated as ZString, while string 
   literals in a Unicode file are treated as WString (regardless of the 
   string literal's value).

Boolean Literals
   The boolean type has two values, represented by literals True and False.

   Dim a As Boolean = False
   Dim b As Boolean = True

	

See also
   * TypeOf
   * #define
   * Const 
   * Standard Data Types
   * Table with variable types overview, limits and suffixes



----------------------------------------------------------- ProPgLabels ----
Labels

Defines a location in a program.

Syntax
   symbolname :
      or
   literalnumber

Description
   Defines a place in a program where Goto or GoSub can jump to.

   A label can be a positive integer line number or a symbolname. In both 
   cases, the label must start at the first column of line. A symbolname 
   label must end with a colon (:) character.

Example
   '' Compile with -lang fblite or qb

   #lang "fblite"

   beginning:
   3 Print "Hello World!"
   Goto beginning

   '' compile with -lang qb

   '$lang: "qb"

   '' Labels can be used to "bookmark" DATA blocks, allowing RESTORE to alter the READ sequence.
   Read a,b,c
   Restore here
   Read d,e
   Print a,b,c,d,e 

   Data 1,2,3,4,5
   here:
   Data 6,7,8

Output:

   1,2,3,6,7

Dialect Differences
   * Line numbers with decimals is available only in the -lang qb dialect.

Differences from QB
   * None if compiled in the -lang qb dialect.

See also
   * GoSub
   * Goto



------------------------------------------------- ProPgLineContinuation ----
Line continuation

A single _ (underscore) character at the end of a line of code tells the 
compiler that the line continues in the next line. This allows a single 
statement (line of code) to be spread across multiple lines in the input 
file, which can be a nice formatting help.

   '' This Dim statement is spread across multiple lines, using the '_' character
   Dim myvariable _
   As Integer

This is often used to make very long lines of code easier to read, for 
example procedure declarations with a lot of parameters:

   '' Here's an example:

   Declare Sub drawRectangle( ByVal x As Integer, ByVal y As Integer, ByVal w As Integer, ByVal h As Integer )

   '' which can also be written as:

   Declare Sub drawRectangle( ByVal x As Integer, ByVal y As Integer, _
                        ByVal w As Integer, ByVal h As Integer )

   '' or:

   Declare Sub drawRectangle _
      ( _
         ByVal x As Integer, _
         ByVal y As Integer, _
         ByVal w As Integer, _
         ByVal h As Integer _
      )

   '' (or any other formatting you like)

The _ line continuation character can be inserted at pretty much any point 
in a line of code. It does not work inside comments though.

Be careful when adding the _ line continuation character right behind an 
identifier or keyword. It should be separated with at least one space 
character, otherwise it would be treated as part of the identifier or 
keyword.

   '' Declare variable "a_"
   '' (no line continuation happening, because the '_' character is part of
   '' the "a_" identifier)
   Dim As Integer a_

   '' Declare variable "a" and initialize to value 5
   '' (line continuation happening, because the '_' character
   '' was separated from the identifier "a" with a space character)
   Dim As Integer a _
   = 5

Warning: When an erroneous code line is spread over a multiple lines block 
by using the _ line continuation character, the error message refers only 
to the last line of the block.




============================================================================
    Variables and Datatypes

--------------------------------------------------- ProPgDataConversion ----
Coercion and Conversion

Transfer the data of a given type variable to a variable of another type 
requires conversion.

Coercion of Numeric Data Types in Expressions and Arguments

For the integer types, the rule depends on the following ranking:
      in 32bit:
         byte < ubyte < short < ushort < long < integer < ulong < uinteger 
         < longint < ulongint
      in 64bit:
         byte < ubyte < short < ushort < long < ulong < longint < integer < 
         ulongint < uinteger
First,  in accordance to the above ranking, all arguments smaller than 
Integer are converted to Integer.
Then, if arguments have different size, the smaller argument is converted 
to match the bigger one. Next, if arguments have different signedness, the 
signed argument is converted to unsigned to match the other one.
Finally, the (U)Integer types replace:
      in 32bit:
         the (U)Long types
      in 64bit:
         the (U)Longint types

On the other hand, if one of the arguments is a Single or a Double, both 
arguments are converted and/or promoted to Double.

Conversion of Numeric Data Types

A type conversion will occur implicitly when an expression or variable is 
assigned, passed as a parameter to a procedure, or returned as a result 
from a procedure. Conversions may also be explicit when using CAST or one 
of the built-in conversion functions (among standard functions).

Integer To Integer, any combination of Signed and Unsigned
   * Any integer type to a smaller integer type: least significant bits 
     are retained
   * Any integer type to a larger integer type: sign extended to fill most 
     significant bits

Integer to Single or Double
   * Possible loss of precision

Double to Single
   * Possible loss of precision
   * If the value of the Double exceeds the range of a Single result is 
     +/- INF

Double or Single to Integer
   * Possible loss of precision
   * If the value of the floating point number exceeds the range of the 
     target type are results are undefined.  A run-time error is not 
     raised.

Conversions using User Data Type constructors and operators

For conversion between built-in types (among standard types like between 
numeric types as above or between string types), the compiler knows what to 
do without the need for instructions from user.
This is called the implicit internal conversion (or coercion).

When one of the two types is at least a UDT (User Defined Type), the user 
has to code some UDT procedures to define how do the conversion.
Then, the conversion execution can be explicit if the user specifies what 
UDT procedure must be used, or implicit if the user leaves the choice to 
compiler.

In the world of UDTs, conversions can be controlled by means of three 
member procedures:
   * Single-argument constructor: allow conversion from a particular type 
     to initialize an object.
   * Assignment operator: allow conversion from a particular type on 
     assignment.
   * Type-cast operator: allow conversion to a particular type.

For a construction with implicit initialization, the compiler searches:
   * Firstly a matched constructor.
   * Then otherwise a matched cast operator.
   (a matched let operator is not searched by compiler on a construction 
   with implicit initialization)

For an implicit assignment, including an implicit return from function by 
assigning (keyword 'Function ='), the compiler searches:
   * Firstly a matched let operator.
   * Then otherwise a matched cast operator.
   (a matched constructor is not searched by compiler on an implicit 
   assignment)

For an implicit return from function by exiting immediately (keyword 
'Return'), the compiler searches:
   * Firstly a matched constructor.
   * Secondly a matched let operator.
   * Then otherwise a matched cast operator.

Example
Very simple syntaxic example highlighting the conversion capabilities by 
using Cast operator (explicit and implicit), Constructor (explicit and 
implicit) and Let operator (implicit):
   Type UDT
     Dim As Integer I
     Declare Operator Cast () As Integer
     Declare Constructor (ByVal I0 As Integer)
     Declare Operator Let (ByVal I0 As Integer)
   End Type

   Operator UDT.Cast () As Integer
     Return This.I
   End Operator

   Constructor UDT (ByVal I0 As Integer)
     This.I = I0
   End Constructor

   Operator UDT.Let (ByVal I0 As Integer)
     This.I = I0
   End Operator

   Dim As Integer J = 12
   Dim As UDT u1 = UDT(J)  '' construction with explicit initialization using the defined "Constructor(Byval As Integer)" operator
   Print u1.I
   Dim As UDT u2 = J       '' construction with implicit initialization by compiler using the defined "Constructor(Byval As Integer)" operator
   Print u2.I
   Print

   u1.I = 34
   J = Cast(Integer, u1)  '' explicit assignment using the defined "Cast() As Integer" operator
   Print J
   Dim As Integer K
   K = u1                 '' implicit assignment by compiler using the defined "Cast() As Integer" operator
   Print K
   Print

   J = 56
   u1 = J                 '' implicit assignment by compiler using the defined "Let(Byval As Integer)" operator
   Print u1.I
   Print

   Sleep

See also
   * Standard Data Types
   * Variable Types
   * Casting and Conversion Functions
   * User Defined Types



-------------------------------------------------------- ProPgConstants ----
Constants

Description
   Constants are numbers (including booleans) or strings which cannot be 
   changed after they are defined. For example, 5 will always mean the same 
   number.

   In FreeBASIC, a constant definition differs from a variable definition 
   by usage of the Const command.

   Such constants are then available globally, meaning that once defined, 
   you can use the word to refer to a constant anywhere in your program. 

   After being defined with the Const command, constants cannot be altered. 
   If code tries to alter a constant, an error message will result upon 
   code compilation.

Example
   Declare Sub PrintConstants ()

   Const FirstNumber = 1
   Const SecondNumber = 2
   Const FirstString = "First string."
   Const FirstBoolean = False
   Const SecondBoolean = True

   Print FirstNumber, SecondNumber 'This will print 1      2
   Print FirstString 'This will print First string.
   Print FirstBoolean, SecondBoolean 'This will print false      true
   Print

   PrintConstants ()

   Sub PrintConstants ()
      Print FirstNumber, SecondNumber 'This will also print 1        2
      Print FirstString 'This will also print First string.
      Print FirstBoolean, SecondBoolean 'This will also print false      true
   End Sub

See also
   * Const
   * Enum



-------------------------------------------------------- ProPgVariables ----
Variables

Symbols representing data in memory.

Description
   Variables are name symbols which can be manipulated. They are declared 
   and referenced using names composed of letters, numbers, and character 
   "_". These reference names cannot contain most other symbols because 
   such symbols are part of the FreeBASIC programming language. They also 
   cannot contain spaces.  See Indentifier Rules.

   In FreeBASIC, variables can be defined using the Dim statement. 

   Variables are available for later access depending on where and how the 
   Dim declaration for that variable is given.  Depending on the scope of a 
   variable, a defined variable can be available within the main area of a 
   program, within a procedure, through an entire module, or through out an 
   entire program.  See Variable Scope.

   Variables are also made available when they are passed as parameters to 
   a procedure such as Function or Sub.

   After a variable is declared with the Dim statement, they can be 
   assigned, passed to procedures, and used in expressions wherever their 
   Standard Data Type is similar.  Sometimes variables are automatically 
   converted to other data types before being used in expressions, or 
   passed as parameters to procedures.  See Coercion and Conversion.

Example
   ' compile with -lang qb or fblite

   '$lang: "qb"

   Declare Sub PrintConstants()

   Dim FirstNumber As Integer
   Dim Shared SecondNumber As Integer

   FirstNumber = 1
   SecondNumber = 2

   PrintConstants ()
   Print FirstNumber, SecondNumber, ThirdNumber 'This will print 1 2 0

   Sub PrintConstants ()
      Dim ThirdNumber As Integer
      ThirdNumber = 3
      Print FirstNumber, SecondNumber, ThirdNumber 'This will print 0 2 3
   End Sub

See also
   * Coercion and Conversion
   * Dim
   * Identifier Rules
   * Variable Scope




============================================================================
    Arrays

----------------------------------------------------------- ProPgArrays ----
Arrays

Multi-dimensional container types.

Overview
   Arrays are special kinds of variables which act as containers for a 
   number of values, or elements. An array can store elements of any type, 
   and all of its elements share the same type. For example, an array can 
   store Integer elements or Single elements, but not both. These elements 
   are accessed--read from or written to--through an Integer value 
   representing their position in the array. Arrays have lengths, or sizes, 
   which are equal to the number of elements they are storing at any given 
   time. Fixed-length arrays have constant sizes throughout their 
   lifetimes, while the sizes of variable-length arrays can change 
   dynamically.

Elements and positions
   The values that an array stores are its elements. Each element of an 
   array has a corresponding position, which is an Integer value ranging 
   from the array's lower bound to its upper bound, inclusive. These 
   positions are used to access individual elements in the array using 
   Operator (), which takes a position and returns a reference to the 
   element at that position. A valid position in an array is greater than 
   or equal to its lower bound, and less than or equal to its upper bound.

   ' Create an array of 3 elements all having the value zero (0.0f).
   Dim array(1 To 3) As Single

   ' Assign a value to the first element.
   array(1) = 1.2

   ' Output the values of all the elements ("1.2 0 0").
   For position As Integer = 1 To 3
      Print array(position)
   Next

Sizes and bounds
   The size of an array is equal to the number of elements it stores at any 
   given time. An array can have a size of zero (0), meaning it's not 
   storing any values at the moment--it's empty. If an array's size is 
   greater than zero, that many elements are being stored. An array's size 
   is equal to one more than the difference between its upper and lower 
   bounds, or UBound(array) - LBound(array) + 1.

   The lower and upper bounds not only determine the size of an array, but 
   also the valid positions of individual elements. For example, an array 
   with a lower bound of zero (0) and an upper bound of four (4), stores 
   five (5) elements, the first element being at position 0, the last at 
   position 4. These bounds may be specified when the array is declared, 
   or, for some arrays, changed by resizing the array. An array's lower and 
   upper bounds can be retrieved using LBound and UBound, respectively.

   When creating or resizing an array, if a lower bound is not specified it 
   defaults to zero (0).

   ' Declares and initializes an array of four integer elements.
   Dim array(3) As Integer = { 10, 20, 30, 40 }

   ' Outputs all of the element values (" 10 20 30 40").
   For position As Integer = LBound(array) To UBound(array)
      Print array(position) ;
   Next

Fixed-length and variable-length
   There are two fundamental kinds of arrays: fixed-length and 
   variable-length. The primary difference between the two is that the 
   bounds of fixed-length arrays can never change, that is, they always 
   store the same number of elements in the same positions. Variable-length 
   array bounds can be changed, affecting the number of elements stored 
   and/or the positions of the elements.

   Since fixed-length arrays never change size, the compiler chooses to 
   make room for--or, allocate--the memory for the array elements either in 
   static storage or on the program stack, depending on the array's 
   storage class. This can be an advantage, since the cost of creating 
   these kinds of arrays doesn't include any adverse run-time penalty. 
   Fixed-length arrays are declared using Extern, Static and Dim. At least 
   an upper bound must be specified, and all bounds must be compile-time 
   constant values, such as numeric literals, Const variables or Enum 
   enumerators.

   Variable-length arrays can change in size, so the compiler chooses to 
   allocate the memory for the array elements at run-time, in the free 
   store. The advantage here of course is being able to dynamically resize 
   the arrays, however, run-time performance could vary when they are 
   created, resized or destroyed. Variable-length arrays are declared using 
   Extern, Static, Dim and ReDim. When using Extern, Static or Dim, the 
   lower and upper bounds can be left unspecified--resulting in an empty 
   array--or either one must have a variable value, such as an Integer 
   variable or Function result. ReDim can be used to resize an existing 
   variable-length array, by giving it different lower and/or upper bounds.

   ' Creates a fixed-length array that holds 5 single elements.
   Const totalSingles = 5
   Dim flarray(1 To totalSingles) As Single

   ' Creates an empty variable-length array that holds integer values.
   Dim vlarray() As Integer

   ' Resizes the array to 10 elements.
   ReDim vlarray(1 To 10)

Multi-dimensional arrays
   The arrays discussed so far have been one-dimensional, that is, the 
   elements are accessed through a single position. One-dimensional arrays 
   can be thought of as a simple row of elements. Arrays can also have more 
   than one dimension; an individual element of the array is accessed using 
   two or more positions. Two-dimensional arrays use two positions--a row 
   and a column position--to refer to individual elements, like a grid or 
   table. Three-dimensional arrays use three positions--a row, column and 
   perhaps depth position--to refer to individual elements, like a cube. 
   Four-dimensional arrays can be thought of as one or more 
   three-dimensional arrays, and so on. Multi-dimensional arrays are 
   declared just like one-dimensional arrays, except that more than one 
   lower and upper bound range is specified.

   ' Take Care while initializing multi-dimensional array
   Dim As Integer multidim(1 To 2,1 To 5) = {{0,0,0,0,0},{0,0,0,0,0}}

See also
   * Fixed-length Arrays
   * Variable-length Arrays
   * Array Indexing
   * Passing Arrays to Procedures
   * Variable Scope



----------------------------------------------------- ProPgFixLenArrays ----
Fixed-length Arrays

Fixed-size homogeneous data structures.

Overview
   Fixed-length arrays are arrays that have a fixed constant size 
   throughout the execution of a program. The memory used by a fixed-length 
   array to store its elements is allocated at compile-time, either on the 
   stack or in the .BSS or .DATA sections of the executable, depending on 
   whether Static (or Shared) was used to define it. This may allow for 
   quicker program execution since the memory for the array is already 
   allocated, unlike variable-length arrays, whose element memory isn't 
   allocated until runtime.

   Fixed-length arrays with automatic storage, have their elements 
   allocated on the program stack, and pointers to these elements remain 
   valid only while the array is in scope. The elements of fixed-length 
   arrays with static storage are allocated in the .DATA or .BSS sections 
   of the executable, depending on whether or not they are initialized when 
   defined, so pointers to these elements remain valid for the entire 
   execution of the program. Fixed-length arrays of any storage class 
   cannot be resized during program execution, only variable-length arrays 
   can.

   Fixed-length arrays may also be used as data members inside 
   user-defined types, in which case the array is directly allocated as 
   part of the user-defined type structure.

Declaration
   A fixed-length array is declared with either the Dim or Static keywords, 
   followed by a variable identifier, a parenthesized list of boundaries 
   and an element data type.

   '' Defines a one-dimensional fixed-length array of type INTEGER having automatic storage.
   Dim arrayOfIntegers(69) As Integer

   '' Defines a one-dimensional fixed-length array of type SHORT having static storage.
   Static arrayOfShorts(420) As Short

   There are various ways to specify an array's amount of elements. Each 
   array can have between 1 or 8 dimensions. Each dimension has a lower 
   bound and an upper bound.

   Dim a(1) As Integer  '' 1-dimensional, 2 elements (0 and 1)
   Dim b(0 To 1) As Integer  '' 1-dimensional, 2 elements (0 and 1)
   Dim c(5 To 10) As Integer  '' 1-dimensional, 5 elements (5, 6, 7, 8, 9 and 10)

   Dim d(1 To 2, 1 To 2) As Integer  '' 2-dimensional, 4 elements: (1,1), (1,2), (2,1), (2,2)
   Dim e(9, 9, 9, 9) As Integer '' 4-dimensional, 10 * 10 * 10 * 10 elements

   For an array to be declared fixed-length, the boundaries must be 
   specified using only number literals or Const values or Enum constants.

   Const myLowerBound = -5
   Const myUpperBound = 10

   '' Declares a one-dimensional fixed-length array, holding myUpperBound - myLowerBound + 1 String objects.
   Dim arrayOfStrings(myLowerBound To myUpperBound) As String

   '' Declares a one-dimensional fixed-length array of bytes,
   '' big enough to hold an INTEGER.
   Dim arrayOfBytes(0 To SizeOf(Integer) - 1) As Byte



----------------------------------------------------- ProPgVarLenArrays ----
Variable-length Arrays

Resizable homogeneous data structures. Also known as "dynamic arrays".

Overview
   Variable-length arrays are arrays that can, during program execution, 
   either be resized to hold more or less elements, or have their 
   dimension[s] use a different subscript range. The memory used by a 
   variable-length array to store its elements is allocated at runtime in 
   the heap, as opposed to fixed-length arrays whose data is either 
   allocated on the program stack or in the .BSS or .DATA sections of the 
   executable, depending on whether they were defined with Static (or Shared
   ).

   Variable-length arrays may also be used as data members inside 
   user-defined types. As opposed to fixed-length arrays though, the array 
   is not allocated as part of the user-defined type structure, because 
   user-defined types cannot be variable-length. Instead, the user-defined 
   type only contains the array descriptor that is used to hold and access 
   the variable-length array behind the scenes, and the array is still 
   allocated on the heap, as with variable-length array variables.

   Variable-length arrays are often called "dynamic arrays" because their 
   size can change dynamically at runtime, instead of being fixed-size.

Declaration
   A variable-length array is declared with either the Dim or ReDim 
   keywords, followed by a variable identifier, a parenthesized list of 
   boundaries and an element data type. For an array to be declared 
   variable-length, it must be declared with unknown boundaries, or with 
   variable (non-constant) boundaries. ReDim always defines variable-length 
   arrays, whether the specified boundaries are constant or not.

   '' Declares a one-dimensional variable-length array of integers, with initially 2 elements (0 and 1)
   ReDim a(0 To 1) As Integer

   '' Declares a 1-dimensional variable-length array without initial bounds.
   '' It must be resized using Redim before it can be used for the first time.
   Dim b(Any) As Integer

   '' Same, but 2-dimensional
   Dim c(Any, Any) As Integer

   Dim myLowerBound As Integer = -5
   Dim myUpperBound As Integer = 10

   '' Declares a 1-dimensional variable-length array by specifying variable (non-constant) boundaries.
   '' The array will have myUpperBound - myLowerBound + 1 elements.
   Dim d(myLowerBound To myUpperBound) As Integer

   '' Declares a variable-length array whose amount of dimensions will be determined
   '' by the first Redim or array access found. The array has no initial bounds and must
   '' be resized using Redim before it can be used for the first time.
   Dim e() As Integer

Resizing
   Resizing a variable-length array refers to "redefining" the array with 
   different boundaries, allowing the array to grow or shrink. Elements 
   outside the new subscript range[s] are erased; object elements will be 
   destroyed. If the array is resized to a larger size, new elements are 
   added initialized with a zero or null value; object elements are 
   default-constructed. Variable-length arrays are resized using the ReDim 
   keyword following the same form as definition. In this case the element 
   data type may be omitted from the ReDim statement.

   '' Define an empty 1-dimensional variable-length array of SINGLE elements...
   Dim array(Any) As Single

   '' Resize the array to hold 10 SINGLE elements...
   ReDim array(0 To 9) As Single

   '' The data type may be omitted when resizing:
   ReDim array(10 To 19)

   Resizing an array cannot change its amount of dimensions, but only the 
   boundaries of each dimension.

   By default, element values of a variable-length array are lost when 
   resized. To retain the previous element values during a resize, use the 
   Preserve keyword.



------------------------------------------------------- ProPgArrayIndex ----
Array Index

An array index is the number used to access an Array of Variables created 
using the Dim command.

Description
   The following examples illustrate the use of array elements.

   If we have an array myArray with elements of 1 to 10, filled with random 
   data:

   Index        Data
   1              5
   2              2
   3              6
   4              5
   5              9
   6              1
   7              0
   8              4
   9              5
   10             7

   One can access each piece of data separately by pointing to the Index of 
   the array element:
      Print myArray(5)
      

   Printing the data contained in the fifth element of myArray results in 
   an output of:

   	9
   	

   To change the contents of an array, use it like any other Variable:
      myArray(3) = 0
      

   To print the contents of myArray(3), use the command:
      Print myArray(3)
      

   Which results in an output of:

   	0
   	

   Array elements can be indexed using another Variable. In this example we 
   set all elements in our array to zero:
      Dim a As Integer
      For a = 1 To 10
        myArray(a) = 0
      Next a
      

   To change a random array element to a random value:
      Dim Index As Integer
      Dim Value As Integer
      index = Int(Rnd(1) * 10) + 1 'This line will simply return a random value between 1 and 10
      Value = Int(Rnd(1) * 10) + 1 'This line will do the same
      myArray(index) = Value
      

Example
   Declare Sub PrintArray()

   Dim Numbers(1 To 10) As Integer
   Dim Shared OtherNumbers(1 To 10) As Integer
   Dim a As Integer

   Numbers(1) = 1
   Numbers(2) = 2
   OtherNumbers(1) = 3
   OtherNumbers(2) = 4

   PrintArray ()

   For a = 1 To 10
    Print Numbers(a)
   Next a

   Print OtherNumbers(1)
   Print OtherNumbers(2)
   Print OtherNumbers(3)
   Print OtherNumbers(4)
   Print OtherNumbers(5)
   Print OtherNumbers(6)
   Print OtherNumbers(7)
   Print OtherNumbers(8)
   Print OtherNumbers(9)
   Print OtherNumbers(10)

   Sub PrintArray ()
    Dim a As Integer
    For a = 1 To 10
      Print otherNumbers(a)
    Next a
   End Sub

See also
   * Arrays
   * Dim
   * Function
   * Sub
   * Variables 
   * Variable Scope
   * Standard Data Type Limits



---------------------------------------------------- ProPgPassingArrays ----
Passing Arrays to Procedures

Declaring/defining array parameters and passing array arguments to 
procedures

Syntax for array symbol name
   As parameter in procedure declaration:
      ( [ Any [, Any...] ] ) As datatype
      array_name( [ Any [, Any...] ] ) As datatype
   As parameter in procedure definition:
      array_name( [ Any [, Any...] ] ) As datatype
   As argument in procedure call:
      array_name()

   Parentheses (even empty) are mandatory to specify that the 
   parameter/argument is an array.

Usage of array symbol name
   When declaring procedure with array parameter:
      Declare { Sub | Function } proc_name ... ( ( [ Any [, Any...] ] ) As 
      datatype , ... ) [ ... ]
      Declare { Sub | Function } proc_name ... ( array_parameter_name( [ Any
      [, Any...] ] ) As datatype , ... ) [ ... ]
   When defining procedure with array parameter:
      { Sub | Function } proc_name ... ( array_parameter_name( [ Any [, Any
      ...] ] ) As datatype , ... ) [ ... ]
   When passing array argument to procedure:
      sub_name ( array_argument_name() , ... )
      sub_name array_argument_name() , ...
      funct_name ( array_argument_name() , ... )
      funct_name array_argument_name() , ...
      ... funct_name ( array_argument_name() , ... ) [ ... ]

      Note (same rules as for any parameter/argument list):
         When declaring/defining a procedure, parentheses surrounding a non 
         empty parameter list are required.
         When calling a subroutine, parentheses surrounding an argument 
         list (empty or non empty) are optional.
         When calling a function as a subroutine (without using the return 
         variable), the same rules as for subroutine apply.
         When calling a function in an expression (which uses the return 
         value), parentheses surrounding a non empty argument list are 
         required.
         But it is a common convention to always use parentheses (empty or 
         non empty) after the procedure name, to signify a procedure call.

Description
   Array parameter can not have a ByVal or ByRef keyword before them, 
   because arrays don't get passed the same way as normal parameters. While 
   variables get passed by value or by reference, arrays get passed by 
   descriptor (see below). In fact when an array is passed to a procedure, 
   it is a reference to its descriptor which is passed.
   All the elements of a passed array can be modified, and those changes 
   are reflected at the calling level. Perhaps ByRef should be allowed by 
   similarity with variable-length string (which are also passed by 
   descriptor).

   There is no direct possibility of passing an array by value. Declaring a 
   passed array parameter As Constant only forbids any modification in the 
   procedure body. A workaround would be to pass a user copy of the array.

   Note:
      A function return can not be an array type variable.
      A fixed-length String array can not be passed to a procedure.
      A ZString/WString array can not be simply passed to a procedure 
      because the zstring/wstring size is not passed (the "as 
      zstring/wstring * 1" type is taken by default by compiler in 
      procedure body). It is a bug at the moment because compiler just 
      fails silently while it badly computes in the procedure body the 
      address of each array element (except the first obviously).

   Array descriptor (for information purposes only):
      For a fixed-length array, the descriptor is only used for passing the 
      array to a procedure (otherwise the compiler does not use it because 
      knowing the fixed characteristics of the array).
      For a variable-length array, the descriptor is always used (the array 
      descriptor is the only defining the array characteristics).

      The array descriptor has the following structure (each item is coded 
      on an 'Any Ptr' or an 'Uinteger', except on an 'Integer' for lbound 
      and ubound):
         - pointer to the real or virtual element: @array(0, 0, ...)
         - pointer to the first real element: @array(lbound1, lbound2, ...)
         - "global" size in bytes: (ubound1 - lbound1 + 1) * (ubound2 - 
         lbound2 + 1) * ... * (size of 1 element in bytes)
         - size of one element in bytes
         - number of dimensions
         then for each dimension:
         - number of elements: (ubound - lbound + 1)
         - lbound
         - ubound

Example

   Declare Sub splitString(ByVal As String, (Any) As String, ByVal As UByte = Asc(","))

   Dim As String s = "Programmer's Guide/Variables and Datatypes/Arrays/Passing Arrays to Procedures"
   Dim As String array(Any)

   splitString(s, array(), Asc("/"))

   Print "STRING TO SPLIT:"
   Print s
   Print
   Print "RESULT ARRAY FROM SPLITTING:"
   For i As Integer = LBound(array) To UBound(array)
      Print i, array(i)
   Next i

   Sleep

   Sub splitString(ByVal source As String, destination(Any) As String, ByVal delimitor As UByte)
      Do
         Dim As Integer position = InStr(1, source, Chr(delimitor))
         ReDim Preserve destination(UBound(destination) + 1)
         If position = 0 Then
            destination(UBound(destination)) = source
            Exit Do
         End If
         destination(UBound(destination)) = Left(source, position - 1)
         source = Mid(source, position + 1)
      Loop
   End Sub

See also
   * Passing Arguments to Procedures
   * Calling Conventions
   * Returning a Value




============================================================================
    Pointers

--------------------------------------------------------- ProPgPointers ----
Pointers

Data types whose values are addresses in memory.

Declaration
   Pointers are Variables whose values are addresses in memory, and they 
   are said to 'point' to this memory. The type of data that is pointed to 
   depends on the type of pointer (an Integer Pointer points to Integer 
   data). Pointers are declared like any other variable, with the suffix "
   pointer" or "ptr" following the type name.

Assigning pointer variables
   A pointer is a memory address and the value of the pointer itself is 
   that memory address.  To assign a pointer variable is to assign it a 
   memory address to something.  One way to assign a pointer a memory 
   address is to take the address of some other variable in the program 
   using Operator @ (Address of).

Accessing pointed to data
   The data pointed to by a pointer can be accessed with Operator * (Value 
   of). This operator returns a reference to the data that its operand 
   points to. The following,

   Dim myInteger As Integer = 10
   Dim myPointer As Integer Pointer = @myInteger
   *myPointer = 20
   Print myInteger

   defines an Integer variable called myInteger and an Integer pointer 
   called myPointer that points to the location in memory where myInteger 
   is stored. Operator @ (Address of) is used to retrieve the address of 
   myInteger. The value of 20 is assigned to the location at which 
   myPointer points - the address of myInteger, or @myInteger. Changes to 
   *myPointer directly affect the value of myInteger (the expression "
   *myPointer" is the same thing as "myInteger").

Pointers to user-defined types
   Pointers to user-defined types are defined and used like all other 
   pointers. Accessing a member of a Type or Class requires one of the 
   following two methods:

   Type myType
      a As Integer
      b As Double
   End Type

   Dim x As myType
   Dim p As myType Pointer = @x

   '' 1) dereference the pointer and use the member access operator:
   (*p).a = 10
   (*p).b = 12.34

   '' 2) use the shorthand form of the member access operator:
   Print p->a
   Print p->b

   The first method uses Operator . (Member Access). This operator accesses 
   members from references, so the pointer is dereferenced first. The 
   member access operator has higher priority over the dereference 
   operator, so parenthesis are needed to dereference the pointer before 
   using it with the member access operator.

   The second method uses Operator -> (Pointer To Member Access). This 
   operator accesses members from pointers, which are automatically 
   dereferenced. This can make code a little clearer, although both forms 
   produce identical results.

See also
   * Operator @ (Address Of)
   * Operator * (Value Of)
   * Operator . (Member Access)
   * Operator -> (Pointer To Member Access)
   * VarPtr
   * StrPtr
   * ProcPtr



---------------------------------------------------- ProPgPtrArithmetic ----
Pointer Arithmetic

Manipulating address values mathematically.

Overview
Adding and subtracting from pointers
Incrementing and decrementing pointers
Distance between two pointers

Overview
   It is often useful to iterate through memory, from one address to 
   another. Pointers are used to accomplish this. While the type of a 
   pointer determines the type of variable or object retrieved when the 
   pointer is dereferenced (using Operator * (Value Of)), it also 
   determines the distance, in bytes, its particular type takes up in 
   memory. For example, a Short takes up two (2) bytes in memory, while a 
   Single needs four (4) bytes.

Adding and subtracting from pointers
   Pointers can be added to and subtracted from just like a numeric type. 
   The result of this addition or subtraction is an address, and the type 
   of pointer determines the distance from the original pointer.

   For example, the following,

   Dim p As Integer Ptr = New Integer[2]

   *p = 1
   *(p + 1) = 2

   will assign the values "1" and "2" to each integer in the array pointer 
   to by p. Since p is an Integer Pointer, the expression "*(p + 1)" is 
   saying to dereference an Integer four/eight (4/8 on 32/64bit systems) 
   bytes from p; the "1" indicates a distance of "1 * the size of an Integer
   ", or four/eight (4/8 on 32/64bit systems) bytes.

   Subtraction follows the exact same principle. Remember, a - b = a + -b.

Incrementing and decrementing pointers
   Sometimes it is more convenient to modify the pointer itself, in which 
   case the combination addition and subtraction operators will work just 
   like above. For example, the following,

   Dim array(5) As Short = { 32, 43, 66, 348, 112, 0 }
   Dim p As Short Ptr = @array(0)

   While (*p <> 0)
      If (*p = 66) Then Print "found 66"
      p += 1
   Wend

   iterates through an array until it finds an element with the value of "0
   ". If it finds an element with the value "66" it displays a nice 
   message.

Distance between two pointers
   The distance between two pointers is retrieved with Operator - (Subtract)
   , and is measured in values, not bytes. For example, the following,

   Type T As Single

   Dim array(5) As T = { 32, 43, 66, 348, 112, 0 }
   Dim p As T Ptr = @array(0)

   While (*p <> 0)
      p += 1
   Wend
   Print p - @array(0)

   will output "5" regardless of what type T is. This is because there is a 
   five (5) element difference between the first element of array (32) and 
   the element pointed to by p (0).

   Specifically, if a and b are both pointers of type T, the distance 
   between them is the number of bytes between them, divided by the size, 
   in bytes, of T, or

      ( cast(byte ptr, a) - cast(byte ptr, b) ) / sizeof(T)

See also
   * Operator + (Add)
   * Operator - (Subtract)
   * Operator @ (Address Of)
   * Operator * (Value Of)
   * Pointer Operators




============================================================================
    Declarations

--------------------------------------------- ProPgImplicitdeclarations ----
Implicit Declarations

Lazy declaration of variables.

   The qb and fblite FreeBASIC language dialects allow variable names to be 
   used without declaring them first. This is called implicit or lazy 
   declaration since the actual declaration is inferred from how the name 
   is first used.

Variable Type
   When a variable is implicitly declared, its type depends on one of two 
   things: the most recent default implicit type directive, if any, or the 
   variable type suffix symbol used, if any.

   Default type
      In the qb dialect, implicitly declared variables default to Single 
      type, while in the fblite dialect they default to Integer type.

   Default implicit type directives
      "DEFxxx" directives dictate the new default type for any following 
      implicit variable declarations. These directives are: DefByte, 
      DefUByte, DefShort, DefUShort, DefInt, DefUInt, DefLng, DefSng, DefDbl
      and DefStr.

   Variable type suffix symbols
      Variable names suffixed with one of a certain set of symbols will be 
      implicitly declared of a certain type. These symbols are: '%' for 
      Integer, '&' for Long, '!' for Single, '#' for Double and '$' for 
      String. These symbols override previous "DEFxxx" directives, if any.

Implicit Array Declaration
   Currently, FreeBASIC does not support implicit declaration of arrays.

Debugging
   For full debugging support, all variables must be explicitly declared 
   and suffixes should not be used. The use of Option Explicit is 
   recommended to turn of support for implicit declarations, so that 
   mistyped variable names are caught at compile time by the compiler.

See also
   * Option Explicit
   * FreeBASIC Language Dialects

 

--------------------------------------------------- ProPgInitialization ----
Variable Initializers

Variable initializers are supported for initializing Arrays, variables and 
UDTs.

Syntax
      Dim scalar_symbol [AS DataType] = expression
      Dim array_symbol ([lbound TO] ubound) [AS DataType] => { expression 
      [, ...] }
      Dim udt_symbol AS DataType = ( expression [, ...] )

Description
   Arrays, variables and UDTs may be given a value at the time of their 
   declaration using Dim, with the syntax shown above.  Please note the 
   important differences between initializing different types.  Scalar 
   variables are initialized as they would in a normal assignment, using an 
   equals sign.  UDTs and arrays are assigned with an equal sign followed 
   by a greater than symbol (=>).  Array values are given in comma 
   delimited values enclosed by curly brackets, and UDT values are given in 
   comma delimited values enclosed by parenthesis.

   These methods of initializing variables can be nested within one another 
   for complex assignments.  For instance, to initialize a multidimensional 
   array:

   Dim array(1 To 2, 1 To 5) As Integer => {{1, 2, 3, 4, 5}, {1, 2, 3, 4, 5}}

   In this declaration, the values for the left-most dimension are given as 
   5-index arrays.  Nesting allows for arrays of any dimension to be 
   initialized.

   UDTs and arrays can be nested within each other as well.  For instance, 
   the following code declares and initializes an array of UDTs.

   Type mytype
      var1 As Double
      var2 As Integer
      var3 As ZString Ptr
   End Type

   Dim MyVar(0 To 1) As mytype => _
      { _
         (1.0, 1, @"Hello"), _
         (2.0, 2, @"GoodBye") _
      }

   For module-level, static, or global variables, initialized values must 
   be constant expressions.  FreeBASIC will report a compile-time error if 
   otherwise.

Differences from QB
   * Variable Initializers are new to FreeBASIC

See also
   * Dim



--------------------------------------------------- ProPgStorageClasses ----
Storage Classes

Visibility and lifetime of variables, objects and arrays

A variable, object or array's storage class determines when and where 
memory is allocated for it and when that memory is destroyed. There are 2 
storage classes in FreeBASIC: automatic and static.

Automatic

   Automatic variable, object and array lifetimes begin at the point of 
   declaration and end when leaving the scope they are declared in.

   Automatic entities are guaranteed to have unique storage for each 
   instance of the block in which they are declared. For example, the 
   automatic variables declared within a procedure will be allocated at 
   different addresses and have unique state (value) for each call to the 
   procedure.

   Automatic variables, objects and arrays are defined using the Dim, ReDim 
   and Var keywords without the Shared specifier.

   The memory for automatic variables, objects and arrays is allocated on 
   the program stack.

   Automatic variables, objects and arrays have no linkage.

Static

   Static variable, object and array lifetimes begin at program creation 
   and end with program termination.

   Static entities are guaranteed to have the same storage for each 
   instance of the block in which they are declared. For example, the 
   static variables declared within a procedure will be allocated at the 
   same address, and retain their state (value) across each call to the 
   procedure.

   Static variables, objects and arrays are declared using the Static 
   keyword. Entities declared using the Shared specifier are implicitly 
   static. All entities declared within a procedure that is declared using 
   the Static specifier are also implicitly static.

   The memory for static variables, objects and arrays is allocated in the 
   .BSS section of the executable, or in the .DATA section if they are 
   initialized when defined. Static variable-length arrays must be declared 
   empty, with an empty subscript range list; their element data is still 
   allocated in the free store (when they are resized), but the internal 
   array data is allocated in the .DATA section of the executable to allow 
   the element data to persist throughout program execution.

   Static variables, objects and arrays have internal linkage by default, 
   unless previously declared using the Extern or Common keywords.

Platform Differences
   *  In DOS and Windows platforms, the size of the program stack can be 
     adjusted at compile-time using the -t command-line switch. In Linux 
     platforms, the size of the program stack can be adjusted at load-time 
     by modifying /etc/security/limits.conf, or on a per-thread basis using 
     the shell builtin ulimit.

Differences from QB
   * QuickBASIC allows static entities to be declared within procedures 
     and DEF FN routines only.

See also
   * Extern, Common
   * Dim, ReDim, Var, Shared, Byref (Variables)
   * Static
   * Linkage



---------------------------------------------------- ProPgVariableScope ----
Variable Scope

Visibility and access rules for variables and objects

A variable's scope refers to its visibility in a program. A variable is not 
visible (cannot be accessed) outside the scope in which it was declared. 
Where and how a variable is declared determines its scope.

   In FreeBASIC, there are 4 categories of scope: local, shared, common and 
   common shared. Each of these scopes has different visibility rules, 
   which are detailed below.

Local Scope
   Variables declared in the local scope are visible only in the most local 
   instance of the IF, SELECT, WITH, FOR, WHILE, DO, SCOPE, procedure, or 
   module block in which they are declared.

   * Sub, Function, the main body, and each compound statement implicitly 
     define a new local scope block. 
   * Explicitly declared variables using Dim or ReDim or Static take the 
     scope of the local most block in which they are declared. 
   * Implicit variables take the scope of the the local most 
     Scope...End Scope block in which they are first used, otherwise take 
     the scope of the Sub, Function, or main body in which they are used. 

   In the local scope, there is no visibility between module-level code and 
   procedure level code. Furthermore, variables dimensioned within a block 
   decision or loop statement will only be visible within the block in 
   which they are dimensioned. Variables declared in the local scope of a 
   module are not visible in any of the procedures within that module. 
   Similarly, local variables declared inside procedures are not visible in 
   the module-level code, nor any other procedure within the module.

   Variables declared inside Scope blocks may only be declared of local 
   scope, and are not visible outside the block. Scope blocks, however, 
   inherit the surrounding scope, so local variables declared outside the 
   Scope block will be visible inside (see example program).

   You can declare a variable to be of local scope explicitly by using the 
   Dim statement, or implicitly (for only -lang qb and -lang fblite 
   dialects) by simply introducing the variable (see Implicit Declarations
   ). The example program local.bas demonstrates visibility rules for the 
   local scope.

local.bas
   '' visible only in this module
   Dim As Integer local_moduleLevel1

   '' OK.
   Print local_moduleLevel1

   Scope
     '' OK; SCOPE Blocks inherit outer scope
     Print local_moduleLevel1
     
     '' visible only in this SCOPE Block
     Dim As Integer local_moduleLevel2

     '' OK.
     Print local_moduleLevel2
   End Scope

   '' Error; can't see inner-SCOPE vars
   '' print local_moduleLevel2

   Function some_function( ) As Integer
     '' visible only in this function
     Dim As Integer local_functionLevel

     '' OK.
     Print local_functionLevel

     '' Error; can't see local module-level vars  
     '' print local_moduleLevel1

     '' Error; can't see local module-level vars
     '' print local_moduleLevel2

     Function = 0

   End Function

   '' print local_functionLevel                    '' Error; can't see function_level vars
   End 0

Shared Scope
   Variables declared in the shared scope of a module are visible to both 
   the module and all procedures of that module.

   Unlike the local scope, the shared scope makes module-level variables 
   visible to procedures of that module. In other words, the module shares 
   its declarations with its procedures.

   Variables can only be declared to be of shared scope at the 
   module-level. Ie., only modules can share variables. Neither procedures 
   nor Scope blocks can declare variables in the shared scope, thus 
   variables declared there can only be local to that procedure or block.

   You can declare a variable to be of shared scope by using the DIM (or 
   REDIM or STATIC) statement with the Shared keyword. The example program 
   shared_scope.bas demonstrates visibility rules for the shared scope.

shared.bas
   '' visible throughout this module
   Dim Shared As Integer shared_moduleLevel1

   '' OK.
   Print shared_moduleLevel1

   Scope
     '' OK; can see outer-scope vars
     Print shared_moduleLevel1
     
     '' Error; SCOPE-level vars cannot be shared
     '' dim shared as integer shared_ModuleLevel2
   End Scope

   End 0

   Function some_function( ) As Integer
     '' OK; can see shared module-level vars
     Print shared_moduleLevel1

     '' Error; function-level vars cannot be shared  
     '' dim shared as integer sharedFunctionLevel

     Function = 0
   End Function

Common Scope
   Variables declared in the common scope are visible to all modules.

   Variables declared with Common are visible to other modules with a 
   matching Common variable declaration.  The variable name declared must 
   match from between modules.

module1.bas
   '' compile with:
   ''    fbc -lang qb module1.bas module2.bas

   '$lang: "qb"

   Declare Sub Print_Values()
   Common m1 As Integer
   Common m2 As Integer
                    ' This is executed after all other modules
   m1 = 1

   Print "Module1"       
   Print "m1 = "; m1     ' m1 = 1 as set in this module
   Print "m2 = "; m2     ' m2 = 2 as set in module2

   Print_Values

module2.bas
   Common m1 As Integer
   Common m2 As Integer

   m2 = 2

   Print "Module2"       ' This is executed first
   Print "m1 = "; m1     ' m1 = 0 (by default)
   Print "m2 = "; m2     ' m2 = 2

   Sub Print_Values()
     Print "Module2.Print_Values"
     Print "m1 = "; m1   ' Implicit variable = 0, because '-lang qb' use
     Print "m2 = "; m2   ' Implicit variable = 0, because '-lang qb' use
   End Sub

Output:

     Module2
     m1 = 0
     m2 = 2
     Module1
     m1 = 1
     m2 = 2
     Module2.Print_Values
     m1 = 0
     m2 = 0

Common Shared Scope
   Variables declared in the common shared scope are visible to all modules 
   and all procedures of those modules.

   Variables declared with Common are visible to other modules with a 
   matching Common variable declaration.  The variable name declared must 
   match from between modules.  Within a module the Shared declaration 
   modifier gives the variable module scope and makes the variable visible 
   to all subs and functions.

module3.bas
   '' compile with:
   ''    fbc module3.bas module4.bas

   Declare Sub Print_Values()
   Common m1 As Integer
   Common m2 As Integer

   '' This is executed after all other modules
   m1 = 1

   Print "Module3"       
   Print "m1 = "; m1     '' m1 = 1 as set in this module
   Print "m2 = "; m2     '' m2 = 2 as set in module2

   Print_Values

module4.bas
   Common Shared m1 As Integer
   Common Shared m2 As Integer

   m2 = 2

   Print "Module4"       '' This is executed first
   Print "m1 = "; m1     '' m1 = 0 (by default)
   Print "m2 = "; m2     '' m2 = 2

   Sub Print_Values()
     Print "Module4.Print_Values"
     Print "m1 = "; m1   '' m1 = 1    
     Print "m2 = "; m2   '' m2 = 2
   End Sub

Output:

     Module4
     m1 = 0
     m2 = 2
     Module3
     m1 = 1
     m2 = 2
     Module4.Print_Values
     m1 = 1
     m2 = 2

Example
   See examples above.

See also
   * Scope
   * Dim
   * Common
   * Shared
   * Variables
   * Implicit Declarations

  

------------------------------------------------- ProPgVariableLifetime ----
Simple Variable Lifetime vs Scope (IN PROGRESS...)

Lifetime of Simple Variable, created from declaration keyword for static 
memory allocation, relative to its Scopes.

Preamble:
   * The Lifetime of a variable is the time period in which the variable 
     has valid memory (the Scope referring to the program part where its 
     name is visible). The value of a variable may change during its 
     lifetime, but it retains some consistent value.
   * The simple variables considered are the predefined variables 
     including the raw pointers, and the fixed-length strings/arrays, but 
     excluding the variable-length strings/arrays. Instances of simple UDT 
     (without any dynamic data allocated) are also considered.
   * The declaration keywords for static memory allocation are: 'Dim', 
     'Static', 'Var'.

For such variables allocated in static way as defined above, the lifetime 
generally matches the surrounding scope, otherwise it can be greater than 
this one.

Declaration syntax for a lifetime matching the surrounding scope
   For such variables declared anywhere, as follows (or similar syntax):
         (1)	Dim [ByRef] Shared As datatype [Ptr] variablename ...
            or
         (2)	Var [ByRef] Shared variablename = expression
               (equivalent to: 'Dim [ByRef] Shared As TypeOf((expression)) 
               = expression')
      or
         (3)	{Dim|Static} [ByRef] Shared As datatype [Ptr] variablename ...
            or
         (4)	Var [ByRef] Shared variablename = expression
               (equivalent to: 'Dim [ByRef] Shared As TypeOf((expression)) 
               = expression')
   they always have a lifetime matching their surrounding scope (global 
   scope, or scope block, or compound statement block, or procedure scope).

   With (1) or (2) syntax ('Shared' not used), these local variables are 
   always allocated on the program stack at the time of their declarations, 
   and are automatically deallocated when going out their scopes.
   With (3) or (4) syntax ('Shared' used), these global variables are 
   always allocated in the .BSS or .DATA section of the executable (their 
   scopes and lifetimes begin at program creation and end with program 
   termination).

Declaration syntax for a lifetime greater than (otherwise equal to) the 
surrounding scope
   For such variables declared anywhere, as follows (or similar syntax):
         Static [ByRef] Shared As datatype [Ptr] variablename ...
   they always have a lifetime equal to the program duration, so greater 
   than their surrounding scope if there are declared in any local scope 
   block (matching their surrounding scope if there are declared in the 
   global scope).

   These static variables are always allocated in the .BSS or .DATA section 
   of the executable (their lifetimes begin at program creation and end 
   with program termination).

   Interest of declaring such static variables in a compound instruction 
   block or in a procedure scope:
      - As for 'Dim', the 'Static' keyword is used in a compound statement 
      block or in a procedure scope to declare variables whose scope stops 
      at the end of the compound statement block or the procedure.
      - However, unlike 'Dim', the lifetime differs because the variables 
      declared with the 'Static' keyword retain their value between the 
      successive loops of the compound instruction block or the successive 
      calls to the procedure.
      - In summary, a declared static variable has a local scope, but its 
      lifetime is comparable to that of a global scope variable.
      - So, static variables with the same name can be declared in several 
      different compound statement blocks and in different procedure 
      scopes. Each of these variables therefore remains independent and 
      retains its own value in its own local scope.

Example

See also
   * Variable Scope
   * Dynamic Object and Data Lifetime



--------------------------------------------------- ProPgObjectLifetime ----
Dynamic Object and Data Lifetime (IN PROGRESS...)

Lifetime of Dynamic Object and its Data, created from declaration keyword 
for dynamic memory allocation.

Preamble:
   * The Lifetime of an object (and of its data) is the time period in 
     which its instance name exists (and refers to valid data). But in 
     absolute terms, the instance name of the object and its associated 
     data can have two independent lifetimes (the Scope referring to the 
     program part where the instance name is visible).
   * The dynamic objects considered are the predefined pseudo-objects such 
     as the variable-length strings/arrays, and the instances of complex 
     UDT (with dynamic data allocated). Simple variables but dynamically 
     allocated are also considered.
   * The declaration keywords for dynamic memory allocation are: 
     'Allocate'/'Callocate'/'Reallocate', 'New', 'Imagecreate' (for 
     deallocation: 'Deallocate', 'Delete', 'Imagedestroy').

For such objects and data dynamically allocated as defined above, the 
lifetime of the instance name of the object generally matches the 
surrounding scope (otherwise it can be greater than this one), but the 
lifetime of associated data may mismatch this one because the 
allocation/deallocation of associated data is triggered by the user 
himself.

------------------------------------------------------- ProPgNamespaces ----
Namespaces

Namespace, a container for identifiers so that they don't conflict with 
those in other Namespaces or the global scope.

Syntax
   Namespace identifier [ Alias "aliasname" ]
      statements
   End Namespace

Parameters
   identifier
      The name of the Namespace (including nested names specifier).
   aliasname
      An alternate external name for the Namespace.

Description
   Namespaces are declaration fields that allow to delimit the search for 
   the names of identifiers by the compiler. Their purpose is essentially 
   to group the identifiers logically and to avoid name conflicts between 
   several parts of the same project.
   This type of conflict stems from the fact that only one global scope is 
   provided by default, in which there should be no name conflict. With 
   Namespaces, this type of problem can be more easily avoided, because 
   defining global objects in the global scope can be avoid.

   Namespaces are not allowed to contain code directly, only inside 
   procedures declared in that Namespace. That is because a Namespace is 
   not a scope, it is not something that is executed, it is just something 
   that can be used to hold declarations.

   Any variable declared in Namespace is implicitly static and visible 
   throughout the entire program (Static and Shared keywords are useless). 
   Therefore only an initializer with a constant is authorized.

Usage
   Unlike another declarative region such as a Type, a Namespace can be 
   split into several pieces. The first piece serves as declaration, and 
   the following ones as extensions. The syntax for a Namespace extension 
   is exactly the same as that for the declaration part.
   Identifiers declared or defined within the same Namespace must not 
   conflict. They may have the same names, but only as part of the 
   overloading. A Namespace therefore behaves exactly like the declaration 
   fields of Types and the global scope.

   Access to Namespace identifiers is through the resolution operator 
   ("."), by prefixing the name of the identifier to use from the name of 
   its Namespace. However, this prefixing is useless inside the Namespace 
   itself, just like members inside their Type.
   Namespace member procedures can be defined inside this space. They can 
   also be set outside this space, if the resolution operator is used 
   (prefixing from the name of its Namespace). The procedures thus defined 
   must appear after their declarations in the Namespace.

   It is possible to define a Namespace within another Namespace. However, 
   this declaration must occur at the outermost declarative level of the 
   Namespace that will contain the Namespace. Namespace declarations can 
   not be put inside a procedure body or inside a Type block.

   When a Namespace has a very complicated name, it may be advantageous to 
   define an alias for that name. The alias will then have a simpler name.
   Names given to Namespace aliases  must not conflict with the names of 
   other identifiers in the same Namespace, whether this is the global 
   scope or not.

   Note: The parser allows to define anonymous Namespaces (without 
   identifier term), but this is the only similarity with the actual C++ 
   capability: The FB compiler automatically generates multiple separate 
   anonymous Namespaces instead of one only per module in such a case.
   The FB anonymous Namespaces are almost unusable because all their 
   declarations are inaccessible, even from the body of the module that 
   contains them. Apart from encapsulating module constructors/destructors 
   also inside, nothing else can be done with them.

   'Using (Namespaces)' command
      Using (Namespaces) allows to use a identifier from a Namespace in a 
      simplified way, without having to specify its full name (that is, the 
      Namespace name followed by the "." operator then the identifier 
      name).
      Each Using command allows to directly use all the identifiers of the 
      referred Namespace.

      - Syntax:
         Using identifier [, identifier [, ...] ]

      - Parameters:
         identifier: The name of the Namespace to use.

      - Usage:
         After a Using command, it is still possible to use the full names 
         of the identifiers from a Namespace, but this is no longer 
         necessary. The Using commands are valid from the line where they 
         are declared until the end of the current scope block.
         If a Namespace is extended after a Using directive, the 
         identifiers defined in the Namespace extension can be then used 
         exactly as the identifiers defined before the using directive 
         (that is, without the full expression of their Namespace names).

         When entering Using command(s) for several Namespace names, name 
         conflicts may occur. In this case, no error is reported from the 
         Using command(s), but an error occurs if one of the identifiers 
         for which there is a conflict is used (using full name of the 
         expected identifier solves the conflict).

Example
   Namespace extension:
   Namespace A  ' Declaration of Namespace A
      Dim As Integer i
   End Namespace

   Namespace B  ' Declaration of Namespace B
      Dim As Integer i
   End Namespace

   Namespace A  ' Extension of Namespace A
      Dim As Integer j
   End Namespace

   Access to Namespace members:
   Dim As Integer i  ' Declare i in the global scope

   Namespace A
      Dim As Integer i = 2  ' Declare i in Namespace A
      Dim As Integer j = 3  ' Declare j in Namespace A
   End Namespace

   i = 1    ' Use i from global scope (.i)
   A.i = 4  ' Use i from Namespace A (A.i)

   External definition of a function declared in a Namespace:
   Namespace A
      Declare Function f () As Integer  ' Declaration of f() in Namespace A (A.f())
   End Namespace

   Function A.f () As Integer  ' Definition of f() from Namespace A (A.f())
      Return 0
   End Function

   Definition of nested Namespace:
   Namespace A
      Dim As Integer i  ' (A.i)
      Namespace B
         Dim As Integer j  ' (A.B.j)
      End Namespace
   End Namespace

   Access with 'Using (Namespaces)' command:
   Namespace A
      Dim As Integer i  ' Declaration of A.i
      Dim As Integer j  ' Declaration of A.j
   End Namespace

   Using A  ' Namespace A identifiers are also used
   i = 1  ' Equivalent to A.i
   j = 1  ' Equivalent to A.j

   Extension of Namespace after 'Using (Namespace)' command:
   Namespace A
      Dim As Integer i
   End Namespace

   Using A

   Namespace A
      Dim As Integer j
   End Namespace

   i = 0  ' Initialize A.i
   j = 0  ' Initialize A.j

   Conflict between local identifiers with 'Using (Namespaces)' command:
   Namespace A
      Dim As Integer i  ' Declare A.i
      Dim As Integer j  ' Declare A.j
   End Namespace

   Namespace B
      Dim As Integer i  ' Declare B.i
      Dim As Integer j  ' Declare B.j
      Using A           ' A.i/j and B.i/j are in conflict, but no error is given
   End Namespace

   Dim As Integer j  ' Declare also j the global scope

   Using B
   'i = 1   ' error: Ambiguous symbol access, explicit scope resolution required (between B.i and A.i)
   B.i = 1  ' ambiguity resolution solved by using full name
   j = 2    ' ambiguity (between .j, B.j, A.j) solved by compiler, by choosing override .j in the global scope

See also
   * Namespace
   * Using (Namespaces)
   * Scope...End Scope



--------------------------------------------------- ProPgVarProcLinkage ----
Variable and Procedure Linkage

Name visibility within and between modules
   Linkage refers to the visibility of the name of a variable, object or 
   procedure between one or more modules of a program. In other words, a 
   linkage dictates how a name is shared between modules. There are two 
   main types of linkage a name can have: internal and external.

Internal linkage
   Names with internal linkage only refer to variables, objects or 
   procedures defined within their own module; they are not outwardly 
   visible to other modules. This means that two or more modules can refer 
   to different things using the same name. Note that linkage only refers 
   to visibility of a name, and depending on storage class and lifetime, a 
   variable, object or procedure with internal linkage may be shared 
   between modules using its address.

   Module-scope declarations

      Variable and object names declared at module-scope have internal 
      linkage unless otherwise declared with Extern or Common. For example, 
      variable names first introduced with Dim or Static have internal 
      linkage, and those variables can only be referred to by name within 
      the module in which they are defined. Note that using Shared only 
      allows name visibility within the module's procedures, and does not 
      contribute to the name's linkage.

      Procedure names declared with Private have internal linkage.

   Local-scope declarations

      All variable and object names declared at local-scope (in a Do loop, 
      or procedure body, for instance) have internal linkage.

External linkage
   Names with external linkage may refer to variables, objects or 
   procedures defined within their module or in another module. Having 
   external linkage means that a name is outwardly visible to other 
   modules, and all modules that use that same external name all refer to 
   the same variable, object or procedure. Thus, only one module may define 
   an external name (the compiler will complain about a duplicated 
   definition if it finds an additional definition of a name with external 
   linkage).

   Module-scope declarations

      Variable and object names declared at module-scope are declared to 
      have external linkage with Extern or Common. 

      Extern declares the variable having external linkage, but does not 
      define it.  This external declaration must come before any definition 
      of the same name (a declaration without Extern specifies internal 
      linkage, and currently, any further external declarations of that 
      name signify a duplicated definition).  Variable and object names 
      with external linkage declared using Extern are always in the shared 
      scope, and so can be referred to within procedure bodies.

      Common declares the variable having external linkage as well as 
      defining the variable.  But, it is different from Extern in that the 
      Common definition of the variable may appear in more than one module. 
      When used with arrays, only variable-length arrays without subscripts 
      may be declared, and the array must be sized at run-time using Dim or 
      ReDim before it can be used.  Variable and object names with external 
      linkage declared using Common are only in the shared scope if the 
      Shared scope specifier is also given.  Shared variables can be 
      referred to within procedure bodies.

      When both Extern and Common are both used to declare and define a 
      variable, the effect is that the meaning of Common statement is 
      altered to behave as though it were a Dim declaration.  So it is 
      generally, not recommended to mix Extern and Common on the same 
      variable in the same module.  However, variables may be declared and 
      defined with Common in one module and then referenced with Extern in 
      another module without confusion.

      Procedure names are declared to have external linkage by default. 
      Declarations using Public explicitly specify external linkage.

   Local-scope declarations

      Currently, names declared at local-scope cannot have external 
      linkage.




============================================================================
    User Defined Types

------------------------------------------------------------- ProPgUDTs ----
User Defined Types

Custom types.

Overview
   User-Defined Types are special kinds of variables which can be created 
   by the programmer.  A User-Defined Type (UDT) is really just a container 
   that contains a bunch of other variables, like an array, but unlike 
   arrays, UDTs can hold different variable types (whereas arrays always 
   hold many variables of the same type).  In fact, UDTs can even have 
   procedures inside of them!

Members
   The different variables and/or procedures stored inside a UDT are called 
   "members", or more generally, items.  Members can be variables of just 
   about any type, including numerical types, strings, pointers, Enums, and 
   even arrays.  Variables are created in UDTs much the same way variables 
   are created 	normally, except that the Dim keyword is optional.  UDT 
   members are accessed via the . Operator, so for example if you created a 
   variable called someVar in a UDT you would access it with the name of 
   the UDT variable followed by ".someVar".  Here is an example:

   'Define a UDT called myType, with an Integer member named someVar
   Type myType
     As Integer someVar
   End Type

   'Create a variable of that type
   Dim myUDT As myType

   'Set the member someVar to 23, then display its contents on the screen
   myUDT.someVar = 23
   Print myUDT.someVar

   Notice that the Type...End Type does not actually create a variable of 
   that type, it only defines what variables of that type contain.  You 
   must create a variable of that type to actually use it!

UDT Pointers
   UDT Pointers are, as the name implies, pointers to UDTs.  They are 
   created like regular pointers, but there is a special way to use them.  
   To access the member of a UDT pointed to by a pointer, you use the 
   -> Operator.  For example, if myUDTPtr is a pointer to a UDT which has a 
   member someVar, you would access the member as myUDTPtr->someVar, which 
   is a much cleaner shorthand for the equally valid (*myUDTPtr).someVar.

   Type rect
      x As Integer
      y As Integer
   End Type

   Dim r As rect
   Dim rp As rect Pointer = @r

   rp->x = 4
   rp->y = 2

   Print "x = " & rp->x & ", y = " & rp->y
   Sleep

See also
   * Type Aliases
   * Temporary Types
   * Constructors and Destructors
   * Member Procedures
   * Member Access Rights
   * Operator Overloading



------------------------------------------------------ ProPgTypeAliases ----
Type Aliases

Additional names for variable or object types

Overview
Declaration
Overload resolution
Pointers to procedure pointers
Type forwarding
Incomplete types

Overview
   Type aliases are alternative names for a type. They can be used to 
   facilitate a mass change from one type to another, save typing, or make 
   circular dependency possible.

Declaration
   Type aliases are declared using the Type keyword much like declaring 
   variables or objects with Extern or Dim.

   The following example declares a type alias to Single called "float", a 
   procedure, and defines and initializes two variables of that type:

   Type float As Single

   Declare Function Add (a As float, b As float) As float

   Dim foo As float = 1.23
   Dim bar As float = -4.56
         

   Procedure pointer type aliases are declared in the same fashion, as 
   shown in the following example:

   Declare Function f (ByRef As String) As Integer

   Type func_t As Function (ByRef As String) As Integer

   Dim func As func_t = @f
         
   Function f (ByRef arg As String) As Integer
      Function = CInt(arg)
   End Function

Overload resolution
   Type aliases are just that - aliases. For all intents and purposes, a 
   type alias is the type it aliases. So as far as procedure overload 
   resolution is concerned, a procedure declared with a parameter of type "
   alias_to_T" is the same as a procedure declared with a parameter of type 
   "T" (the same applies to overloading member procedures as well).

   In other words, it is an error - duplicated definition - to declare a 
   procedure where parameters differ only in a type and its alias, as the 
   following example shows:

   Type float As Single

   Declare Sub f Overload (a As Single)

   '' If following line is uncommented, this will generate a duplicated definition error
   '' Declare Sub f (a As float)

Pointers to procedure pointers
   Pointers to procedure pointers are just like any other pointer type, 
   except they point to procedure pointers. Because the syntax for 
   declaring procedure pointers doesn't allow directly creating a pointer 
   to procedure pointer when the procedure is a function (because ptr 
   applies on return type and not on procedure), a type alias is used.

   The following example declares a pointer to a procedure returning an 
   integer pointer, and then a pointer to a pointer to a procedure 
   returning an integer:

   Dim pf As Function() As Integer Ptr

   Type pf_t As Function() As Integer
   Dim ppf As pf_t Ptr
      

Type forwarding
   Type aliases can be forward referencing: an alias can refer to some 
   other type not yet fully defined.

   Type foo As bar

   Type sometype
     f   As foo Ptr
   End Type

   Type bar
     st  As sometype
     a   As Integer
   End Type
      

   Using a type alias and forward referencing allows circular dependencies 
   between types.

   Type list As list_

   Type listnode
     parent As list Ptr
     text As String
   End Type

   Type list_
     first As listnode Ptr
     count As Integer
   End Type
      

Incomplete types
    A type is considered incomplete until the size of it, that is the 
   number of bytes it would need to occupy in memory is known, and the 
   offsets of all of its fields are known.  It is not possible to allocate 
   space for an incomplete type.  It is not possible to declare a variable 
   having the data type of an incomplete type, pass an incomplete type as a 
   parameter, or access the members of an incomplete type.

   However, pointers to incomplete types may be allocated, declared as 
   members in other types, or passed as parameters to a procedures since 
   the size of a pointer is known.

   Type sometype As sometype_

   '' Not allowed since size of sometype is unknown
   '' TYPE incomplete
   ''   a AS sometype
   '' END TYPE

   '' Allowed since size of a pointer is known
   Type complete
     a As sometype Ptr
   End Type
   Dim x As complete

   '' Not allowed since size of sometype is still unknown
   '' DIM size_sometype AS INTEGER = SIZEOF( sometype )

   '' Complete the type
   Type sometype_
     value As Integer
   End Type

   '' Allowed since the types are now completed
   Dim size_sometype As Integer = SizeOf( sometype )

   Type completed
     a As sometype
   End Type

   Dim size_completed As Integer = SizeOf( completed )
      

   


--------------------------------------------------------- KeyPgTypeTemp ----
Temporary Types

Creates a temporary copy of a user defined type

Syntax
   result = Type( initializers, ... )
      or
   result = Type<typename>( initializers, ... )

Parameters
   initializers
      Initial values for the type (or only the firsts)
   typename
      The name of the Type or Union

Return Value
   A temporary copy of the type.

Description
   Used to create a temporary type.  If typename is not explicitly given, 
   it will be inferred from its usage if possible.  Usage of the temporary 
   copy may include assigning it to a variable, passing it as a parameter 
   to a procedure, or returning it as a value from a procedure.

   For a type without own or inherited constructor (excluding also any type 
   that is directly or indirectly derived from Object), the temporary type 
   syntax is allowed if all type data-fields (including those inherited) 
   are numeric primitives only and without any default initializers.
   If at same time the type is without destructor, the compiler does a 
   direct assignment instead of using a temporary copy.

   The Constructor for the type, if there is one with parameters matching 
   with the initializers provided, will be called when the temporary copy 
   is created, and the Destructor for the type, if there is one, will be 
   called immediately after its use. But when there is a matching 
   constructor, the temporary type expression may be simply replaced by 
   typename( initializers, ... ).
   If there is a constructor at least but none which matches with the 
   initializers, the temporary type syntax is obviously disallowed.

   It can create not only a temporary copy of an user defined type, but 
   also a temporary copy of predefined data-type as a variable-length 
   string or any numeric data-type (all standard data-types excluding 
   fixed-length strings).

   It can also be used as an even shorter shortcut than With (see below) if 
   you are changing all the data-fields (or the n firsts only).

   A temporary object is destroyed at the end of execution of the statement 
   (where it's defined), but its corresponding allocated memory is not 
   released and remains available (unused) until going out the scope where 
   statement is.

   Note: Static qualifier used at procedure definition level does not apply 
   to temporary types.

Example
   Type Example
      As Integer field1
      As Integer field2
   End Type

   Dim ex As Example

   '' Filling the type by setting each field
   ex.field1 = 1
   ex.field2 = 2

   '' Filling the type by setting each field using WITH
   With ex
      .field1 = 1
      .field2 = 2
   End With

   '' Fill the variable's fields with a  temporary type
   ex = Type( 1, 2 )

   '' Passing a user-defined types to a procedure using a temporary type
   '' where the type can be inferred.

   Type S
     As Single x, y
   End Type

   Sub test ( v As S )
     Print "S", v.x, v.y
   End Sub

   test( Type( 1, 2 ) )

   '' Passing a user-defined type to a procedure using temporary types
   '' where the type is ambiguous and the name of the type must be specified.

   Type S
     As Single x, y
   End Type

   Type T
     As Integer x, y
   End Type

   Union U
     As Integer x, y
   End Union

   '' Overloaded procedure test()
   Sub test Overload ( v As S )
     Print "S", v.x, v.y
   End Sub

   Sub test ( v As T )
     Print "T", v.x, v.y
   End Sub

   Sub test ( v As U )
     Print "U", v.x, v.y
   End Sub

   '' Won't work: ambiguous
   '' test( type( 1, 2 ) )

   '' Specify name of type instead
   test( Type<S>( 1, 2 ) )
   test( Type<T>( 1, 2 ) )
   test( Type<U>( 1 ) )

Differences from QB
   * New to FreeBASIC

See also
   * Type...End Type
   * Type (Alias)



------------------------------------------------------- ProPgCtorsDtors ----
Constructors and Destructors

In charge of the creation and destruction of objects.

Overview
Declaration
Default constructors
Copy constructors
Calling constructors

Overview
   Constructors and destructors are responsible for creating and destroying 
   objects, respectively. In general, constructors give objects their 
   initial state, that is, they give meaningful values to their objects' 
   member data. Destructors perform the opposite function; they make sure 
   any resources owned by their objects are properly freed.

   Simply, constructors are special member procedures that are called when 
   an object is created, and destructors are special member procedures 
   called when an object is destroyed. Both constructors and destructors 
   are called automatically by the compiler whenever an object is created 
   or destroyed, whether explicitly with the use of the Dim or 
   New Expression/Delete Statement keywords, or implicitly by passing an 
   object to a procedure by value or through an object going out of scope.

Declaration
   Constructors and destructors are declared like member procedures but 
   with the Constructor keyword instead of Sub or Function, and without a 
   name. Similarly, they are defined with only the name of the Type or Class
   they are declared in.

   A Type or Class can have multiple constructors, but only one destructor.

Default constructors
   Default constructors are constructors that either have no parameters, or 
   all of their parameters have a default value. They are called when an 
   object is defined but not initialized, or is created as part of an 
   array, with the Dim, ReDim or New[] expression keywords. The first 
   constructor declared in the example below is a default constructor.

Copy constructors
   Copy constructors are constructors called when an object is created, or 
   cloned, from another object of the same type (or an object that can be 
   converted to that type). This happens explicitly when initializing an 
   object with another object, or implicitly by passing an object to a 
   procedure by value. Copy constructors are declared having one parameter: 
   an object of the same type passed by reference.

   Copy constructors are only called when creating and initializing object 
   instances. Assignment to objects is handled by the Member Operator Let.

Calling constructors
   Unlike other member procedures, constructors are generally not called 
   directly from an object instance. Instead, a constructor is specified in 
   a Dim statement either with an initializer or without one, or in a 
   New Expression statement with or without arguments.

   When specifying an initializer for an object, the name of the type 
   followed by any arguments it requires is used.

   Type foo
      '' Declare a default ctor, copy ctor and normal ctor
      Declare Constructor
      Declare Constructor (ByRef As foo)
      Declare Constructor (As Integer)

      '' Declare a destructor
      Declare Destructor

      ints As Integer Ptr
      numints As Integer
   End Type

   '' Define a constructor that creates 100 integers
   Constructor foo
      ints = New Integer(100)
      numints = 100
   End Constructor

   '' Define a constructor that copies the integers from another object
   Constructor foo (ByRef x As foo)
      ints = New Integer(x.numints)
      numints = x.numints
   End Constructor

   '' Define a constructor that creates some integers based on a parameter
   Constructor foo (n As Integer)
      ints = New Integer(n)
      numints = n
   End Constructor

   '' Define a destructor that destroys those integers
   Destructor foo
      Delete[] ints
   End Destructor

   Scope
      '' calls foo's default ctor
      Dim a As foo
      Dim x As foo Ptr = New foo

      '' calls foo's copy ctor
      Dim b As foo = a
      Dim y As foo Ptr = New foo(*x)

      '' calls foo's normal ctor
      Dim c As foo = foo(20)
      Dim z As foo Ptr = New foo(20)

      '' calls foo's dtor
      Delete x
      Delete y
      Delete z
   End Scope '' <- a, b and c are destroyed here as well

Compiler-provided constructors and destructors
   If no copy constructor is declared for a Type or Class, the compiler 
   provides one. If no constructor has been declared, the compiler also 
   provides a default constructor.

   The compiler-provided default constructor initializes member data to 
   default values, that is, numeric and pointer members are set to zero 
   (0), and object members are default-constructed. The copy constructor 
   that the compiler declares shallow-copies all member data from one type 
   to another: numeric and pointer types are initialized with the 
   corresponding data members in the object that is copied, and object 
   members are copy-constructed from their corresponding object members. 
   This means that dynamic resources, such as memory pointed to by a 
   pointer data member, is not copied; only the address is copied. So if an 
   object owns a resource, meaning it is responsible for its creation and 
   destruction, then the compiler-generated copy constructor will not be 
   sufficient.

   If a destructor is not declared, the compiler generates one. This 
   destructor calls object members' destructors and does nothing for 
   numeric and pointer types. Again, if an object owns a dynamic resource, 
   then the compiler-generated destructor will not be sufficient, as the 
   resource will not be freed when the object is destroyed.

   This is commonly referred to as the "Rule of 3": If an object needs a 
   custom copy constructor, assignment operator or destructor, chances are 
   it needs all three.



------------------------------------------------- ProPgMemberProcedures ----
Member Procedures

Procedures with full access to members of a Type or Class.

Declaration and definition
   Declaring and defining member procedures.
Usage
   Calling member procedures.
The hidden parameter, This
   Implicit access to the instance with which non-static member procedures 
   are called.
Access rights
   Referring to other members in member procedures.
Overloading
   Declaring two or more member procedures with the same name.
Static member procedures
   Differences from non-static member procedures.

   The term 'member procedure' refers to both static and non-static member 
   procedures, unless otherwise noted.

Declaration and definition
   Member procedures are declared much like normal module-level procedures 
   except that they are declared within, and defined outside, a Type or 
   Class definition [1].

   When defining member procedures, the procedure name is prefixed with the 
   name of the Type or Class and the member access operator (
   Operator . (Member Access)). It is an error to define a member procedure 
   without a matching declaration in the Type or Class definition.

   The following example declares and defines a Sub and Function member 
   procedure:

   '' foo1.bi

   Type foo
      Declare Sub f (As Integer)
      Declare Function g As Integer

      i As Integer
   End Type

   Sub foo.f (n As Integer)
      Print n
   End Sub

   Function foo.g As Integer
      Return 420
   End Function

Usage
   Member procedures are referred to just like member data, that is, their 
   name is prefixed with the name of an object instance and the member 
   access operator (Operator . (Member Access)) [2].

   The following example, using the code from the last example, calls Sub 
   and Function member procedures:

   '' ... foo with non-static members as before ...
   #include Once "foo1.bi"

   Dim bar As foo
   bar.f(bar.g())

The hidden parameter, This
   Member procedures actually have an additional parameter than what they 
   are declared with [3]. When they are called, using the name of an 
instance and Operator . (Member Access), a reference to that instance is 
passed along with any other arguments in the call, allowing the member 
procedure direct access to the instance.

   The additional parameter added by the compiler is called This, and since 
   it's a reference, any modifications to This are actually modifications 
   to the instance that was passed to the member procedure when it was 
   called. You can use This just like any other variable, ie., pass it to 
   procedures taking a object of the same type, call other member 
   procedures and access member data using Operator . (Member Access), etc.

   Most of the time, however, using This explicitly is unnecessary; member 
   procedures can refer to other members of the instance which they are 
   passed directly by name, without having to qualify it with This and 
   Operator . (Member Access). The only times when you need to qualify 
   member names with This is when the member name is hidden, for example, 
   by a parameter or local variable. In these situations, qualifying the 
   member name is the only way to refer to these hidden member names.

   Note:
   To access duplicated symbols defined outside the Type, add one (or two) 
   dot(s) as prefix: .SomeSymbol (or ..SomeSymbol if inside a With..End With
   block).

   The following example uses the This keyword to refer to member data 
   whose name is hidden by a parameter and local variable:

   Type foo
      Declare Sub f (i As Integer)
      Declare Sub g ()

      i As Integer = 420
   End Type

   Sub foo.f (i As Integer)
      '' A parameter hides T.i, so it needs to be qualified to be used:
      Print this.i
   End Sub

   Sub foo.g ()
      '' A local variable hides T.i, so it needs to be qualified to be used:
      Dim i As Integer
      Print this.i
   End Sub

Access rights
   Unlike normal module-level procedures, member procedures have full 
   access rights to the members of the Type or Class they are declared in; 
   they can refer to the public, protected and private members of a Type or 
   Class.

Overloading
   A member procedure can be declared to have the same name as another 
   member procedure, provided the parameters are different, either in 
   number or in type. This is referred to as overloading.

   Only the parameters are used to determine if a procedure declaration is 
   a valid overload. For example, a Type or Class could have static and 
   non-static member procedures with the same name, or Sub and Function 
   member procedures with the same name

   Unlike a module-level procedure, which needs to specify the Overload 
   clause in the declaration to allow overloading it, a member procedure is 
   overloadable by default, and does not need the Overload clause.

   Type T
      Declare Sub f
      
      '' Different number of parameters:
      Declare Sub f (As Integer)
      
      '' Different type of parameters:
      Declare Sub f (ByRef As String)
      
      '' Again, parameters are different:
      Declare Function f (As UByte) As Integer
      
      '' following three members would cause an error,
      '' number of parameters and/or types do not differ:

      '' Declare Function f As Integer
      '' Declare Function f (As UByte) As String
      '' Declare Static Function f (As UByte) As Integer

      '' ...
      somedata As Any Ptr
   End Type

Static member procedures
   Static member procedures are declared and defined much in the same way 
   as non-static member procedures, with the Static keyword preceding the 
   declaration and definition.

   Member procedures defined using the Static keyword must be declared with 
   the Static keyword in the Type or Class definition, or a compiler error 
   will occur. Like non-static member procedures, it is an error to define 
   a static member procedure without a matching declaration in the Type or 
   Class definition.

   Do not confuse this with procedure definitions that specify static 
   storage for their variables and objects by appending the Static keyword 
   to the procedure header. The Static keyword can be used in both 
   contexts, however; static member procedures can be defined with static 
   variable and object storage.

   The following example declares two static member procedures, the first 
   of which also has static variable and object storage. Note that the 
   Static keyword is optional in the member procedure definition:

   '' foo2.bi

   Type foo
      Declare Static Sub f (As Integer)
      Declare Static Function g As Integer

      i As Integer
   End Type

   Static Sub foo.f (n As Integer) Static
      Print n
   End Sub
      
   Function foo.g As Integer
      Return 420
   End Function

   Static member procedures can be called like non-static member 
   procedures, qualifying the name of the procedure with the name of an 
   instance and the member access operator (Operator . (Member Access)).

   They can also be called by qualifying the procedure name with the name 
   of the Type or Class they were declared in and the member access 
   operator (Operator . (Member Access)). In other words, an instance is 
   not required in order to call static-member procedures.

   The following example, using the code from the last example, uses both 
   ways to call static member procedures:

   '' ... foo with static members as before ...
   #include Once "foo2.bi"

   Dim bar As foo
   bar.f(foo.g())

   Unlike non-static member procedures, which are declared with an extra 
   This parameter, static member procedures do not get passed an instance 
   when called. Because of this, static member procedures can only refer to 
   constants, enumerations, other static members (data or procedures), 
   etc., without qualifying their names. Static member procedures can still 
   refer to non-static members when qualified with an instance, for 
   example: a parameter or local variable.

   The following example refers to a non-static member from a static 
   procedure:

   Type foo
      Declare Static Sub f (ByRef As foo)

      i As Integer
   End Type

   Sub foo.f (ByRef self As foo)
      '' Ok, self is an instance of foo:
      Print self.i

      '' would cause error
      '' cannot access non-static members, no foo instance:
      '' Print i
   End Sub

[1] In the future, member procedures may be able to be defined within the 
Type or Class definition.
[2] Static member procedures do not require an object instance in order to 
be called.
[3] Static member procedures do not have this extra parameter added by the 
compiler, and so cannot access the object instance from which it was called 
with.



------------------------------------------------------- ProPgProperties ----
Properties

Properties are a special mix of member variable and member procedure. They 
provide a way to set or retrieve values of an object, through normal 
looking assignments or member accesses, but also let the object perform 
actions if it needs to update itself.

Basic properties
   Declaring and using setter and getter properties.
Indexed properties
   Properties with an additional parameter.

Basic properties

   A property is declared similar to a member procedure, except that the 
   Property keyword is used instead of Sub or Function. For example, let's 
   consider a window class for a windowing system or GUI library.

   Type Window
   Private:
      As String title_
   End Type

   Dim As Window w

   In order to set the window's title, a setter property can be added:

   Type Window
      Declare Property title(ByRef s As String)
   Private:
      As String title_
   End Type

   Property Window.title(ByRef s As String)
      this.title_ = s
   End Property

   Dim As Window w
   w.title = "My Window"

   It is very similar to a member Sub, as it takes a parameter and updates 
   the object to the new state based on the parameter. However, the syntax 
   for sending this parameter is a basic assignment, not a function call. 
   By assigning the new value to the title property, the property procedure 
   will automatically be called with the given new value, and can update 
   the window to reflect the change. It is up to the object how to 
   represent the property state internally.

   By design, properties can only be assigned one value at a time, and as a 
   result the property procedure can not have more than one parameter.

   After setting the window title, it should also be possible to retrieve 
   it. Here is how to add a getter property:

   Type Window
      '' setter
      Declare Property title(ByRef s As String)
      '' getter
      Declare Property title() As String
   Private:
      As String title_
   End Type

   '' setter
   Property Window.title(ByRef s As String)
      this.title_ = s
   End Property

   '' getter
   Property Window.title() As String
      Return this.title_
   End Property

   Dim As Window w
   w.title = "My Window"
   Print w.title

   The getter is very similar to a Function. It is supposed to return the 
   current value of the property, and it allows the current value to be 
   calculated from other internal values, if needed. Note that both setter 
   and getter use the same identifier, indicating they handle the same 
   property.

   Just like method overloading, it is possible to specify multiple 
   setters, provided they have different parameter types:

   Type Window
      Declare Property title(ByRef s As String)
      Declare Property title(ByVal i As Integer)
      Declare Property title() As String
   Private:
      As String title_
   End Type

   Property Window.title(ByRef s As String)
      this.title_ = s
   End Property

   Property Window.title(ByVal i As Integer)
      this.title_ = "Number: " & i
   End Property

   Property Window.title() As String
      Return this.title_
   End Property

   Dim As Window w
   w.title = "My Window"
   Print w.title
   w.title = 5
   Print w.title

   In comparison to this example of properties, here is similar code that 
   does not use properties:

   Type Window
      Declare Sub set_title(ByRef s As String)
      Declare Sub set_title(ByVal i As Integer)
      Declare Function get_title() As String
   Private:
      As String title
   End Type

   Sub Window.set_title(ByRef s As String)
      this.title = s
   End Sub

   Sub Window.set_title(ByVal i As Integer)
      this.title = "Number: " & i
   End Sub

   Function Window.get_title() As String
      Return this.title
   End Function

   Dim As Window w
   w.set_title("My Window")
   Print w.get_title()
   w.set_title(5)
   Print w.get_title()

   The code is basically the same, only the syntax is different. Properties 
   are specifically designed to combine the setter/getter concept and the 
   language's normal way of literally assigning and accessing values to a 
   class' member variables. It is up to the programmers to decide which way 
   they prefer.

   Here is an example demonstrating a text user interface window class 
   allowing to set position and title using properties:

   Namespace tui
      Type Point
         Dim As Integer x, y
      End Type

      Type char
         Dim As UByte value
         Dim As UByte Color
      End Type

      Type Window
         '' public
         Declare Constructor _
            ( _
               x As Integer = 1, y As Integer = 1, _
               w As Integer = 20, h As Integer = 5, _
               title As ZString Ptr = 0 _
            )
         
         Declare Destructor

         Declare Sub show

         '' title property
         Declare Property title As String
         Declare Property title( new_title As String )

         '' position properties
         Declare Property x As Integer
         Declare Property x( new_x As Integer )

         Declare Property y As Integer
         Declare Property y( new_y As Integer )

      Private:
         Declare Sub redraw
         Declare Sub remove
         Declare Sub drawtitle

         Dim As String p_title
         Dim As Point Pos
         Dim As Point siz
      End Type

      Constructor Window _
         ( _
            x_ As Integer, y_ As Integer, _
            w_ As Integer, h_ As Integer, _
            title_ As ZString Ptr _
         )

         pos.x = x_
         pos.y = y_
         siz.x = w_
         siz.y = h_

         If( title_ = 0 ) Then
            title_ = @"untitled"
         End If

         p_title = *title_
      End Constructor

      Destructor Window
         Color 7, 0
         Cls
      End Destructor

      Property window.title As String
         title = p_title
      End Property

      Property window.title( new_title As String )
         p_title = new_title
         drawtitle
      End Property

      Property window.x As Integer
         Return pos.x
      End Property

      Property window.x( new_x As Integer )
         remove
         pos.x = new_x
         redraw
      End Property

      Property window.y As Integer
         Property = pos.y
      End Property

      Property window.y( new_y As Integer )
         remove
         pos.y = new_y
         redraw
      End Property

      Sub window.show
         redraw
      End Sub

      Sub window.drawtitle
         Locate pos.y, pos.x
         Color 15, 1
         Print Space( siz.x );
         Locate pos.y, pos.x + (siz.x \ 2) - (Len( p_title ) \ 2)
         Print p_title;
      End Sub

      Sub window.remove
         Color 0, 0
         Var sp = Space( siz.x )
         For i As Integer = pos.y To pos.y + siz.y - 1
            Locate i, pos.x
            Print sp;
         Next
      End Sub

      Sub window.redraw
         drawtitle
         Color 8, 7
         Var sp = Space( siz.x )
         For i As Integer = pos.y + 1 To pos.y + siz.y - 1
            Locate i, pos.x
            Print sp;
         Next
      End Sub
   End Namespace

   Dim win As tui.window = tui.window( 3, 5, 50, 15 )

   win.show
   Sleep 500

   win.title = "Window 1"
   Sleep 250
   win.x = win.x + 10
   Sleep 250

   win.title = "Window 2"
   Sleep 250
   win.y = win.y - 2
   Sleep 250

   Locate 25, 1
   Color 7, 0
   Print "Press any key...";

   Sleep

   Note how updating the window's position or title automatically causes 
   the window to be redrawn.

Indexed properties

   Properties can have an additional parameter that is called an index 
   (currently only one additional parameter is allowed). The index is 
   specified in parentheses behind the property's name, as if the property 
   was an array (with only one dimension). For example:

   Type IntArray
      '' setters
      Declare Property value(index As Integer, v As Integer)
      Declare Property value(index As String, v As Integer)
      Declare Property value(index As Integer, v As String)
      Declare Property value(index As String, v As String)

      '' getters
      Declare Property value(index As Integer) As Integer
      Declare Property value(index As String) As Integer

   Private:
      Dim As Integer data_(0 To 9)
   End Type

   Property IntArray.value(index As Integer) As Integer
      Return This.data_(index)
   End Property

   Property IntArray.value(index As String) As Integer
      Return This.data_(CInt(index))
   End Property

   Property IntArray.value(index As Integer, v As Integer)
      This.data_(index) = v
   End Property

   Property IntArray.value(index As String, v As Integer)
      This.data_(CInt(index)) = v
   End Property

   Property IntArray.value(index As Integer, v As String)
      This.data_(index) = CInt(v)
   End Property

   Property IntArray.value(index As String, v As String)
      This.data_(CInt(index)) = CInt(v)
   End Property

   Dim a As IntArray

   a.value(0) = 1234
   a.value("1") = 5678
   a.value(2) = "-1234"
   a.value("3") = "-5678"

   Print a.value(0)
   Print a.value("1")
   Print a.value(2)
   Print a.value("3")

   Sleep

   This simulates an integer array that can be assigned strings, and even 
   be indexed with strings. See KeyPgProperty for another example.



----------------------------------------------- ProPgMemberAccessRights ----
Member Access Rights

Restricting member access to certain parts of code.

Overview
Public members
Protected members
Private members
Constructors and destructors

Overview
   All members of a Type or Class - including member data, procedures, 
   constants, etc. - belong in one of three different classifications, each 
   with its own rules dictating where in code they may be accessed, or 
   referred to. These rules are called access rights. There are public, 
   protected and private members, and they are declared in a Type or Class 
   definition following a Public, Protected or Private label, respectively.

   By default, that is, without an access classification label, members of 
   a Type are public, and members of a Class are private.

Public members
   Public members can be referred to from anywhere; they are accessible 
   from, for example, member procedures or module-level code or procedures.

Protected members
   Protected members can only be accessed from member procedures of the Type
   or Class they are declared in, or member procedures of a derived Type or 
   Class. They are not accessible to outside code.

Private members
   Private members can only be accessed from member procedures of the Type 
   or Class they are declared in. They are not accessible to outside code 
   or member procedures from a derived Type or Class.

Constructors and destructors
   Constructors and destructors follow the same rules as any other member. 
   When public, objects can be instantiated and destroyed from anywhere in 
   code. When protected, objects can be instantiated and destroyed only 
   from member procedures of their Type or Class or a derived Type or Class.
   Private constructors and destructors restrict object instantiation 
   solely to member procedures of their Type or Class.



---------------------------------------------- ProPgOperatorOverloading ----
Operator Overloading

Changing the way user defined types work with built-in operators.

Overview
Global Operators
Member Operators

Overview
   Simply, operators are procedures, and their arguments are called 
   operands. Operators that take one operand (Operator Not) are called 
   unary operators, operators that take two operands (Operator +) are 
   called binary operators and operators taking three operands (Operator Iif
   ) are called ternary operators.

   Most operators are not called like procedures. Instead, their operator 
   symbol is placed next to their operands. For unary operators, their sole 
   operand is placed to the right of the symbol. For binary operators, 
   their operands - referred to as the left and right-hand side operands - 
   are placed to the left and right of the operator symbol. FreeBASIC has 
   one ternary operator, Operator Iif, and it is called like a procedure, 
   with its operands comma-separated surrounded by parenthesis. For 
   example, the following code calls Operator Iif to determine if a pointer 
   is valid. If it is, Operator * (Value Of) is called to dereference the 
   pointer, and if not, Operator / (Divide) is called to find the value of 
   twenty divided by four.

   Dim i As Integer = 420
   Dim p As Integer Ptr = @i

   Dim result As Integer = IIf( p, *p, CInt( 20 / 4 ) )

   Notice the call to Operator Iif is similar to a procedure call, while 
   the calls to Operator * (Value Of) and Operator / (Divide) are not. In 
   the example, p is the operand to Operator * (Value Of), and 20 and 4 are 
   the left and right-hand side operands of Operator / (Divide), 
   respectively.

   All operators in FreeBASIC are predefined to take operands of standard 
   data types, like Integer and Single, but they may also be overloaded for 
   user-defined types; that is, they can be defined to accept operands that 
   are objects as well. There are two types of operators that can be 
   overloaded, global operators and member operators.

Global Operators
   Global operators are those that are declared in module-level scope 
   (globally). These are the operators - (Negate), Not (Bitwise Not), 
   -> (Pointer To Member Access), * (Value Of), + (Add), - (Subtract), 
   * (Multiply), / (Divide), \ (Integer Divide), & (Concatenate), 
   Mod (Modulus), Shl (Shift Left), Shr (Shift Right), And (Bitwise And), 
   Or (Bitwise Or), Xor (Bitwise Xor), Imp (Bitwise Imp), Eqv (Bitwise Eqv)
   , ^ (Exponentiate), = (Equal), <> (Not Equal), < (Less Than), 
   > (Greater Than), <= (Less Than Or Equal) and >= (Greater Than Or Equal)
   .

   Declaring a custom global operator is similar to declaring a procedure. 
   The Declare keyword is used with the Operator keyword. The operator 
   symbol is placed next followed by the comma-separated list of parameters 
   surrounded in parenthesis that will represent the operands passed to the 
   operator. Unlike procedures, operators can be overloaded by default, so 
   the Overload keyword is not necessary when declaring custom operators. 
   At least one of the operator's parameters must be of user-defined type 
   (after all, operators with built-in type parameters are already 
   defined).

   The following example declares the global operators - (Negate) and 
   + (Multiply) to accept operands of a user-defined type.

   Type Rational
      As Integer numerator, denominator
   End Type

   Operator - (ByRef rhs As Rational) As Rational
      Return Type(-rhs.numerator, rhs.denominator)
   End Operator

   Operator * (ByRef lhs As Rational, ByRef rhs As Rational) As Rational
      Return Type(lhs.numerator * rhs.numerator, _
         lhs.denominator * rhs.denominator)
   End Operator

   Dim As Rational r1 = (2, 3), r2 = (3, 4)
   Dim As Rational r3 = -(r1 * r2)
   Print r3.numerator & "/" & r3.denominator

   Here the global operators are defined for type Rational, and are used in 
   the initialization expression for r3. The output is -6/12.

Member Operators
   Member operators are declared inside a Type or Class definition, like 
   member procedures, and they are the cast and assignment operators 
   Let (Assign), Operator Cast (Cast), += (Add And Assign), 
   -= (Subtract And Assign), *= (Multiply And Assign), 
   /= (Divide And Assign), \= (Integer Divide And Assign), 
   ^= (Exponentiate And Assign), &= (Concat And Assign), 
   Mod= (Modulus And Assign), Shl= (Shift Left And Assign), 
   Shr= (Shift Right And Assign), And= (Conjunction And Assign), 
   Or= (Inclusive Disjunction And Assign), 
   Xor= (Exclusive Disjunction And Assign), Imp= (Implication And Assign) 
   and Eqv= (Equivalence And Assign).

   When declaring member operators, the Declare and Operator keywords are 
   used followed by the operator symbol and its parameter list. Like member 
   procedures, member operators are defined outside the Type or Class 
   definition, and the symbol name is prefixed with the name of the Type or 
   Class name.

   The following example overloads the member operators Operator Cast (Cast)
   and *= (Multiply And Assign) for objects of a user-defined type.

   Type Rational
      As Integer numerator, denominator
      
      Declare Operator Cast () As Double
      Declare Operator Cast () As String
      Declare Operator *= (ByRef rhs As Rational)
   End Type

   Operator Rational.cast () As Double
      Return numerator / denominator
   End Operator

   Operator Rational.cast () As String
      Return numerator & "/" & denominator
   End Operator

   Operator Rational.*= (ByRef rhs As Rational)
      numerator *= rhs.numerator
      denominator *= rhs.denominator
   End Operator

   Dim As Rational r1 = (2, 3), r2 = (3, 4)
   r1 *= r2
   Dim As Double d = r1
   Print r1, d

   Notice that the member operator Cast (Cast) is declared twice, once for 
   the conversion to Double and once for the conversion to String. This is 
   the only operator (or procedure) that can be declared multiple times 
   when only the return type differs. The compiler decides which cast 
   overload to call based on how the object is used (in the initialization 
   of the Double d, Rational.Cast as double is called, and in the Print 
   statement, Rational.Cast as string is used instead).



---------------------------------------------------- ProPgTypeIterators ----
Iterators

The overload Operators For, Next, and Step, allowing to construct 
User-Defined Types Iterators (instead of only intrinsic scalar types 
iterators) for a For...Next loop

Syntax (declaration)
   { Type | Class | Union } typename
      ' For...Next statement with implicit step (1st version of operators)
         Declare Operator For ( )
         Declare Operator Next ( [ ByRef | ByVal ] cond As typename ) As 
         Integer
         Declare Operator Step ( )
      ' For...Next statement with explicit step (2nd version of operators)
         Declare Operator For ( [ ByRef | ByVal ] stp As typename )
         Declare Operator Next ( [ ByRef | ByVal ] cond As typename, [ ByRef
         | ByVal ] stp As typename ) As Integer
         Declare Operator Step ( [ ByRef | ByVal ] stp As typename )
   End { Type | Class | Union }

Usage
   For iterator [ As typename ] = start_value To end_value [ Step 
   step_value ]
      [ ...statements... ]
   Next

   The first version of operators is used if no step_value is given in the 
   For...Next statement.
   If a step_value is given, the second version is used and a step object 
   (initialized with step-value) is passed through the stp parameter:
      - to Operator For because eventual additional initialization may use 
      it,
      - to Operator Next because testing for iterating end may depend on 
      it,
      - to Operator Step to increment the iterator object.
   Both versions of the operators can coexist (thanks to member 
   overloading) in the same user-defined type (to be able to both use and 
   not use the explicit increment in For...Next statements of the user 
   code).

Parameters
   typename
      name of the Type, Class, or Union
   stp, step_value
      a typename object used as an incremental value
   iterator
      a typename object used as an iterator
   cond, end_value
      a typename object used as a loop-terminating value
   start_value
      a typename object used to copy construct or assign to the iterator 
      initially

Description
   Operator For, Operator Next and Operator Step can be overloaded in 
   user-defined type definitions to allow objects of that type to be used 
   as iterators and step values in For...Next loops (instead of the 
   pre-defined for intrinsic scalar types).

   As all non-static member procedures, the 3 operators have passed a 
   hidden This parameter that allows to access by reference to the iterator 
   object (initialized to the start_value argument value from the For...Next
   statement).
   The cond parameter of the Operator Next allows to access the end_value 
   argument value from the For...Next statement.
   If a step_value is given (as argument) in the For...Next statement, the 
   stp parameter allows to access this value in the 3 operators.

   Note: If no step_value is given in the For...Next statement (implicit 
   step), the user-defined type must have a default constructor (implicit 
   or explicit) or a conversion constructor. It is a bug at the moment 
   because if the user defines a default constructor, the compiler does not 
   even use it when initializing the For...Next loop!

   Operator For
      Operator For is called once immediately after copy constructing or 
      assigning to the iterator object (with the start_value), constructing 
      the end object (with the end_value), and constructing the step object 
      (with step_value if defined in the For...Next statement).
      Operator For allows to perform any additional initialization needed 
      in preparation for the loop.

   Operator Next
      Operator Next is called every time the iterator object needs to be 
      checked against the end value. This happens immediately after the 
      call to the Operator For, and then immediately after any calls to the 
      Operator Step.
      Operator Next should return zero (0) if the loop should be 
      terminated, or non-zero if the loop should continue iterating.
      The first time Operator Next is called, no statements in the 
      For...Next body have been executed yet.
      Operator Next also allows to perform some processing before the 
      execution of all statements in the For...Next body.

   Operator Step
      Operator Step is called to increment the iterator object immediately 
      after all statements in the For...Next body are executed.

Algorithm
   For...Next loop algorithm around the 3 overload operators:

   '                       FOR...NEXT loop
   '                              V
   '                              |
   '            constructing/assigning iterator object
   '       (This = start_value from For...Next statement)
   '                              |
   '                   constructing end object
   '       (cond = end_value from For...Next statement)
   '                              |
   '                   if step_value is defined >---------------------.
   '                            else                                  :
   '                              v                                   v
   '                              :                        constructing step object
   '                              :               (stp = step_value from For...Next statement)
   '                              :                                   :
   '                              :<----------------------------------'
   '                              |
   '                    calling Operator For
   '                              |
   '     .----------------------->|
   '     |                        |
   '     |              calling Operator Next
   '     |     (if end-condition verified: =0 returned) >-------------.
   '     |               (else: <>0 returned)                         |
   '     |                        v                                   |
   '     |                        |                                   |
   '     |            executing For...Next body                       |
   '     |                        |                                   |
   '     |              calling Operator Step                         |
   '     |                        |                                   |
   '     '------------------------'                                   |
   '                                                                  |
   '                                                                  V

Example
   Type for iterating through screen resolutions, with implicit step-value:
   Type screenResolution
      ' user interface
         Declare Constructor (ByVal colorBit As Long)
         Declare Property colorDepth () As Long
         Declare Property screenWidth () As Long
         Declare Property screenHeigth () As Long
      ' overload iteration operators when Step is not defined in For...Next statement
         Declare Operator For ()
         Declare Operator Next (ByRef iterateCondition As screenResolution) As Integer
         Declare Operator Step ()
      ' internal variables
         Dim As Long colorBit, resolutionWH
   End Type

   Constructor screenResolution (ByVal colorBit As Long)
      This.colorBit = colorBit
   End Constructor

   Property screenResolution.colorDepth () As Long
      Return This.colorBit
   End Property

   Property screenResolution.screenWidth () As Long
      Return HiWord(This.resolutionWH)
   End Property

   Property screenResolution.screenHeigth () As Long
      Return LoWord(This.resolutionWH)
   End Property

   Operator screenResolution.For ()
      This.resolutionWH = ScreenList(This.colorBit)
   End Operator

   Operator screenResolution.Next (ByRef iterateCondition As screenResolution) As Integer
      While This.resolutionWH = 0
         If This.colorBit < iterateCondition.colorBit Then
            This.colorBit += 1
            This.resolutionWH = ScreenList(This.colorBit)
         Else
            Exit While
         End If
      Wend
      Return (This.resolutionWH <> iterateCondition.resolutionWH)
   End Operator

   Operator screenResolution.Step ()
      This.resolutionWH = ScreenList()
   End Operator

   Print "Screen resolutions supported within [1 bpp , 64 bpp]:"
   For iterator As screenResolution = screenResolution(1) To screenResolution(64)
      Print "    " & iterator.colorDepth & " bpp ",
      Print ":" & iterator.screenWidth & "x" & iterator.screenHeigth
   Next iterator
   Print "End of supported screen resolutions"

   Sleep
         
Output example:

   Screen resolutions supported within [1 bpp , 64 bpp]:
   	24 bpp    :320x200
   	24 bpp    :320x240
   	24 bpp    :400x300
   	24 bpp    :512x384
   	24 bpp    :640x400
   	24 bpp    :640x480
   	24 bpp    :800x600
   	24 bpp    :1024x768
   	24 bpp    :1152x864
   	24 bpp    :1280x600
   	24 bpp    :1280x720
   	24 bpp    :1280x768
   	24 bpp    :1280x800
   	24 bpp    :1280x960
   	24 bpp    :1280x1024
   	24 bpp    :1360x768
   	24 bpp    :1366x768
   	24 bpp    :1400x1050
   	24 bpp    :1440x900
   	24 bpp    :1600x900
   	24 bpp    :1680x1050
   	24 bpp    :1920x1080
   	32 bpp    :320x200
   	32 bpp    :320x240
   	32 bpp    :400x300
   	32 bpp    :512x384
   	32 bpp    :640x400
   	32 bpp    :640x480
   	32 bpp    :800x600
   	32 bpp    :1024x768
   	32 bpp    :1152x864
   	32 bpp    :1280x600
   	32 bpp    :1280x720
   	32 bpp    :1280x768
   	32 bpp    :1280x800
   	32 bpp    :1280x960
   	32 bpp    :1280x1024
   	32 bpp    :1360x768
   	32 bpp    :1366x768
   	32 bpp    :1400x1050
   	32 bpp    :1440x900
   	32 bpp    :1600x900
   	32 bpp    :1680x1050
   	32 bpp    :1920x1080
   End of supported Screen resolutions

   Type for iterating through fractions, with explicit step-value used in 
   the 3 operators:
   (improved example compared to the one of Operator Step page)
   Type fraction
      ' user interface
         Declare Constructor (ByVal n As Integer, ByVal d As Integer)
         Declare Operator Cast () As String
      ' overload iteration operators when Step is defined in For...Next statement
         Declare Operator For (ByRef iterateStep As fraction)
         Declare Operator Next (ByRef iterateCondition As fraction, ByRef iterateStep As fraction) As Integer
         Declare Operator Step (ByRef step_var As fraction)
      ' internal variables and cast operator
         As Integer num, den
         Declare Operator Cast () As Double
   End Type

   Constructor fraction (ByVal n As Integer, ByVal d As Integer)
      this.num = n
      this.den = d
   End Constructor

   Operator fraction.Cast () As String
      ' search for the highest common factor (a) between numerator and denominator
         Dim As Integer a = Abs(This.num), b = Abs(This.den)
         If a <> 0 Then
            While a <> b 
               If a > b Then
                  a -= b
               Else
                  b -= a
               End If
            Wend
         Else
            a = 1
         End If
      ' reduce the fraction
         Return num \ a & "/" & den \ a
   End Operator

   Operator fraction.Cast () As Double
      Return This.num / This.den
   End Operator

   Operator fraction.For (ByRef iterateStep As fraction)
      ' search for the least common multiple (a) between the two denominators
         Dim As Integer a = Abs(This.den), b = Abs(iterateStep.den), c = a, d = b
         While a <> b
            If a > b Then
               b += d
            Else
               a += c
            End If
         Wend
      ' align at the same denominator the 2 fractions
         This.num *= a \ This.den
         This.den = a
         iterateStep.num *= a \ iterateStep.den
         iterateStep.den = a
   End Operator

   Operator fraction.Next (ByRef iterateCondition As fraction, ByRef iterateStep As fraction) As Integer
      If iterateStep.num < 0 Or iterateStep.den < 0 Then
         Return This >= iterateCondition
      Else
         Return This <= iterateCondition
      End If
   End Operator

   Operator fraction.Step (ByRef iterateStep As fraction)
      This.num += iterateStep.num
   End Operator 

   Print "iteration from 1/8 to 1/2 by step of 1/12:"
   For iterator As fraction = fraction(1, 8) To fraction(1, 2) Step fraction(1, 12)
      Print "    " & iterator;
   Next
   Print
   Print
   Print "iteration from 7/10 to -8/5 by step of -8/15:"
   For iterator As fraction = fraction(7, 10) To fraction(-8, 5) Step fraction(-8, 15)
      Print "    " & iterator;
   Next
   Print

   Sleep
         
Output:

   iteration from 1/8 To 1/2 by Step of 1/12:
   	1/8    5/24    7/24    3/8    11/24
   	
   iteration from 7/10 To -8/5 by Step of -8/15:
   	7/10    1/6    -11/30    -9/10    -43/30

See also
   * For...Next
   * Operator



-------------------------------------------------------- ProPgNewDelete ----
New and Delete

The different operators New (Implicit/Overload/Expression/Placement) and Del
ete (Implicit/Overload/Statement), and all their array-versions New[] and De
lete[]

Definition
   There may be confusion in the user mind between the different operators 
   New and Delete (despite the documentation that distinguishes them from 
   each other through some different pages):
      * 'Operator New Implicit' (inaccessible by user):
            - It is a static function that only allocates memory (it is not 
            very different from Allocate).
      * Operator New Overload:
            - It is a member operator (static function) that can overload 
            the 'Operator New Implicit' only for user-defined types.
            - So the user can define its own dynamic memory allocation 
            process part (the following process part for implicit data 
            construction can not be modified).
      * 'Operator Delete Implicit' (inaccessible by user):
            - It is a static sub that only frees the memory (it is not very 
            different from Deallocate).
      * Operator Delete Overload:
            - It is a member operator (static sub) that can overload the 
            'Operator Delete Implicit' only for user-defined types.
            - So the user can define its own memory deallocation process 
            part (the previous process part for implicit data destruction 
            can not be modified).
      * Operator New Expression:
            - It starts by using the 'Operator New Implicit/Overload' (the 
            implicit, or the overload if exists) to allocate memory.
            - Then it invokes the constructor for the right type of object. 
            If that object contains any other objects (either embedded or 
            as base types) those constructors as invoked as well.
            - So the final result is memory allocated and object 
            constructed.
            - This operator applies to pre-defined types (except 
            fixed-length strings) as well as user-defined types.
      * Operator Delete Statement:
            - It starts by invoking the destructor for the right type of 
            object. If that object contains any other objects (either 
            embedded or as base types) those destructors as invoked as 
            well.
            - Then it uses the 'Operator Delete Implicit/Overload' (the 
            implicit, or the overload if exists) to deallocate memory.
            - So the final result is object destroyed and memory freed.
            - This operator applies to pre-defined types (except 
            fixed-length strings) as well as user-defined types.
      * Operator Placement New:
            - It only constructs object at a specified memory address 
            (already allocated). This operator applies to pre-defined types 
            (except fixed-length strings) as well as user-defined types.

   Similar definition for 'Operator New[] Implicit/Overload/Expression', 
   'Operator Delete[] Implicit/Overload/Statement' and 'Operator Placement 
   New[]', which are only the (one-dimensional) array-versions of the 
   previous operators (there is construction/destruction loop on the array 
   elements).

   Instances created with 'Operator New Overload/Expression' must be freed 
   with 'Operator Delete Overload/Statement'.
   Instance array created with 'Operator New[] Overload/Expression' must be 
   freed with 'Operator Delete[] Overload/Statement', the array-version of 
   'Operator Delete Overload/Statement'.
   User can not mix and match the different versions of the operators.

Algorithm (applied to user-defined types)
   Operator New/New[] Expression:

   '       OPERATOR NEW/NEW[] EXPRESSION
   '                     V
   '                     |
   '              call if there is >----------------------------.
   '                   else                                     :
   '                     v                                      v
   '       (Operator New/New[] Implicit)          (Operator New/New[] Overload)
   '                     :                                      :
   '          BASIC MEMORY ALLOCATION                       USER BODY
   '                     :                                      :
   '                     :<-------------------------------------'
   '                     |
   '                     |<-------------------------------------.
   '                     |                                      :
   '        DATA FIELDS INITIALIZATION                          :
   '        OBJECT FIELDS CONSTRUCTION                          :
   '           (VPTR INITIALIZATION)                            :
   '                     |                                      :
   '              call if there is >-----------.                :
   '                   else                    :                :
   '                     v                     v                :
   '                     :            (User Constructor)        :
   '                     :                     :                :
   '                     :                 USER BODY            :
   '                     :                     :                :
   '                     :<--------------------'                :
   '                     |                                      :
   '        loop if array-version NEW[] >-----------------------'
   '                   else
   '                     v
   '                     |
   '                     V

   Operator Delete/Delete[] Statement:

   '     OPERATOR DELETE/DELETE[] STATEMENT
   '                     V
   '                     |
   '                     |<-------------------------------------.
   '                     |                                      :
   '          (VPTR REINITIALIZATION)                           :
   '                     |                                      :
   '              call if there is >-----------.                :
   '                   else                    :                :
   '                     v                     v                :
   '                     :             (User Destructor)        :
   '                     :                     :                :
   '                     :                 USER BODY            :
   '                     :                     :                :
   '                     :<--------------------'                :
   '                     |                                      :
   '         OBJECT FIELDS DESTRUCTION                          :
   '                     |                                      :
   '       loop if array-version DELETE[] >---------------------'
   '                   else
   '                     v
   '                     |
   '              call if there is >----------------------------.
   '                   else                                     :
   '                     v                                      v
   '    (Operator Delete/Delete[] Implicit)    (Operator Delete/Delete[] Overload)
   '                     :                                      :
   '         BASIC MEMORY DEALLOCATION                      USER BODY
   '                     :                                      :
   '                     :<-------------------------------------'
   '                     |
   '                     V

   Operator Placement New/New[]:

   '        OPERATOR PLACEMENT NEW/NEW[]
   '                     V
   '                     |
   '                     |<-------------------------------------.
   '                     |                                      :
   '        DATA FIELDS INITIALIZATION                          :
   '        OBJECT FIELDS CONSTRUCTION                          :
   '           (VPTR INITIALIZATION)                            :
   '                     |                                      :
   '              call if there is >-----------.                :
   '                   else                    :                :
   '                     v                     v                :
   '                     :             (User Constructor)       :
   '                     :                     :                :
   '                     :                 USER BODY            :
   '                     :                     :                :
   '                     :<--------------------'                :
   '                     |                                      :
   '        loop if array-version NEW[] >-----------------------'
   '                   else
   '                     v
   '                     |
   '                     V

Example
   Example that uses the operators New (Overload/Expression/Placement) and 
   Delete (Overload/Statement), and all their array-versions New[] and 
   Delete[]:
   (all the 10 operators New and Delete accessible by the user):
   Declare Sub printArray (ByRef label As String = "", array() As String)

   Type UDT
      Declare Constructor ()
      Declare Destructor ()
      Declare Operator New (ByVal size As UInteger) As Any Ptr    ' Operator New Overload
      Declare Operator New[] (ByVal size As UInteger) As Any Ptr  ' Operator New[] Overload
      Declare Operator Delete (ByVal buf As Any Ptr)              ' Operator Delete Overload
      Declare Operator Delete[] (ByVal buf As Any Ptr)            ' Operator Delete[] Overload
      Dim As String array (1 To 4)
   End Type

   Constructor UDT ()
      Static As Integer n
      Print "    Constructor"
      printArray("        init: @" & @This & " (descriptors) -> ", This.array())
      For i As Integer = LBound(This.array) To UBound(This.array)
         This.array(i) = Chr(Asc("a") + n + i - LBound(This.array))
      Next i
      printArray(" => ", This.array())
      Print
      n += UBound(This.array)- LBound(This.array) + 1
   End Constructor

   Destructor UDT ()
      Print "    Destructor"
      printArray("        erase: @" & @This & " (descriptors) -> ", This.array())
      Erase This.array
      printArray(" => ", This.array())
      Print
   End Destructor

   Operator UDT.New (ByVal size As UInteger) As Any Ptr
      Print "    Operator New Overload"
      Dim As Any Ptr p = Allocate(size)                   ' Memory allocation (with passed size)
      Print "        memory allocation: ";
      Print size & " Bytes from @" & p
      Return p                                            ' Returning memory pointer
   End Operator

   Operator UDT.New[] (ByVal size As UInteger) As Any Ptr
      Print "    Operator New[] Overload"
      Dim As Any Ptr p = Allocate(size)                   ' Memory allocation (with passed size)
      Print "        memory allocation: ";
      Print size & " Bytes from @" & p
      Return p                                            ' Returning memory pointer
   End Operator

   Operator UDT.Delete (ByVal buf As Any Ptr)
      Print "    Operator Delete Overload"
      Deallocate(buf)                                     ' Memory deallocation (with passed pointer)
      Print "        memory deallocation: ";
      Print "for @" & buf
   End Operator

   Operator UDT.Delete[] (ByVal buf As Any Ptr)
      Print "    Operator Delete[] Overload"
      Deallocate(buf)                                     ' Memory deallocation (with passed pointer)
      Print "        memory deallocation: ";
      Print "for @" & buf
   End Operator

   Print "Operator New Expression"
   Dim As UDT Ptr pu1 = New UDT         ' Operator New Expression
   Print "Operator Delete Statement"
   Delete pu1                           ' Operator Delete Statement
   Sleep

   Print
   Print "Operator New[] Expression"      
   Dim As UDT Ptr pu2 = New UDT[2]      ' Operator New[] Expression
   Print "Operator Delete[] Statement"
   Delete[] pu2                         ' Operator Delete[] Statement
   Sleep

   Dim As Byte buffer(1 To 256)
   Dim As Any Ptr p = @buffer(1)

   Print
   Print "Operator Placement New"
   Dim As UDT Ptr pu3 = New(p) UDT      ' Operator Placement New
   Print "User call of Destructor"
   pu3->Destructor()                    ' User Call of Destructor
   Sleep

   Print
   Print "Operator Placement New[]"
   Dim As UDT Ptr pu4 = New(p) UDT[2]   ' Operator Placement New[]
   For i As Integer = 0 To 1
      Print "User Call of Destructor"
      pu4[i].Destructor()              ' User Call of Destructor
   Next i
   Sleep

   Sub printArray (ByRef label As String = "", array() As String)
      Print label & "{";
      For i As Integer = LBound(array) To UBound(array)
         Print """" & array(i) & """";
         If i < UBound(array) Then
            Print ",";
         End If
      Next I
      Print "}";
   End Sub

Output example:

   Operator New Expression
   	Operator New Overload
   		memory allocation: 96 Bytes from @1728352
   	Constructor
   		init: @1728352 (descriptors) -> {"","","",""} => {"a","b","c","d"}
   Operator Delete Statement
   	Destructor
   		Erase: @1728352 (descriptors) -> {"a","b","c","d"} => {"","","",""}
   	Operator Delete Overload
   		memory deallocation: For @1728352


   Operator New[] Expression
   	Operator New[] Overload
   		memory allocation: 200 Bytes from @1728352
   	Constructor
   		init: @1728360 (descriptors) -> {"","","",""} => {"e","f","g","h"}
   	Constructor
   		init: @1728456 (descriptors) -> {"","","",""} => {"i","j","k","l"}
   Operator Delete[] Statement
   	Destructor
   		Erase: @1728456 (descriptors) -> {"i","j","k","l"} => {"","","",""}
   	Destructor
   		Erase: @1728360 (descriptors) -> {"e","f","g","h"} => {"","","",""}
   	Operator Delete[] Overload
   		memory deallocation: For @1728352


   Operator Placement New
   	Constructor
   		init: @1375248 (descriptors) -> {"","","",""} => {"m","n","o","p"}
   User Call of Destructor
   	Destructor
   		Erase: @1375248 (descriptors) -> {"m","n","o","p"} => {"","","",""}


   Operator Placement New[]
   	Constructor
   		init: @1375248 (descriptors) -> {"","","",""} => {"q","r","s","t"}
   	Constructor
   		init: @1375344 (descriptors) -> {"","","",""} => {"u","v","w","x"}
   User Call of Destructor
   	Destructor
   		Erase: @1375248 (descriptors) -> {"q","r","s","t"} => {"","","",""}
   User Call of Destructor
   	Destructor
   		Erase: @1375344 (descriptors) -> {"u","v","w","x"} => {"","","",""}

See also
   * Operator
   * Constructor
   * Destructor



------------------------------------------------------ ProPgTypeObjects ----
Types as Objects

An example of the overloadable operators and member procedures

Description
!!! WRITEME !!!

   '' Sample Type showing available methods and operators
   '' Practically this is a pointless example, as the only
   '' data member is an Integer.  It serves only as a
   '' guide to syntax.
   ''
   '' There are many other combinations that can be
   '' used in passed parameters.  For simplicity
   '' This example only uses byref and type T
   '' where ever possible.

   '' The type 'DataType' is included to show where
   '' any data type might be used
   Type DataType As Integer

   '' The type 'UDT' is included to show where only 
   '' a UDT data type can be used
   Type UDT
     value As DataType
   End Type

   '' Our main type
   Type T
     value As DataType
     value_array( 0 ) As DataType

     '' let, cast, combined assignment operators,
     '' constructors, and the destructor, must be
     '' declared inside the type.
     ''
     '' Parameters can be passed Byval or Byref
     '' in most (All? - verify this).
     ''
     '' All procs can be overloaded with different
     '' types as parameters.  In many cases this is not
     '' necessary as the TYPE can be coerced and
     '' converted depending on the CAST methods
     '' it exposes.  The compiler will to its best
     '' to evaluate statements and expressions if
     '' there is enough information to complete
     '' the operation.
     ''
     '' For example,
     '' Even though operator += may not be overloaded
     '' but operator let and operator + are, the
     '' compiler will convert the T += datatype
     '' to T = T + datatype.

     '' Nonstatic members must be declared inside the
     '' type.
     ''
     '' All Nonstatic members are implicitly
     '' passed a hidden **this** parameter having
     '' the same type as the TYPE in which they are
     '' declared.
     ''
     '' Nonstatic member overloaded operators do not
     '' return a type.  All operations are done on the
     '' hidden this parameter.
     ''
     '' Properties: Can be value properties or single
     '' indexed value properties
     '' GET/SET methods must be each delcared if used.

     '' Nonstatic Member Declarations:

     '' Memory Allocation/Deallocation
     
     Declare Operator New ( ByVal size As UInteger ) As Any Ptr
     Declare Operator New[] ( ByVal size As UInteger ) As Any Ptr
     Declare Operator Delete ( ByVal buf As Any Ptr )
     Declare Operator Delete[] ( ByVal buf As Any Ptr )

     '' Assignment

     Declare Operator Let ( ByRef rhs As T )
     Declare Operator Let ( ByRef rhs As DataType )

     '' Cast can be overloaded to return multiple types

     Declare Operator Cast () As String
     Declare Operator Cast () As DataType

     '' Combined assignment

     Declare Operator += ( ByRef rhs As T )
     Declare Operator += ( ByRef rhs As DataType )
     Declare Operator -= ( ByRef rhs As DataType )
     Declare Operator *= ( ByRef rhs As DataType )
     Declare Operator /= ( ByRef rhs As DataType )
     Declare Operator \= ( ByRef rhs As DataType )
     Declare Operator Mod= ( ByRef rhs As DataType )
     Declare Operator Shl= ( ByRef rhs As DataType )
     Declare Operator Shr= ( ByRef rhs As DataType )
     Declare Operator And= ( ByRef rhs As DataType )
     Declare Operator Or= ( ByRef rhs As DataType )
     Declare Operator Xor= ( ByRef rhs As DataType )
     Declare Operator Imp= ( ByRef rhs As DataType )
     Declare Operator Eqv= ( ByRef rhs As DataType )
     Declare Operator ^= ( ByRef rhs As DataType )
     Declare Operator &= ( ByRef rhs As DataType )
     
     '' Address of

     Declare Operator @ () As DataType Ptr

     '' Constructors can be overloaded

     Declare Constructor ()
     Declare Constructor ( ByRef rhs As T )
     Declare Constructor ( ByRef rhs As DataType )

     '' There can be only one destructor

     Declare Destructor ()

     '' Nonstatic member functions and subs
     '' overloaded procs must have different parameters

     Declare Function f ( ) As DataType
     Declare Function f ( ByRef arg1 As DataType ) As DataType

     Declare Sub s ( )
     Declare Sub s ( ByRef arg1 As T )
     Declare Sub s ( ByRef arg1 As DataType )

     '' Properties

     Declare Property p () As DataType
     Declare Property p ( ByRef new_value As DataType )

     Declare Property pidx ( ByVal index As DataType ) As DataType
     Declare Property pidx ( ByVal index As DataType, ByRef new_value As DataType )

     '' Iterator
     
     Declare Operator For ()
     Declare Operator Step ()
     Declare Operator Next ( ByRef cond As T ) As Integer

     Declare Operator For ( ByRef stp As T )
     Declare Operator Step ( ByRef stp As T )
     Declare Operator Next ( ByRef cond As T, ByRef stp As T ) As Integer

   End Type

   '' These must be global procedures
   '' Globals are not prefixed with the the TYPE name

   '' At least one parameter must be of Type 'T'
   '' For simplicity, type 'T' is always given first for binary ops
   '' in this example

   Declare Operator - ( ByRef rhs As T ) As DataType
   Declare Operator Not ( ByRef rhs As T ) As DataType

   Declare Operator -> ( ByRef rhs As T ) As UDT
   Declare Operator * ( ByRef rhs As T ) As DataType

   Declare Operator + ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
   Declare Operator - ( ByRef lhs As T, ByRef rhs As DataType ) As DataType 
   Declare Operator * ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
   Declare Operator / ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
   Declare Operator \ ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
   Declare Operator Mod ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
   Declare Operator Shl ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
   Declare Operator Shr ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
   Declare Operator And ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
   Declare Operator Or ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
   Declare Operator Xor ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
   Declare Operator Imp ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
   Declare Operator Eqv ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
   Declare Operator ^ ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
   Declare Operator = ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
   Declare Operator <> ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
   Declare Operator < ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
   Declare Operator > ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
   Declare Operator <= ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
   Declare Operator >= ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
   Declare Operator & ( ByRef lhs As T, ByRef rhs As DataType ) As DataType

   Declare Operator Abs ( ByRef arg As UDT ) As Double
   Declare Operator Fix ( ByRef arg As UDT ) As Double
   Declare Operator Frac ( ByRef arg As UDT ) As Double
   Declare Operator Int ( ByRef arg As UDT ) As Double
   Declare Operator Sgn ( ByRef arg As UDT ) As Double

   '' Global procedures (subs and funcs) can also accept the TYPE
   '' as a parameter or return it as a value, as could be done
   '' in previous versions of FreeBASIC.
   '' No example given. See function or sub in the manual.

   '' All TYPE members are defined outside the TYPE

   '' Nonstatic members must be prefixed with type name
   '' in this case 'T'

   '' Name resolution in a NAMESPACE is same as other
   '' subs/funcs.  Use USING or prefix the namespace name

   Operator T.new ( ByVal size As UInteger ) As Any Ptr
      Operator = Allocate( size )
   End Operator
    
   Operator T.new[] ( ByVal size As UInteger ) As Any Ptr
      Operator = Allocate( size )
   End Operator

   Operator T.delete ( ByVal buf As Any Ptr )
      Deallocate buf
   End Operator

   Operator T.delete[] ( ByVal buf As Any Ptr )
      Deallocate buf
   End Operator

   Operator T.let ( ByRef rhs As T )
     value = rhs.value  
   End Operator

   Operator T.let ( ByRef rhs As DataType )
     value = rhs  
   End Operator

   Operator T.cast ( ) As String
     Return Str( value )
   End Operator

   Operator T.cast ( ) As DataType
     Return value
   End Operator

   Operator T.+= ( ByRef rhs As T )
     value += rhs.value
   End Operator

   Operator T.+= ( ByRef rhs As DataType )
     value += rhs
   End Operator

   Operator T.-= ( ByRef rhs As DataType )
     value -= rhs
   End Operator

   Operator T.*= ( ByRef rhs As DataType )
     value *= rhs
   End Operator

   Operator T./= ( ByRef rhs As DataType )
     value /= rhs
   End Operator

   Operator T.\= ( ByRef rhs As DataType )
     value \= rhs
   End Operator

   Operator T.mod= ( ByRef rhs As DataType )
     value Mod= rhs
   End Operator

   Operator T.shl= ( ByRef rhs As DataType )
     value Shl= rhs
   End Operator

   Operator T.shr= ( ByRef rhs As DataType )
     value Shr= rhs
   End Operator

   Operator T.and= ( ByRef rhs As DataType )
     value And= rhs
   End Operator

   Operator T.or= ( ByRef rhs As DataType )
     value Or= rhs
   End Operator

   Operator T.xor= ( ByRef rhs As DataType )
     value Xor= rhs
   End Operator

   Operator T.imp= ( ByRef rhs As DataType )
     value Imp= rhs
   End Operator

   Operator T.eqv= ( ByRef rhs As DataType )
     value Eqv= rhs
   End Operator

   Operator T.^= ( ByRef rhs As DataType )
     value ^= rhs
   End Operator

   Operator T.&= ( ByRef rhs As DataType )
     Dim tmp As String
     tmp &= Str( rhs )
   End Operator

   Operator T.@ () As DataType Ptr
     Return( Cast( DataType Ptr, @This ))
   End Operator

   '' Constructors:

   Constructor T ()
     '' default constructor
     value = 0
   End Constructor

   Constructor T ( ByRef rhs As T )
     '' copy constructor
     value = rhs.value
   End Constructor

   Constructor T ( ByRef rhs As DataType )
     '' custom constructor
     value = rhs
   End Constructor

   '' There can be only one destructor

   Destructor T ()
     '' clean-up, none in this example
   End Destructor

   '' Globals must specify all arguments and return type

   Operator - ( ByRef rhs As T ) As DataType
     Return (-rhs.value)
   End Operator

   Operator Not ( ByRef rhs As T ) As DataType
     Return (Not rhs.value)
   End Operator

   Operator -> ( ByRef rhs As T ) As UDT
     Return Type(4)
   End Operator

   Operator * ( ByRef rhs As T ) As DataType
     Return 5
   End Operator

   Operator + ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
     Return (lhs.value + rhs)
   End Operator

   Operator - ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
     Return (lhs.value - rhs)
   End Operator

   Operator * ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
     Return (lhs.value * rhs)
   End Operator

   Operator / ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
     Return (lhs.value / rhs)
   End Operator

   Operator \ ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
     Return (lhs.value \ rhs)
   End Operator

   Operator Mod ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
     Return (lhs.value Mod rhs)
   End Operator

   Operator Shl ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
     Return (lhs.value Shl rhs)
   End Operator

   Operator Shr ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
     Return (lhs.value Shr rhs)
   End Operator

   Operator And ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
     Return (lhs.value And rhs)
   End Operator

   Operator Or ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
     Return (lhs.value Or rhs)
   End Operator

   Operator Xor ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
     Return (lhs.value Xor rhs)
   End Operator

   Operator Imp ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
     Return (lhs.value Imp rhs)
   End Operator

   Operator Eqv ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
     Return (lhs.value Eqv rhs)
   End Operator

   Operator ^ ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
     Return (lhs.value ^ rhs)
   End Operator

   Operator = ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
     Return (lhs.value = rhs)
   End Operator

   Operator <> ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
     Return (lhs.value <> rhs)
   End Operator

   Operator < ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
     Return (lhs.value < rhs)
   End Operator

   Operator > ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
     Return (lhs.value > rhs)
   End Operator

   Operator <= ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
     Return (lhs.value <= rhs)
   End Operator

   Operator >= ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
     Return (lhs.value >= rhs)
   End Operator

   Operator & ( ByRef lhs As T, ByRef rhs As DataType ) As DataType
     Return Val(lhs.value & rhs)
   End Operator

   Operator Abs ( ByRef arg As UDT ) As Double
      Return Abs(arg.value)
   End Operator

   Operator Fix ( ByRef arg As UDT ) As Double
      Return Fix(arg.value)
   End Operator

   Operator Frac ( ByRef arg As UDT ) As Double
      Return Frac(arg.value)
   End Operator

   Operator Int ( ByRef arg As UDT ) As Double
      Return Int(arg.value)
   End Operator

   Operator Sgn ( ByRef arg As UDT ) As Double
      Return Sgn(arg.value)
   End Operator

   '' Nonstatic member methods

   Function T.f ( ) As DataType
     Dim x As DataType
     Return x
   End Function

   Function T.f ( ByRef arg1 As DataType ) As DataType
     arg1 = this.value
     Return value
   End Function

   Sub T.s ( )
     '' refer to the type using
     
     '' with block
     With This
      .value = 1
     End With
     
     '' field access
     this.value = 2
     
     '' directly
     value = 3

   End Sub

   Sub T.s ( ByRef arg1 As T )
     value = arg1.value
   End Sub

   Sub T.s ( ByRef arg1 As DataType )
     value = arg1
   End Sub

   Property T.p () As DataType
     '' GET property
     Return value
   End Property

   Property T.p ( ByRef new_value As DataType )
     '' SET property
     value = new_value
   End Property

   Property T.pidx ( ByVal index As DataType ) As DataType
     '' GET indexed property
     Return value_array( index )
   End Property

   Property T.pidx ( ByVal index As DataType, ByRef new_value As DataType )
     '' SET indexed property
     value_array( index ) = new_value
   End Property

   Operator T.for ()
   End Operator

   Operator T.step ()
   End Operator

   Operator T.next ( ByRef cond As T ) As Integer
     Return 0
   End Operator

   Operator T.for ( ByRef stp As T )
   End Operator 

   Operator T.step ( ByRef stp As T )
   End Operator

   Operator T.next ( ByRef cond As T, ByRef stp As T ) As Integer
     Return 0
   End Operator

   '' new, delete, delete[]

   '' Allocate object
   Dim X As T Ptr = New T

   '' Deallocate object
   Delete X

   '' Allocate object vector
   Dim Xlist As T Ptr = New T[10]

   '' Deallocate object vector
   Delete[] Xlist

See also
   * Type




============================================================================
    Statements and Expressions

---------------------------------------------------------- OpPrecedence ----
Operator Precedence

   When several operations occur in a single expression, each operation is 
   evaluated and resolved in a predetermined order. This is called the 
   order of operation or operator precedence. 

   If an operator in an expression has a higher precedence, it is evaluated 
   before an operator of lower precedence. 

   If operators have equal precedence, they then are evaluated in the order 
   in of their associativity.  The associativity may be Left-to-Right or 
   Right-to-Left order.

   As a rule, binary operators (such as +, ^) and unary postfix operators 
   (such as (), ->) are evaluated Left-to-Right, and unary prefix operators 
   (such as Not, @) are evaluated Right-to-Left.

   Operators that have an associativity of "N/A" indicate that there is no 
   expression in which the operator can be used where its order of 
   operation would need to be checked, either by precedence or by 
   associativity.  Function-like operators such as Cast are always the 
   first to be evaluated due to the parentheses required in their syntax.  
   And assignment operators are always the last to be evaluated.

   Parentheses can be used to override operator precedence. Operations 
   within parentheses are performed before other operations. Within the 
   parentheses normal operator precedence is used.

   The following table lists operator precedence from highest to lowest.  
   Breaks in the table mark the groups of operators having equal 
   precedence.

Highest Precedence

      +--------+-----------------------------------+-------------+
      |Operator|Description                        |Associativity|
      |        |                                   |             |
      |CAST    |Type Conversion                    |N/A          |
      |PROCPTR |Procedure pointer                  |N/A          |
      |STRPTR  |String pointer                     |N/A          |
      |VARPTR  |Variable pointer                   |N/A          |
      |        |                                   |             |
      |[]      |String index                       |Left-to-Right|
      |[]      |Pointer index                      |Left-to-Right|
      |()      |Array index                        |Left-to-Right|
      |()      |Function Call                      |Left-to-Right|
      |.       |Member access                      |Left-to-Right|
      |->      |Pointer to member access           |Left-to-Right|
      |        |                                   |             |
      |@       |Address of                         |Right-to-Left|
      |*       |Value of                           |Right-to-Left|
      |New     |Allocate Memory                    |Right-to-Left|
      |Delete  |Deallocate Memory                  |Right-to-Left|
      |        |                                   |             |
      |^       |Exponentiate                       |Left-to-Right|
      |        |                                   |             |
      |-       |Negate                             |Right-to-Left|
      |        |                                   |             |
      |*       |Multiply                           |Left-to-Right|
      |/       |Divide                             |Left-to-Right|
      |        |                                   |             |
      |\       |Integer divide                     |Left-to-Right|
      |        |                                   |             |
      |MOD     |Modulus                            |Left-to-Right|
      |        |                                   |             |
      |SHL     |Shift left                         |Left-to-Right|
      |SHR     |Shift right                        |Left-to-Right|
      |        |                                   |             |
      |+       |Add                                |Left-to-Right|
      |-       |Subtract                           |Left-to-Right|
      |        |                                   |             |
      |&       |String concatenation               |Left-to-Right|
      |        |                                   |             |
      |Is      |Run-time type information check    |N/A          |
      |        |                                   |             |
      |=       |Equal                              |Left-to-Right|
      |<>      |Not equal                          |Left-to-Right|
      |<       |Less than                          |Left-to-Right|
      |<=      |Less than or equal                 |Left-to-Right|
      |>=      |Greater than or equal              |Left-to-Right|
      |>       |Greater than                       |Left-to-Right|
      |        |                                   |             |
      |NOT     |Complement                         |Right-to-Left|
      |        |                                   |             |
      |AND     |Conjunction                        |Left-to-Right|
      |        |                                   |             |
      |OR      |Inclusive Disjunction              |Left-to-Right|
      |        |                                   |             |
      |EQV     |Equivalence                        |Left-to-Right|
      |IMP     |Implication                        |Left-to-Right|
      |XOR     |Exclusive Disjunction              |Left-to-Right|
      |        |                                   |             |
      |ANDALSO |Short Circuit Conjunction          |Left-to-Right|
      |ORELSE  |Short Circuit Inclusive Disjunction|Left-to-Right|
      |        |                                   |             |
      |=[>]    |Assignment                         |N/A          |
      |&=      |Concatenate and Assign             |N/A          |
      |+=      |Add and Assign                     |N/A          |
      |-=      |Subtract and Assign                |N/A          |
      |*=      |Multiply and Assign                |N/A          |
      |/=      |Divide and Assign                  |N/A          |
      |\=      |Integer Divide and Assign          |N/A          |
      |^=      |Exponentiate and Assign            |N/A          |
      |MOD=    |Modulus and Assign                 |N/A          |
      |AND=    |Conjunction and Assign             |N/A          |
      |EQV=    |Equivalence and Assign             |N/A          |
      |IMP=    |Implication and Assign             |N/A          |
      |OR=     |Inclusive Disjunction and Assign   |N/A          |
      |XOR=    |Exclusive Disjunction and Assign   |N/A          |
      |SHL=    |Shift Left and Assign              |N/A          |
      |SHR=    |Shift Right and Assign             |N/A          |
      |LET     |Assignment                         |N/A          |
      |        |                                   |             |
      |LET()   |Assignment                         |N/A          |
      +--------+-----------------------------------+-------------+

In some cases, the order of precedence can cause confusing or 
counter-intuitive results.  Here are some examples:
   '' trying to raise a negated number to a power
   -2 ^ 2
   Desired result: (-2) ^ 2 = 4
   Actual result:   -(2 ^ 2) = -4

   '' trying to test a bit in a number
   n And 1  <>  0
   Desired result: (n And 1) <> 0
   Actual result:   n And (1 <> 0)

   '' trying to shift a number by n+1 bits
   a Shl n+1
   Desired result: a Shl (n + 1)
   Actual result: (a Shl n) + 1

For expressions where the operator precedence may be ambiguous, it is 
recommended to wrap parts of the expression in parentheses, in order both 
to minimise the possibility of error and to aid comprehension for people 
reading the code.

See also
   * Operators



------------------------------------------------------ ProPgControlFlow ----
Control Flow Statements

Statements that direct the flow of execution.

Description
   Control flow statements control program execution from one statement to 
   the next; they determine what statements get executed and when, based on 
   some kind of condition. The condition is always some expression that 
   evaluates to true or false. Most control flow statements check for some 
   kind of condition, and direct code flow accordingly, that is, they do or 
   do not execute a block of code (except for the transferring control flow 
   statements and Do..Loop, which has an optional condition). Additionally, 
   all control flow statements can be nested, that is, they can have other 
   control flow statements within the statement block.

   Control flow statements come in three flavors: transferring, branching 
   and looping. Transferring control flow statements transfer execution to 
   different parts of code. Branching control flow statements execute 
   certain statements blocks based on a condition, while looping control 
   flow statements execute code repeatedly while or until a condition is 
   met.

Transferring Statements
   These statements are used for either unconditional or conditional, 
   temporary or permanent transfer of execution. The "ON" variants 
   conditionally select a point of transfer from a list of text labels.  
   Execution may be transferred between different scopes provided that the 
   branching does not cross any local array, variable length string or 
   object definition.

   Goto
      Unconditionally transfers execution to another point in code defined 
      by a text label. Execution resumes with the first statement after the 
      label.

   GoSub
      Unconditionally and temporarily transfers execution to another point 
      in code, defined by a text label. Execution resumes with the first 
      statement after the label. Execution is then brought back to its 
      original location with the Return keyword. Yes, GoSub statements can 
      be nested, that is, multiple GoSub statements can be executed before 
      the first corresponding Return, but there must always be a 
      corresponding Return throughout the course of an application.

   On Goto
      Transfers execution to one of a number of points in code defined by 
      text labels, based on the value of an expression.

   On Gosub
      Temporarily transfers execution to one of a number of points in code 
      defined by text labels, based on the value of an expression.

Branching Statements
   These statements are used for executing one of a number of statement 
   blocks.

   If..End If
      Executes a block of statements if an expression evaluates to true 
      (the condition). If and only if the expression evaluates to false, 
      another statement block can be executed if yet another expression 
      evaluates to true using the ElseIf keyword. If and only if all of 
      those expressions evaluate to false, a statement block can be execute 
      using the Else keyword.

   Select..End Select
      Executes one of a number of statement blocks. This branching 
      statement tries to meet a condition of an expression and one of a 
      number of case expressions. The case expressions are checked in the 
      order in which they are given, and the first case expression that is 
      met has its associated statement block executed. Like If..End If, a 
      default case can be defined when no other case expression meets the 
      condition, and, as with the looping control flow statements, a case's 
      statement block can be prematurely broken out of with the Exit 
      keyword.

Looping Statements
   These statements are used for executing a block of statements 
   repeatedly. Within a statement block, the loop can be prematurely 
   re-executed using the Continue keyword, or broken out of using the Exit 
   keyword. Whether the loop is terminated by the condition or with the Exit
   keyword, execution always begins at the first statement after the block.

   While..Wend
      Executes a block of statements while some expression evaluates to 
      true (the condition). The expression is evaluated and checked before 
      the block of statements is executed.

   For..Next
      Like While..Wend, but more suited to loop a certain number of times. 
      This loop initializes a so-called iterator with an initial value that 
      is checked against a test expression. If the iterator compares less 
      than or equal to the test expression (the condition), the block of 
      statements is executed and the iterator gets incremented. The loop 
      can also be setup so that the iterator gets decremented after every 
      loop, in which case it is compared greater than or equal to the test 
      expression. Iterators can be numeric data types like Integer or Double
      , or user-defined types. User-defined types must implement 
      Operator For.

   Do..Loop
      The most versatile of the looping control flow statements, this loop 
      can execute a block of statements while or until an expression 
      evaluates to true (the condition). It can also delay the checking of 
      the expression until after the block has executed the first time, 
      useful when a block of statements needs to be executed at least once. 
      Finally, this loop can have no condition at all, and merely loop 
      indefinitely.




============================================================================
    Procedures

------------------------------------------------------- ProPgProcedures ----
Procedures Overview

Overview of the different FB procedure types.

   Procedures are blocks of code that can be executed, or called, from 
   anywhere in a program, any number of times. The code that is executed is 
   called the procedure body. There are two types of procedures in 
   FreeBASIC: procedures that don't return a value and procedures that do.

Subs
   Subs are procedures that don't return values. They are declared using 
   the Declare keyword, and defined using the Sub keyword. Declaring a 
   procedure introduces its name so that it can be called, and a procedure 
   definition lists the statements of code that will be executed when 
   called. A sub is called simply by using its name somewhere in the 
   program.

   ' introduces the sub 'MyProcedure'
   Declare Sub MyProcedure

   ' calls the procedure 'MyProcedure'
   MyProcedure

   ' defines the procedure body for 'MyProcedure'
   Sub MyProcedure
      Print "the body of MyProcedure"
   End Sub

   will produce the output:


   the body of MyProcedure

   Notice that only the declaration is needed to call the procedure. The 
   procedure can be defined later in code, or even in a different source 
   file altogether.

Functions
   Functions are procedures that return a value back to the point in code 
   in which they are called. You can think of a function call as evaluating 
   to some expression, just like a variable or object. They are declared 
   using the Declare keyword, and defined using the Function keyword. The 
   type of value that functions return is specified at the end of the 
   declaration.

   ' introduces and defines a procedure that returns an integer value
   Function MyProcedure As Integer
      Return 10
   End Function

   ' calls the procedure, and stores its return value in a variable
   Dim i As Integer = MyProcedure
   Print i

   will produce the output:


   10

   Since a definition is a declaration, a procedure can be called after it 
   has been defined, as well.

   It is a common convention when calling a procedure to place parenthesis 
   '()' after the procedure name, to signify a procedure call. FreeBASIC 
   does not require this, however.

See also
   * Passing Arguments to Procedures
   * Returning a Value
   * Declare
   * Sub
   * Function



------------------------------------------------- ProPgPassingArguments ----
Passing Arguments to Procedures

Passing information to procedures.

Declaring parameters
   Procedures can get passed information in the form of variables and 
   objects when they are called. In the context of a procedure call, these 
   variables and objects are called arguments. These arguments are then 
   represented as so-called parameters inside the procedure body. 
   Parameters can be used just like any other variable or object.

   To specify that a procedure should get passed arguments when called, 
   declare the procedure with a parameter list. A parameter list is a list 
   of one or more names and types that the procedure will use when 
   referring to the arguments that are passed to it. Parameter lists are 
   surrounded by parenthesis.

   Sub Procedure (s As String, n As Integer)
      Print "The parameters have the values: " & s & " and " & n
   End Sub

   Procedure "abc", 123

   will produce the following output:


   The parameters have the values: abc And 123

   There are two ways to pass arguments to procedures: by value and by 
   reference. By default, arguments are passed by value unless otherwise 
   specified.

Passing arguments by value
   Arguments that are passed by value are not actually passed to 
   procedures; a copy of the argument is made and passed instead. This 
   allows the procedure to modify the copy, and the original variable or 
   object remains unchanged.

   When passing objects to procedures by value, the copy is made by calling 
   the copy constructor of the Type or Class.

   To specify that an argument should be passed by value, precede the 
   parameter name in the procedure declaration with the ByVal keyword:

   Sub Procedure (ByVal param As Integer)
      param *= 2
      Print "The parameter 'param' = " & param
   End Sub

   Dim arg As Integer = 10
   Print "The variable 'arg' before the call = " & arg
   Procedure(arg)
   Print "The variable 'arg' after the call = " & arg

   will produce the following output:


   The variable 'arg' before the call = 10
   The parameter 'param' = 20
   The variable 'arg' after the call = 10

   Notice how parenthesis surround the arguments - in this case only one, 
   arg - in the procedure call. These parenthesis are optional, but are a 
   common convention to signify a procedure call.

Passing arguments by reference
   Unlike arguments that are passed by value, arguments that are passed to 
   procedures by reference really do get passed; no copy is made. This 
   allows the procedure to modify the original variable or object that was 
   passed to it.

   A reference is like an alias for a variable or object. Whenever you 
   refer to a reference, you're referring to the actual variable or object 
   that it aliases. In other words, you can think of a reference parameter 
   of a procedure as the argument that is passed to it; any changes made to 
   the reference parameter are actually changes to the argument it 
   represents.

   To specify that an argument should be passed by reference, precede the 
   parameter name in the procedure declaration with the ByRef keyword:

   Sub Procedure (ByRef param As Integer)
      param *= 2
      Print "The parameter 'param' = " & param
   End Sub

   Dim arg As Integer = 10
   Print "The variable 'arg' before the call = " & arg
   Procedure(arg)
   Print "The variable 'arg' after the call = " & arg

   will produce the following output:


   The variable 'arg' before the call = 10
   The parameter 'param' = 20
   The variable 'arg' after the call = 20

Manually passing pointers to by-reference parameters
   By specifying the Byval keyword in front of an argument to a ByRef 
   parameter, an address (usually stored in a pointer) can be passed 
   directly as-is, forcing the Byref parameter to reference the same memory 
   location which the address pointed to.

   Sub f( ByRef i As Integer )
      i = 456
   End Sub

   Dim i As Integer = 123
   Dim pi As Integer Ptr = @i

   Print i
   f( ByVal pi )
   Print i

See also
   * Procedures Overview
   * Returning a Value
   * Declare
   * Sub
   * Function
   * ByVal
   * ByRef



------------------------------------------------------ ProPgReturnValue ----
Returning Values

Returning Values

... refers to the ability of a Function procedure to have a value when the 
function finishes such that the value can be used in an expression or 
assigned to a variable.

The value of a function can be returned in three ways:

   '' Using the name of the function to set the return value and continue executing the function:
   Function myfunc1() As Integer
      myfunc1 = 1
   End Function

   '' Using the keyword 'Function' to set the return value and continue executing the function:
   Function myfunc2() As Integer
      Function = 2
   End Function

   '' Using the keyword 'Return' to set the return value and immediately exit the function:
   Function myfunc3() As Integer
      Return 3
   End Function

   '' This program demonstrates a function returning a value.

   Declare Function myFunction () As Integer

   Dim a As Integer

   'Here we take what myFunction returns and add 10.
   a = myFunction() + 10

   'knowing that myFunction returns 10, we get 10+10=20 and will print 20.
   Print a 

   Function myFunction () As Integer
     'Here we tell myFunction to return 10.
     Function = 10 
   End Function

Returning References
   Function results can also be returned by reference, rather than by 
   value. The semantics are quite different.

   When assigning a Byref function result through a Function = variable or 
   Return variable statement, the function does not copy and return the 
   variable's value. Instead, it returns a reference to that variable. The 
   caller of the function can modify the variable through the reference 
   returned from the function, without having to use pointers manually. 
   This is very much like ByRef parameters.

   For more information, refer to: Byref (Function Results)

Manually returning pointers as-is from Byref functions
   By specifying the Byval keyword in front of the result variable in the 
   Function = variable or Return variable statements, an address (usually 
   stored in a pointer) can be passed directly as-is, forcing the Byref 
   function result to reference the same memory location which the address 
   pointed to. For example:

   Dim Shared i As Integer = 123

   Function f( ) ByRef As Integer
      Dim pi As Integer Ptr = @i

      Function = ByVal pi

      '' or, with RETURN it would look like this:
      Return ByVal pi
   End Function

   Print i, f( )

See also
   * Function
   * Byref (Function Results)



----------------------------------------------- ProPgCallingConventions ----
Calling Conventions

Specifying how procedures are called.

Calling conventions determine how calling code interacts with procedures 
when called. They specify rules about how parameters are pushed onto the 
call stack, how values are returned and when the call stack is cleaned up. 
This information is useful when interacting with code written in other 
languages, particularly assembly language. In some cases, calling 
conventions also apply some kind of name decoration to procedure names.

FreeBASIC supports 3 calling conventions: stdcall, cdecl and pascal, 
specified with stdcall, cdecl and pascal, respectively. Calling convention 
can be specified in either a procedure declaration or definition 
immediately following the procedure name. The declaration of a procedure 
must have the same calling convention as the definition.

In all calling conventions, integral procedure return values are returned 
in the EAX(, EDX) register(s), and floating-point return values are stored 
in the ST(0) register (the top of the floating-point stack). User-defined 
type (UDT) values are returned in the EAX(, EDX) register(s) if eight (8) 
bytes or smaller, otherwise they are returned in memory by having their 
address pushed onto the call stack after any parameters.

stdcall	
   In the stdcall convention, procedure parameters are pushed onto the call 
   stack prior to the procedure call (which will push the return address 
   just above parameters) in the reverse order they are declared, that is, 
   from right to left. The procedure is in charge of popping any parameters 
   from the call stack (commonly by appending a constant to the RET 
   instruction, signifying the number of bytes to release).

   stdcall is the default calling convention on Windows, and for procedures 
   within Extern "Windows" and Extern "Windows-Ms" blocks. It is also the 
   default convention used in the Windows API.

   Platform Differences
   * In DOS and Windows platforms, the procedure name is decorated with an 
     "@N" suffix, where N is the total size, in bytes, of any parameters 
     passed.

cdecl
   In the cdecl convention, procedure parameters are pushed onto the call 
   stack prior to the procedure call, in the reverse order they are 
   declared, that is, from right to left. The calling code is in charge of 
   popping parameters from the call stack.

   cdecl is the default calling convention on Linux, the *BSDs, and DOS, 
   and for procedures within Extern "C" and Extern "C++" blocks. It is also 
   the default convention used by most C and C++ compilers.

pascal
   In the pascal convention, procedure parameters are pushed onto the call 
   stack, in the order they are declared, that is, from left to right. The 
   procedure is in charge of popping any parameters from the call stack.

   pascal is the default convention used by Pascal and the Microsoft 
   QuickBASIC series of compilers.

The following table summarizes the differences between the various calling 
conventions:

      +-------------------+------------------------------------------------+---------------------------------------------+
      |Calling convention | Parameters are pushed onto the call stack from | Parameters are popped off the call stack by |
      | stdcall           | right to left                                  | the procedure                               |
      | cdecl             | right to left                                  | the calling code                            |
      | pascal            | left to right                                  | the procedure                               |
      +-------------------+------------------------------------------------+---------------------------------------------+

Platform Differences
   * In DOS and Windows platforms, all calling conventions decorate 
     procedure names with an underscore ("_") prefix.
   * The default calling convention changes depending on the platform.  
     For Windows it is stdcall; while on Linux, the *BSDs, and DOS, it is 
     cdecl.

See also
   * Declare, Sub, Function
   * stdcall, cdecl, pascal
   * Extern..End Extern



-------------------------------------------------------- ProPgRecursion ----
Recursion

Recursive procedures (subroutines or functions)

Iteration and recursion are two very useful ways to program, especially to 
perform a certain number of times a certain script, and thus allow 
optimization of the code. If iteration is relatively easy to understand, 
recursion is a concept not necessarily obvious at the beginning.
When speaking of a recursive procedure (subroutine or function), we refer 
to a syntactic characteristic: the procedure, in its own definition, refers 
to itself (it calls itself).
But when talking about recursive process, linear or tree, we are interested 
in the process flow, not in the syntax of the procedure's writing.
Thus, a procedure can have a recursive definition but correspond to an 
iterative process.

Some treatments are naturally implemented as a recursive algorithm 
(although this is not always the most optimal solution).
The main problem of the recursive approach is that it consumes potentially 
a lot of space on the execution stack: from a certain level of "depth" of 
recursion, the space allocated for the execution stack of the thread is 
exhausted, and causes an error of type "stack overflow".
Repeatedly calling the same procedure can also make the execution slower, 
although this may make the code easier.
To increase the speed of execution, simple recursive algorithms can be 
recreated in little more complicated iterative algorithms using loops that 
execute much faster.

What is the use of recursion if it increases the execution time and memory 
space compared to an iterative solution?
There are still cases where it is not possible to do otherwise, where 
iterative translation does not exist or, where it exists, is much heavier 
to implement (requiring for example a dynamic storage capacity to 
substitute for the execution stack).

Recursion beside iteration
   Iteration and recursion both repeatedly execute the instruction set:
      * Iteration occurs when a loop executes repeatedly until the control 
        condition becomes false.
      * Recursion occurs when an instruction in a procedure calls the 
        procedure itself repeatedly.
   The main difference between iteration and recursion is that iteration is 
   a process applied to a set of instructions to execute repeatedly, while 
   recursion is a process always applied to a procedure.

   Definition of iteration
      Iteration is a process of repeatedly executing a set of instructions 
      until the iteration condition becomes false.
      The iteration block includes the initialization, the comparison, the 
      execution of the instructions to be iterated and finally the update 
      of the control variable.
      Once the control variable is updated, it is compared again and the 
      process is repeated until the condition in the iteration is false.
      Iteration blocks are For loop, While loop, ...

      The iteration block does not use the execution stack to store the 
      variables at each cycle. Therefore, the execution of the iteration 
      block is faster than the recursion block. In addition, iteration does 
      not have the overhead of repeated procedure calls that also make its 
      execution faster than a recursion.
      The iteration is complete when the control condition becomes false.

      Simple example with a iterative function which returns the factorial 
      of the integer:
   '' The code body of the iterative function is defined by using the iterative definition of the factorial function:
   ''    Case (n = 0) : factorial(0) = 1
   ''    Case (n > 0) : factorial(n) = (1) * ..... * (n - 2) * (n - 1) * (n)
   ''    The first line allows to determine the cumulative variable initialization: 'result = 1'
   ''    The second line allows to determine the statement syntax which accumulates: 'result = result * I'

   Function iterativeFactorial (ByVal n As Integer) As Integer
      Dim As Integer result = 1  '' variable initialization
      For I As Integer = 1 To n  '' iteration loop
         result = result * I    '' iterative accumulation
      Next I
      Return result
   End Function

   Print iterativeFactorial(6)

   Sleep

   Definition of recursion
      FreeBASIC allows a procedure to call itself in its code. This means 
      that the procedure definition has a procedure call to itself. The set 
      of local variables and parameters used by the procedure are newly 
      created each time the procedure is called and are stored at the top 
      of the execution stack. But every time a procedure calls itself, it 
      does not create a new copy of that procedure. The recursive procedure 
      does not significantly reduce the size of the code and does not even 
      improve the memory usage, but it does a little bit compared to 
      iteration.

      To end recursion, a condition must be tested to force the return of 
      the procedure without giving a recursive call to itself. The absence 
      of a test of a condition in the definition of a recursive procedure 
      would leave the procedure in infinite recursion once called.

      Note: When the parameters of a recursive procedure are passed by 
      reference, take care to work with local variables when the code body 
      needs to modify their values.

      Simple example with a recursive function which returns the factorial 
      of the integer:
   '' The code body of the recursive function is defined by using the recursive definition of the factorial function:
   ''    Case (n = 0) : factorial(0) = 1
   ''    Case (n > 0) : factorial(n) = n * factorial(n-1)
   ''    The first line allows to determine the end condition: 'If (n = 0) Then Return 1'
   ''    The second line allows to determine the statement syntax which calls the function itself: 'Return n * factorial(n - 1)'

   Function recursiveFactorial (ByVal n As Integer) As Integer
      If (n = 0) Then                           '' end condition
         Return 1
      Else                                      '' recursion loop
         Return n * recursiveFactorial(n - 1)  '' recursive call
      End If
   End Function

   Print recursiveFactorial(6)

   Sleep

Recursion structure
   Different types of recursion structure can be found:
      * Tail recursion.
      * Non-tail but final recursion.
      * Non-tail and non-final recursion.
      * Mutual recursion.
      * Nested recursion.

   Tail recursion
      The recursive procedure is a tail recursive procedure if the only 
      recursive call is at the end of the recursion and is therefore not 
      followed by any other statement:
         * for a recursive subroutine, the only recursive call is at the 
           end of the recursion,
         * for a recursive function, the only recursive call is at the end 
           of the recursion and consists in taking into account the return 
           of the function without any other additional operation on it.
      A tail recursive procedure is easy to transform into an iterative 
      procedure.

      Example with the simple "factorial" recursive function (already 
      presented above):
         * This function has a non-tail recursive form because even though 
           the recursive call is at the end of function, this recursive 
           call is not the last instruction of the function because one has 
           to multiplied again by 'n' when 'recursiveFactorial(n - 1)' is 
           got.
         * This calculation is done when popping context from execution 
           stack.

      It is quite easy to transform this function so that the recursion is 
      a tail recursion.
      To achieve this, it is necessary to add a new parameter to the 
      function: the 'result' parameter which will serve as accumulator:
   Function tailRecursiveFactorial (ByVal n As Integer, ByVal result As Integer = 1) As Integer
      If (n = 0) Then                                       '' end condition
         Return result
      Else                                                  '' recursion loop
         Return tailRecursiveFactorial(n - 1, result * n)  '' tail recursive call
      End If
   End Function

   Print tailRecursiveFactorial(6)

   Sleep
         
This time, the calculation is done when pushing context on execution stack.

      Similar transformation steps for the simple "reverse string" 
      recursive function following:
   Function recursiveReverse (ByVal s As String) As String
      If (s = "") Then                                     '' end condition
         Return s
      Else                                                 '' recursion loop
         Return recursiveReverse(Mid(s, 2)) & Left(s, 1)  '' recursive call
      End If
   End Function

   Print recursiveReverse("9876543210")

   Sleep

   Function tailRecursiveReverse (ByVal s As String, ByVal cumul As String = "") As String
      If (s = "") Then                                                '' end condition
         Return cumul
      Else                                                            '' recursion loop
         Return tailRecursiveReverse(Mid(s, 2), Left(s, 1) & cumul)  '' tail recursive call
      End If
   End Function

   Print tailRecursiveReverse("9876543210")

   Sleep
         
Note: As the "&" operator (string concatenation) is not a symmetric 
operator ('(a & b) <> (b & a)', while '(x * y) = (y * x)' like previously), 
the two operand order must to be reversed when pushing context on execution 
stack instead of before when popping context from execution stack.

   Non-tail but final recursion
      A non-tail recursive procedure is final when the recursive call(s) 
      is(are) placed at the end of executed code (no executable instruction 
      line after and between for several recursive calls).

      First example, computation of the combination coefficients nCp 
      (binomial coefficients calculation) and display of the Pascal's 
      triangle:
   Function recursiveCombination (ByVal n As UInteger, ByVal p As UInteger) As LongInt
      If p = 0 Or p = n Then
         Return 1
      Else
         Return recursiveCombination(n - 1, p) + recursiveCombination(n - 1, p - 1)
      End If
   End Function

   Dim As UInteger n = 10
   For I As UInteger = 0 To n
      For J As UInteger = 0 To I
         Locate , 6 * J + 3 * (n - I) + 3
         Print recursiveCombination(I, J);
      Next J
      Print
   Next I

   Sleep

      Second example, recursive drawing of circles:
   Sub recursiveCircle (ByVal x As Integer, ByVal y As Integer, ByVal r As Integer)
      Circle (x, y), r
      If r > 16 Then
         recursiveCircle(x + r / 2, y, r / 2)
         recursiveCircle(x - r / 2, y, r / 2)
         recursiveCircle(x, y + r / 2, r / 2)
         recursiveCircle(x, y - r / 2, r / 2)
      End If
   End Sub

   Screen 12

   Locate 2, 2
   recursiveCircle(160, 160, 150)

   Sleep

      Third example, quick sort algorithm:
   Dim Shared As UByte t(99)

   Sub recursiveQuicksort (ByVal L As Integer, ByVal R As Integer)
      Dim As Integer pivot = L, I = L, J = R
      Do
         If t(I) >= t(J) Then
            Swap t(I), t(J)
            pivot = L + R - pivot
         End If
         If pivot = L Then
            J = J - 1
         Else
            I = I + 1
         End If
      Loop Until I = J
      If L < I - 1 Then
         recursiveQuicksort(L, I - 1)
      End If
      If R > J + 1 Then
         recursiveQuicksort(J + 1, R)
      End If
   End Sub

   Randomize
   For I As Integer = LBound(t) To UBound(t)
      t(i) = Int(Rnd * 256)
   Next I

   Print "raw memory:"
   For K As Integer = LBound(t) To UBound(t)
      Print Using "####"; t(K);
   Next K
   Print

   recursiveQuicksort(LBound(t), UBound(t))

   Print "sorted memory:"
   For K As Integer = LBound(t) To UBound(t)
      Print Using "####"; t(K);
   Next K
   Print

   Sleep

   Non-tail and non-final recursion
      A non-tail recursive procedure is also not final when the recursive 
      call(s) is(are) not all placed at the end of executed code (an 
      executable instruction line at least after or between for several 
      recursive calls).

      Example, tower of Hanoi algorithm:
   '' For this example, the two recursive calls are at the end of executed code block but separated by an instruction line and there is an order constraint.

   Sub recursiveHanoi (ByVal n As Integer, ByVal departure As String, ByVal middle As String, ByVal arrival As String)
      If n > 0 Then
         recursiveHanoi(n - 1, departure, arrival, middle)
         Print "  move one disk from " & departure & " to " & arrival
         recursiveHanoi(n -1 , middle, departure, arrival)
      End If
   End Sub

   recursiveHanoi(3, "A", "B", "C")

   Sleep

   Mutual recursion
      Two functions are said to be mutually recursive if the first calls 
      the second, and in turn the second calls the first.

      Example using mutual recursive, 'even()' and 'odd()' recursive 
      functions:
   Declare Function recursiveIsEven(ByVal n As Integer) As Boolean
   Declare Function recursiveIsOdd(ByVal n As Integer) As Boolean

   Function recursiveIsEven(ByVal n As Integer) As Boolean
      If n = 0 Then
         Return True
      Else
         Return recursiveIsOdd(n - 1)
      End If
   End Function

   Function recursiveIsOdd(ByVal n As Integer) As Boolean
       If n = 0 Then
         Return False
      Else
         Return recursiveIsEven(n - 1)
      End If
   End Function

   Print recursiveIsEven(16), recursiveIsOdd(16)
   Print recursiveIsEven(17), recursiveIsOdd(17)

   Sleep

   Nested recursion
      A recursive function is said nested if an argument passed to the 
      function refers to the function itself.

      Example using nested recursive function, 'Ackermann()' recursive 
      function:
   Function recursiveAckermann (ByVal m As Integer, ByVal n As Integer) As Integer
      If m = 0 Then
         Return n + 1
      Else
         If n = 0 Then
            Return recursiveAckermann(m - 1, 1)
         Else
            Return recursiveAckermann(m - 1, recursiveAckermann(m, n - 1))
         End If
      End If
   End Function

   Print recursiveAckermann(3, 0), recursiveAckermann(3, 1), recursiveAckermann(3, 2), recursiveAckermann(3, 3), recursiveAckermann(3, 4)

   Sleep



------------------------------------------------ ProPgProcedurePointers ----
Pointers to Procedures

Pointers that point to procedures

   Just as pointers can be made to point to an Integer or Single type, 
   pointers can also point to procedures, that is, they can store the 
   address of a procedure.

Declaration
   To declare a pointer to procedure, use the Sub or Function keywords, 
   followed by any parameters and return value type:

   ' declares a pointer to sub procedure that takes no arguments
   Dim pointerToProcedure As Sub

   Procedure pointers store procedure addresses, which are retrieved using 
   Operator @ (Address of) or the Procptr Operator:

   '' pfunc.bi

   Function Add (a As Integer, b As Integer) As Integer
      Return a + b
   End Function

   Dim pFunc As Function (As Integer, As Integer) As Integer = @Add

Calling a procedure pointer
   The interesting thing about procedure pointers is that they can be 
   called just like a procedure:

   '' .. Add and pFunc as before ..
   #include Once "pfunc.bi"

   Print "3 + 4 = " & pFunc(3, 4)

   For a calling example of subroutine pointer, see the 
   Operator @ (Address Of) page.

   Note: When calling a procedure through a procedure pointer, parentheses 
   surrounding the argument list (even empty) are mandatory to resolve 
   ambiguity with a simple access to the pointer value.

Passing procedure pointers to procedures
   Passing procedure pointers to other procedures is similar as well:

   '' .. Add and pFunc as before ..
   #include Once "pfunc.bi"

   Function DoOperation (a As Integer, b As Integer, operation As Function (As Integer, As Integer) As Integer) As Integer
      Return operation(a, b)
   End Function

   Print "3 + 4 = " & DoOperation(3, 4, @Add)

   Because procedure pointer declarations can be lengthy, it often helps to 
   create a type alias for the procedure pointer, in an effort to make 
   clearer code:

   '' .. Add and pFunc as before ..
   #include Once "pfunc.bi"

   Type operation As Function (As Integer, As Integer) As Integer

   Function DoOperation (a As Integer, b As Integer, op As operation) As Integer
      Return op(a, b)
   End Function

   Print "3 + 4 = " & DoOperation(3, 4, @Add)

Pointers to procedure pointers
   Because the syntax of a procedure pointer does not allow declaration of 
   a pointer to procedure pointer when the procedure is a function (because 
   ptr applies on return type and not on procedure), a type alias is used. 
   Notice how it is necessary to surround a dereferenced pointer to 
   procedure pointer by parenthesis when calling the procedure. This is 
   because the function-call operator '()' has higher precedence than 
   Operator * (Value of):

   Function Halve (ByVal i As Integer) As Integer
      Return i / 2
   End Function

   Function Triple (ByVal i As Integer) As Integer
      Return i * 3
   End Function

   Type operation As Function (ByVal As Integer) As Integer

   ' an array of procedure pointers, NULL indicates the
   ' end of the array
   Dim operations(20) As operation = _
   { @Halve, @Triple, 0 }

   Dim i As Integer = 280

   ' apply all of the operations to a variable by iterating through the array
   ' with a pointer to procedure pointer
   Dim op As operation Ptr = @operations(0)
   While (*op <> 0)
      ' call the procedure that is pointed to, note the extra parenthesis
      i = (*op)(i)
      op += 1
   Wend

   Print "Value of 'i' after all operations performed: " & i

Pointers to member procedures
   Method pointers are not implemented yet, but it is possible to 
   work-around that by using a static wrapper:

   /''
    ' This example shows how you can simulate getting a class method pointer, 
    ' until support is properly implemented in the compiler.
    '
    ' When this is supported, you will only need to remove the static wrapper
    ' function presented here, to maintain compatibility. 
    '/

   Type T
      Declare Function test(ByVal number As Integer) As Integer
      Declare Static Function test(ByRef This As T, ByVal number As Integer) As Integer
      Dim As Integer i = 420
   End Type

   Function T.test(ByVal number As Integer) As Integer
      Return i + number
   End Function

   Function T.test(ByRef This As T, ByVal number As Integer) As Integer
      Return this.test(number)
   End Function

   Dim p As Function(ByRef As T, ByVal As Integer) As Integer
   p = @T.test

   Dim As T obj

   Print p(obj, 69) '' prints 489

Typing rule for procedure pointer declaration
   The procedure pointer declaration allows to assign to the pointer:
      * not only a procedure with the same parameters types, and if any, 
        the same result type,
      * but also a procedure with contravariant byref (or by pointer) 
        parameters or/and a covariant byref (or by pointer) result.

   'Example of assigning to a function pointer a function with a contravariant parameter and a covariant result.

   Type A
      Dim As Integer I
   End Type

   Type B Extends A
      Dim As Integer J
   End Type

   Function f (ByRef a0 As A) As B Ptr
      Print "instance of B created"
      Return New B(a0)
   End Function

   Dim As Function (ByRef As B) As A Ptr pf = @f

   Dim As B b0
   Dim As A Ptr pab = pf(b0)

   Sleep
   Delete CPtr(B Ptr, pab)

See also
   * Sub
   * Function
   * Pointer
   * Operator @ (Address Of)
   * Procptr Operator

   

   


----------------------------------------------------------- CatPgVarArg ----
Variable Arguments

The ellipsis symbol for the declaration and keywords to handle the variable 
arguments of a variadic procedure.

   * ... (Ellipsis)
   * Cva_List
   * Cva_Start
   * Cva_Copy
   * Cva_End
   * Cva_Arg

   * va_first
   * va_arg
   * va_next

   


============================================================================
    Making Binaries

-------------------------------------------------- ProPgStaticLibraries ----
Static Libraries

A static library is compiled code that can be later used when building an 
executable.

When the compiler makes an executable, the basic source files are first 
turned in to object files.  The object files are then linked together to 
make an executable.  When we compile source code, we don't necessarily have 
to make an executable.  We could instead group all of the object files 
(made from sources) in to a single file called a static library.

The library is referred to as static, because when the object files which 
it contains are later linked in to an executable, a copy of all the needed 
code in the library is added to the executable.

Once the library is made, we can then use the code that it contains just as 
if we were compiling the source directly with our program.

Following is a simple example of creating a static library using these 
three files:
   * mylib.bas - the source for the library
   * mylib.bi - the header for the library
   * mytest.bas - a test program

Our library will be a single module providing a single function:

   '' mylib.bas
   '' compile with: fbc -lib mylib.bas

   '' Add two numbers together and return the result
   Public Function Add2( ByVal x As Integer, ByVal y As Integer ) As Integer
     Return( x + y )
   End Function

Compile the library with:
   fbc -lib mylib.bas

The -lib option tells the compiler to take the source code, mylib.bas, and 
turn it in to an object file mylib.o, then store the object file in to a 
library file, also called an archive, libmylib.a.  A library might contain 
many modules (source files) each with many functions, but for this simple 
example, it is just one each.

To make use of the library in some other source code, we need some way of 
telling the compiler what exactly is in the library.  A good way to do this 
is to put the declarations ( also called an interface, or API ) for the 
library in to a header file.

   '' mylib.bi
   #inclib "mylib"
   Declare Function Add2( ByVal x As Integer, ByVal y As Integer ) As Integer

There is no need to compile the header.  We want this in its source form so 
it can be included with other source files.  The #inclib statement will 
tell the compiler the name of a static library that we need to link with 
when eventually making an executable.

With our library (.a file) and a header (.bi file) we can try them out in a 
test program:

   '' mytest.bas
   '' compile with: fbc mytest.bas
   #include Once "mylib.bi"
   Print Add2(1,2)

The #include statement tells the compiler to include the source code from 
mylib.bi just as if we had typed it in to the original source.  With the 
way we have written our include file, it tells the compiler everything it 
needs to know about the library.

We compile this with:
   fbc mytest.bas

Then when we run the mytest executable, we should get the result of:
   3

More than one source module can be used when making a library.  And basic 
programs can use more than one library by including each needed header.  
Some libraries are so large that they might use several headers.  On very 
large projects, making libraries out of some code modules that seldom 
change can improve compile times dramatically.

Libraries can optionally contain debugging information specified with the -g
command line option.

Object files, and therefore libraries, are platform specific and in some 
cases specific to a particular version of the compiler and FreeBASIC 
runtime library.

See also
   * Shared Libraries
   * #inclib
   * #include
   * Compiler Option: -lib
   * Compiler Option: -static



-------------------------------------------------- ProPgSharedLibraries ----
Shared Libraries

A shared library is compiled code that can be loaded and used later when 
running an executable.

When the compiler makes an executable, the basic source files are first 
turned in to object files.  The object files are then linked together to 
make an executable.  A shared library is much like a static library in that 
it contains object files.  But a shared library is also like an executable 
in that it only gets loaded when the executable is running.  

The library is referred to as shared, because the code in the library is 
loaded by an executable at runtime and can be loaded by more than one 
executable, even though there might only be one copy of the shared library.

Once the library is made, we can then use the code that it contains just as 
if we were compiling the source directly with our program.

Shared Library Example
Using Shared Libraries on Windows
Using Shared Libraries on Linux
Executables that export symbols
Loading Shared Libraries Dynamically

Shared Library Example
   Following is a simple example of creating a shared library using these 
   three files:
   * mylib.bas - the source for the library
   * mylib.bi - the header for the library
   * mytest.bas - a test program

   Our library will be a single module providing a single function:

   '' mylib.bas
   '' compile with: fbc -dll mylib.bas

   '' Add two numbers together and return the result
   Public Function Add2( ByVal x As Integer, ByVal y As Integer ) As Integer Export
     Return( x + y )
   End Function

   Compile the library with:
   fbc -dll mylib.bas

   The -dll option tells the compiler to take the source code, mylib.bas, 
   and turn it in to an object file mylib.o, then store the object file in 
   to a shared library.  The name of the shared library will have a .so 
   extension or .dll extension depending on if the platform is the linux or 
   windows version. A library might contain many modules (source files) 
   each with many functions, but for this simple example, it is just one 
   each.

   Making a shared library is almost identical to making a static library 
   except for the addition of Export declaration specifier.  Export tells 
   the compiler to make the function visible to other executables loading 
   the shared library.

   To make use of the library in some other source code, we need some way 
   of telling the compiler what exactly is in the library.  A good way to 
   do this is to put the declarations ( also called an interface, or API ) 
   for the library in to a header file.

   '' mylib.bi
   #inclib "mylib"
   Declare Function Add2( ByVal x As Integer, ByVal y As Integer ) As Integer

   There is no need to compile the header.  We want this in its source form 
   so it can be included with other source files.  The #inclib statement 
   will tell the compiler the name of a shared library that we need to link 
   with at runtime running an executable that needs it.

   With our library (.dll / .so file) and a header (.bi file) we can try 
   them out in a test program:

   '' mytest.bas
   '' compile with: fbc mytest.bas
   #include Once "mylib.bi"
   Print Add2(1,2)

   The #include statement tells the compiler to include the source code 
   from mylib.bi just as if we had typed it in to the original source.  
   With the way we have written our include file, it tells the compiler 
   everything it needs to know about the library.

   We compile this with:
   fbc mytest.bas

   Then when we run the mytest executable, we should get the result of:
   3

   More than one source module can be used when making a library.  And 
   basic programs can use more than one library by including each needed 
   header.  Some libraries are so large that they might use several 
   headers.  On very large projects, making shared libraries out of some 
   code modules that seldom change can improve compile times and link times 
   dramatically.

   Shared libraries can optionally contain debugging information specified 
   with the -g command line option.

   Object files, and therefore shared libraries, are platform specific and 
   in some cases specific to a particular version of the compiler and 
   FreeBASIC runtime library.

Using Shared Libraries on Windows
   On Windows, the shared library must be stored in a location where it can 
   be found by the executable that needs it a run-time.  

   The operating system may search the following directories:
   * The directory from which the executable was loaded.
   * The current directory.
   * The Windows and Windows system folder.
   * Directories list in the PATH environment variable.

   The order in which directories are searched may depend on the Windows 
   version in use, and on what settings that the operating system is 
   configured with.

Using Shared Libraries on Linux
   By default, Linux will not normally search the current directory or the 
   directory from which the executable was loaded.  You will need to 
   either:
   * copy the .so file to a directory that has shared libraries (e.g. 
     /usr/lib) and run ldconfig to configure the library.
   * modify the environment variable LD_LIBRARY_PATH to search the current 
     directory or a specific directory for the newly created shared 
     library.

   To run the executable ./mytest/ and temporarily tell linux to search the 
   current directory, use the following shell command:
   LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./mytest

Executables that export symbols
   If an executable has symbols that must be available to other shared 
   libraries when those shared libraries are loaded, use the Export 
   procedure declaration specifier, and the -export command line option 
   when making (linking) the executable.

   The -export option has no extra effect when used with the -dylib or -dll 
   command line options.

Loading Shared Libraries Dynamically
   Shared libraries can be loaded and used at run time by dynamically 
   loading the library and its symbols at runtime.
   * DyLibLoad can be used to load and obtain a handle to a shared 
     library.
   * DyLibSymbol is used to obtain the address of a symbol in a loaded 
     shared library.
   * DyLibFree is used to unload a shared library when it is no longer 
     needed.

   Procedures in the shared library must use the Export specifier to ensure 
   that the symbols name is placed in the shared library's export table.

   '' mydll.bas
   '' compile as: fbc -dll mydll.bas
   '' This will create mydll.dll (and libmydll.dll.a import library) on Windows,
   '' and libmydll.so on Linux.
   ''
   '' Note: libmydll.dll.a is an import library, it's only needed when creating 
   '' an executable that calls any of mydll's functions, only distribute 
   '' the DLL files with your apps, do not include the import libraries, 
   '' they are useless to end-users.

   '' Simple exported function; the <alias "..."> disables FB's default
   '' all-upper-case name mangling, so the DLL will export AddNumbers() instead of
   '' ADDNUMBERS().
   Function AddNumbers Alias "AddNumbers"( ByVal a As Integer, ByVal b As Integer ) As Integer Export
      Function = a + b
   End Function

   '' load.bas: Loads mydll.dll (or libmydll.so) at runtime, calls one of mydll's
   '' functions and prints the result. mydll is not needed at compile time.
   '' compile as: fbc test.bas
   ''
   '' Note: The compiled mydll.dll (or libmydll.so) dynamic library is expected
   '' to be available in the current directory.

   '' Note we specify just "mydll" as library file name; this is to ensure
   '' compatibility between Windows and Linux, where a dynamic library
   '' has different file name and extension.
   Dim As Any Ptr library = DyLibLoad( "mydll" )
   If( library = 0 ) Then
      Print "Failed to load the mydll dynamic library, aborting program..."
      End 1
   End If

   '' This function pointer will be used to call the function from mydll, after
   '' the address has been found. Note: It must have the same calling
   '' convention and parameters.
   Dim AddNumbers As Function( ByVal As Integer, ByVal As Integer ) As Integer
   AddNumbers = DyLibSymbol( library, "AddNumbers" )
   If( AddNumbers = 0 ) Then
      Print "Could not retrieve the AddNumbers() function's address from the mydll library, aborting program..."
      End 1
   End If

   Randomize Timer

   Dim As Integer x = Rnd * 10
   Dim As Integer y = Rnd * 10

   Print x; " +"; y; " ="; AddNumbers( x, y )

   '' Done with the library; the OS will automatically unload libraries loaded
   '' by a process when it terminates, but we can also force unloading during
   '' our program execution to save resources; this is what the next line does.
   '' Remember that once you unload a previously loaded library, all the symbols
   '' you got from it via dylibsymbol will become invalid, and accessing them
   '' will cause the application to crash.
   DyLibFree( library )

See also
   * Static Libraries
   * #inclib
   * #include
   * Compiler Option: -dll
   * Compiler Option: -export
   * Compiler Option: -dylib



-------------------------------------------------------- ProPgProfiling ----
Profiling

Profiling can be used to analyze the performance of an application.

The performance of an application might be measured by how many times 
functions are called, how much time is spent executing those functions, and 
which functions are calling other functions.  This can help to identify 
functions that might be taking too long to execute or executed too many 
times and that might be worth reviewing for optimization.

FreeBASIC uses GPROF for analyzing the execution of an application.  The 
profiler information is collected while the program is running, and GPROF 
is used to report on the collected data afterward.

The three basic steps to profiling a program are:
   * 1) Prepare the program for profiling by compiling source with the 
     -profile option.
   * 2) Run the program to collection information ( stored in gmon.out ).
   * 3) Analyze the information collected using GPROF.

Full documentation on GPROF is available here: 
https://ftp.gnu.org/old-gnu/Manuals/gprof-2.9.1/html_mono/gprof.html.  If 
the documentation has moved from that location, simply search the web for 
"GNU GPROF" and a relevant link should be returned.

FreeBASIC supports function profiling; not basic-block or line-by-line 
profiling.

Preparing a Program for Profiling
   Only code that is compiled with the -profile command line option can be 
   profiled.  Pass the -profile option to the FreeBASIC compiler to prepare 
   the program to be profiled.  This will tell the compiler to insert 
   special startup code at the beginning of the application as well as at 
   the beginning of each function.

   fbc program.bas -profile

Profiling the Program
   The information needed to analyze execution of the program is gathered 
   while the program is running.  Run the program to begin collecting the 
   function call information.  This information is automatically stored in 
   a file named gmon.out in the same directory as the program.

Analyzing the Program's Output
   Use GPROF to analyze the output.  The default report for GPROF includes 
   descriptions on what each of the columns of values mean.  If you are new 
   to using GPROF, you may want to first run the default report and read 
   through the descriptions.  The output from GPROF can be saved to a file 
   by redirection.

   Save output from GPROF to profile.txt:

   gprof program[.exe] > profile.txt

   Show just the flat report with no descriptions:

   gprof program[.exe] --brief --flat-profile > profile.txt

Combining the Results of More than One Session
   GPROF also has a '--sum' option for conveniently combining results from 
   multiple execution sessions.  Here is an example of usable:
   * Run your program once. This will create gmon.out.
   * Use the command :
      mv gmon.out gmon.sum 
      or 
      rename gmon.out gmon.sum.
   * Run your program again.  This will create new data in gmon.out.
   * Merge the new data in gmon.out into gmon.sum using the command: 
      gprof --sum program[.exe] gmon.out gmon.sum
   * Repeat the last two steps as often as needed. 
   * Analyze the summary data using the command: 
      gprof program[.exe] gmon.sum > profile.txt

FreeBASIC Profiling Internals
   When the '-profile' option is enabled, one or more bits of code are 
   added to the program.
   * Call to "_monstartup()" at the beginning of the implicit main to 
     initialize the profiling library.
   * Call to "mcount()" at the beginning of each procedure.  This is how 
     the profiling library keeps track of what function is being and by 
     which other function.
   * Linking of additional program startup object code.  (e.g. gcrt?.o )

   The profiling library itself may be in a separate library or part of the 
   C runtime library.
   * mingw will require gcrt2.o and libgmon.a 
   * cygwin will require gcrt0.o and libgmon.a
   * dos will require gcrt0.o (profiler code is in libc.a) 
   * linux will require gcrt1.o (profiler code is in libc.a) 

   The details may vary from one port of FreeBASIC to the next, but source 
   code built for profiling with FreeBASIC should be compatible with other 
   languages also supporting GPROF.




============================================================================
    Preprocessor


============================================================================
    Other Topics

-------------------------------------------------------------- CptAscii ----
Table of ASCII Characters

FreeBASIC graphics programs support in all versions the same "ASCII 
extended" USA character set the old DOS (and QBasic) supported. It is also 
called CP437 or Code page 437.  Each character is represented with one (1) 
byte of data.  Here is a table.  Each entry has decimal code, hex code, and 
printed representation.

      
     0  0  ³ 16 10  ³ 32 20  ³ 48 30 0³ 64 40 @³ 80 50 P³ 96 60 `³112 70 p
     1  1  ³ 17 11  ³ 33 21 !³ 49 31 1³ 65 41 A³ 81 51 Q³ 97 61 a³113 71 q
     2  2  ³ 18 12  ³ 34 22 "³ 50 32 2³ 66 42 B³ 82 52 R³ 98 62 b³114 72 r
     3  3  ³ 19 13  ³ 35 23 #³ 51 33 3³ 67 43 C³ 83 53 S³ 99 63 c³115 73 s
     4  4  ³ 20 14  ³ 36 24 $³ 52 34 4³ 68 44 D³ 84 54 T³100 64 d³116 74 t
     5  5  ³ 21 15  ³ 37 25 %³ 53 35 5³ 69 45 E³ 85 55 U³101 65 e³117 75 u
     6  6  ³ 22 16  ³ 38 26 &³ 54 36 6³ 70 46 F³ 86 56 V³102 66 f³118 76 v
     7  7  ³ 23 17  ³ 39 27 '³ 55 37 7³ 71 47 G³ 87 57 W³103 67 g³119 77 w
     8  8  ³ 24 18  ³ 40 28 (³ 56 38 8³ 72 48 H³ 88 58 X³104 68 h³120 78 x
     9  9  ³ 25 19  ³ 41 29 )³ 57 39 9³ 73 49 I³ 89 59 Y³105 69 i³121 79 y
    10  A  ³ 26 1A  ³ 42 2A *³ 58 3A :³ 74 4A J³ 90 5A Z³106 6A j³122 7A z
    11  B  ³ 27 1B  ³ 43 2B +³ 59 3B ;³ 75 4B K³ 91 5B [³107 6B k³123 7B {
    12  C  ³ 28 1C  ³ 44 2C ,³ 60 3C <³ 76 4C L³ 92 5C \³108 6C l³124 7C |
    13  D  ³ 29 1D  ³ 45 2D -³ 61 3D =³ 77 4D M³ 93 5D ]³109 6D m³125 7D }
    14  E  ³ 30 1E  ³ 46 2E .³ 62 3E >³ 78 4E N³ 94 5E ^³110 6E n³126 7E ~
    15  F  ³ 31 1F  ³ 47 2F /³ 63 3F ?³ 79 4F O³ 95 5F _³111 6F o³127 7F 

   128 80 €³144 90 �³160 A0  ³176 B0 °³192 C0 À³208 D0 Ð³224 E0 à³240 F0 ð
   129 81 �³145 91 ‘³161 A1 ¡³177 B1 ±³193 C1 Á³209 D1 Ñ³225 E1 á³241 F1 ñ
   130 82 ‚³146 92 ’³162 A2 ¢³178 B2 ²³194 C2 Â³210 D2 Ò³226 E2 â³242 F2 ò
   131 83 ƒ³147 93 “³163 A3 £³179 B3 ³³195 C3 Ã³211 D3 Ó³227 E3 ã³243 F3 ó
   132 84 „³148 94 ”³164 A4 ¤³180 B4 ´³196 C4 Ä³212 D4 Ô³228 E4 ä³244 F4 ô
   133 85 …³149 95 •³165 A5 ¥³181 B5 µ³197 C5 Å³213 D5 Õ³229 E5 å³245 F5 õ
   134 86 †³150 96 –³166 A6 ¦³182 B6 ¶³198 C6 Æ³214 D6 Ö³230 E6 æ³246 F6 ö
   135 87 ‡³151 97 —³167 A7 §³183 B7 ·³199 C7 Ç³215 D7 ×³231 E7 ç³247 F7 ÷
   136 88 ˆ³152 98 ˜³168 A8 ¨³184 B8 ¸³200 C8 È³216 D8 Ø³232 E8 è³248 F8 ø
   137 89 ‰³153 99 ™³169 A9 ©³185 B9 ¹³201 C9 É³217 D9 Ù³233 E9 é³249 F9 ù
   138 8A Š³154 9A š³170 AA ª³186 BA º³202 CA Ê³218 DA Ú³234 EA ê³250 FA ú
   139 8B ‹³155 9B ›³171 AB «³187 BB »³203 CB Ë³219 DB Û³235 EB ë³251 FB û
   140 8C Œ³156 9C œ³172 AC ¬³188 BC ¼³204 CC Ì³220 DC Ü³236 EC ì³252 FC ü
   141 8D �³157 9D �³173 AD ­³189 BD ½³205 CD Í³221 DD Ý³237 ED í³253 FD ý
   142 8E Ž³158 9E ž³174 AE ®³190 BE ¾³206 CE Î³222 DE Þ³238 EE î³254 FE þ
   143 8F �³159 9F Ÿ³175 AF ¯³191 BF ¿³207 CF Ï³223 DF ß³239 EF ï³255 FF ÿ

 

Many of the standard ASCII characters cannot be Printed in FreeBASIC, 
because the console interprets some characters as controls: 7 is bell, 8 is 
backspace, 9 is tab, 10 is line feed, 13 is carriage return, and others.  
There are symbols associated with these characters also, but there is no 
way in FreeBASIC to output them to the screen. 

The acronym ASCII stands for American Standard Code for Information 
Interchange. For more information, see http://en.wikipedia.org/wiki/Ascii.  
The symbols for codes 32 through 127 are the same as the standard 
Latin ISO-8859-1 char set most Windows fonts use. Others are often very 
different.

In console mode (i.e. Screen 0/ non-graphics mode) the characters less than 
32 or greater than 127 may display using different characters, depending on 
the operating system and code page of the screen / console in use.
UNICODE is a newer standard of character sets involving two or more bytes 
per character, and may be used to print other characters to a 
Unicode-enabled console.

In graphics modes, Draw String does not give special meaning to control 
characters allowing an alternative to display all characters in the set. 



------------------------------------------------------------ ProPgDates ----
Date Serials

Description
   A date serial is a number that holds a date and time value in the same 
   format used by PDS or VBDOS. The value is a count of the days from 0:00 
   AM of December 30,1899; it's mainly used for easy counting of the time 
   between two dates.

   The date serial unit is one day and the fractional part represents the 
   time of the day. If a date serial is written into an integer, the time 
   is lost. FreeBASIC date serials are not limited to dates between 1753 
   and 2078 as in VBDOS. FreeBASIC date serial handling functions use Double
   arguments.

   FreeBASIC date serial handling functions require the inclusion of 
   vbcompat.bi or datetime.bi in the source.

   A date serial can be created by the functions Now, TimeSerial+DateSerial
   , or DateValue+TimeValue.

   The functions Year, Month, Weekday, Day, Hour, Minute, Second allow to 
   recover the different components of a date serial.

   The Format function has formatting expressions to print date serials in 
   a human readable way.

Example
   #include "vbcompat.bi"
   Dim a As Double, b As Double

   a = 0
   Print "The origin of the date serials is:"
   Print Format(a, "yyyy/mm/dd hh:mm:ss")
   Print

   a = Now
   Print "The time now is: "
   Print Format(a, "yyyy/mm/dd hh:mm:ss")
   Print

   b = DateSerial(2000,1,1)
   Print Int(a-b) & " days have passed since 2000/01/01"

   


---------------------------------------------------------- ProPgRadians ----
Radian system of measuring angles

All of the built-in trigonometric functions in FreeBASIC express angles in 
radians.

Let pi the constant equal to the ratio of the circumference of a circle to 
its diameter. It can be calculated programmatically by multiplying the 
arctangent of 1 by 4.
A full circle is divided into 2 * pi radians or 360 degrees, which leads to 
the following conversions:

   pi = Atn(1) * 4
   radians = degrees * pi / 180
   degrees = radians * 180 / pi

These 3 formulas can be expressed by using macros:

   #define   pi          ( Atn(1) * 4 )
   #define   radian(x)   ( (x) * pi / 180 )
   #define   degree(x)   ( (x) * 180 / pi )
The added parentheses compared to the raw formulas are mandatory to not 
undergo an unwanted precedence change of operators when the macros are used 
in any context of expressions.



---------------------------------------------------------------- GfxLib ----
GfxLib - FreeBASIC graphics library overview

The libary named GfxLib is the built-in graphics library included in FreeBAS
IC. As well as re-creating every QuickBASIC graphics command, GfxLib has 
built-in commands to handle input from the keyboard and mouse. Major 
contributors of the library are Lillo, coderJeff and DrV.

The library supports various drivers depending on the platform: 

   * All:
      * Null Does nothing, allows to use graphics functions on in-memory 
        buffers and such, without anything being displayed in a graphics 
        window.  (gfxlib2/gfx_driver_null.c)

   * Win32:
      * DirectX The default selection of FB GfxLib. May not be available 
        on old Windows installations. (gfxlib2/win32/gfx_driver_ddraw.c)
      * GDI The "safest" one, available in all Win32 versions. Bug note: 
        broken in FB versions 0.20 to 0.24 (crash), and minor problems 
        0.18.5, and 0.90.x and 1.xx ("banding effects", try extra 
        SCREENUNLOCK), (forum discussion: p=106600) 
        (gfxlib2/win32/gfx_driver_gdi.c)
      * OpenGL (gfxlib2/win32/gfx_driver_opengl.c)

   * Linux & others:
      * X11 The default on Unix systems  (gfxlib2/unix/gfx_driver_x11.c)
      * OpenGL (on top of X11) (gfxlib2/unix/gfx_driver_opengl_x11.c)
      * FBDev Linux framebuffer device -- fallback in case X11 is disabled 
        (gfxlib2/linux/gfx_driver_fbdev.c)

   * DOS:
      * BIOS (gfxlib2/dos/gfx_driver_bios.c)
      * ModeX "tuned" 320x240x8bpp VGA mode 
        (gfxlib2/dos/gfx_driver_modex.c)
      * VESA banked compatible with very old VESA 1.x implementations 
        (gfxlib2/dos/gfx_driver_vesa_bnk.c)
      * VESA linear needs VESA version at least 2.0, usually faster than 
        banked VESA (gfxlib2/dos/gfx_driver_vesa_lin.c)
      * VGA (gfxlib2/dos/gfx_driver_vga.c)
      * Bug note: Palette doesn't work well 
        (forum discussion: t=12691 2008) (forum discussion: t=19980 2012)

ScreenControl can be used (SET_DRIVER_NAME 103) to override the default 
driver preferences.

Platform Differences
   * In DOS, GfxLib will create and "manage" a mouse arrow if a mouse 
     driver is detected. There is no "official" way to disable this. Also 
     note that the arrow doesn't react to mouse movements while the screen 
     is locked.
   * In DOS, Windowing and OpenGL related commands and switches are not 
     available (they exist but do nothing, or return some values with no 
     meaning)
   * In DOS, the refresh rate setting is not available (some VESA cards do 
     support it, but FreeBASIC for now doesn't)
   * In DOS, the resolution must match one supported by the graphics card. 
     GfxLib will try to find an appropriate mode from VGA modes, ModeX or 
     VESA, preferring VESA LFB interface if available, or banked VESA 
     otherwise. Unsupported resolutions may currently crash the program (if 
     you fail to check SCREENPTR for ZERO before using it), though in 
     future GfxLib may try to find a close match instead. For optimal 
     compatibility, you should support "safe" resolutions like 640x480 and 
     800x600, and maybe 1024x768. There are various additional modes like 
     768x576 around, but they are vendor specific and lacking on many other 
     cards. Also modes 1024x768 and above are not available on older cards 
     and laptops.
   * It has been observed that SCREEN and SCREENRES may fail to clear the 
     screen in DOS, actually this is probably a BIOS bug that GfxLib 
     currently doesn't workaround.

Differences from QB
   * Graphics support was internally redesigned. QB used VGA graphics 
     modes, and wrote directly into the VGA RAM. Multiple pages were 
     available as long as the card supported them. FB uses backbuffers, one 
     per defined page, and copies them to the video RAM (VGA (DOS), VESA 
     (DOS), DirectX (Win32), ...) in the background. Graphics commands do 
     work as they used to in QB, but a few notable differences are present:
      * The background screen updating eats a considerable amount of CPU 
        performance.
      * There is a thread (Win32 and Linux) or ISR (DOS, uses the PIT) 
        active for this.
      * Mixing FB's graphics support with low-level screen accesses (VGA) 
        is not supported, even in DOS. However direct screen memory access 
        is possible using Screenptr and Screenlock and is fully portable. 
        In DOS VGA and VESA are still available, but can't be mixed with 
        FB's graphics support.

See also
   * GFX Functions Index
   * Screen The QB-like way to set graphics mode
   * ScreenRes More flexible alternative to Screen
   * ScreenList Check display modes available for FB GfxLib to use
   * ScreenControl Select driver and more 
   * ScreenLock
   * ScreenUnlock
   * ScreenPtr Semi-low level access
   * ScreenSet
   * ScreenCopy
   * ScreenInfo
   * ScreenGLProc
   * Internal pixel formats



---------------------------------------------------- GfxInternalFormats ----
Internal graphics formats

Information on the internal formats used by FreeBASIC to represent 
graphics.

Pixel formats

   When a graphics mode is set via the Screen or ScreenRes functions, 
   GfxLib creates also a framebuffer in standard system memory and sets an 
   appropriate internal pixel format for the mode. There are basically 
   three internal pixel formats, selected depending on the screen depth, as 
   described in the following table:

      +------------+------------------------+-------------+--------------------------------+
      |Screen depth|Internal bytes per pixel|Range bitmask|Pixel format                    |
      |1bpp        | 1                      | &h1         |palette color index             |
      |2bpp        | 1                      | &h3         |palette color index             |
      |4bpp        | 1                      | &hF         |palette color index             |
      |8bpp        | 1                      | &hFF        |palette color index             |
      |15/16bpp    | 2                      | &hFFFF      |RRRRRGGGGGGBBBBB                |
      |24/32bpp    | 4                      | &hFFFFFFFF  |AAAAAAAARRRRRRRRGGGGGGGGBBBBBBBB|
      +------------+------------------------+-------------+--------------------------------+

   All drawing operations work on this RAM framebuffer; when the actual 
   display needs to be updated, GfxLib copies the contents of the 
   framebuffer to the real display memory, automatically converting in the 
   process from the current internal pixel format to whatever pixel format 
   the real display uses. By limiting the internal pixel formats to 3, the 
   library prevents you having to deal with the plethora of real display 
   formats.

Color values

   When calling a graphics primitive that accepts a color, this can be 
   specified in two ways. In 8bpp or less modes, the color value must be a 
   direct 8 bits color index in the current palette, and this matches the 
   internal pixel format for those modes. In higher color depths, the color 
   value should always have the form &hAARRGGBB. This is what the RGB and 
   RGBA macros return, and is equivalent to the 24/32bpp internal pixel 
   format representation. If the current color depth is 24 or 32bpp, this 
   means the color value passes in unaltered. If a 15/16bpp mode is in use, 
   internally each primitive automatically converts the color from the 
   &hAARRGGBB form into the RRRRRGGGGGGBBBBB internal pixel format (note 
   that in this process the alpha channel is lost, as 15/16bpp modes do not 
   support it). Once the color value is in one of the three pixel formats, 
   the primitive limits its range to the range supported by the current 
   color depth, by using a bitwise And operation with a range bitmask. So 
   if in 8bpp, the color value passed is Anded by &hFF for example.

Notes on transparency

   For 8bpp or less modes, color index 0 is always treated as the 
   transparent color for the Put modes that support transparency. For 
   higher depths, RGB(255, 0, 255) always represents the transparent color. 
   In 15/16bpp modes, this translates to the internal value &hF81F, whereas 
   in 24/32bpp modes it becomes &hFFFF00FF. Note that in 24/32bpp modes, Put
   identifies the transparent color by looking just at the red, green and 
   blue components of the color value, while the alpha value can assume any 
   value. This means that in 24/32bpp modes, &h00FF00FF, &h10FF00FF, 
   &hABFF00FF and &hFFFF00FF for example all represent the transparent 
   color, since the lower 24 bits are always &hFF00FF.

Buffer formats

   In FreeBASIC, images can be used as arrays (as in QB) or as pointers. 
   Either way, the image data is contained in one continuous chunk. The 
   chunk consists of an header followed by the image data. The header can 
   be of two types (old-style and new-style) and determines the format of 
   the following image data.

      Old-style chunk header consists of 4 bytes (32 bits, or 4 bytes). The 
      first 3 bits contain the image color depth in bytes per pixel (8-bit 
      color depth -> 1; 16-bit color depth -> 2; 32-bit color depth -> 4). 
      The next 13 bits contain the image width. The last 16 bits contain 
      the image's height. Please note the intrinsic nature of the header 
      allows only for sizes up to 8191 * 65535 pixels. The actual pixel 
      data follows the header, and is compacted one row of pixels after 
      another; no data alignment is assumed. The final size of the chunk 
      can then be computed using the formula:

         size = 4 + ( width * height * bytes_per_pixel )

      New-style chunk header consists of 32 bytes. The first dword (32 
      bits) must be equal to the value 7, allowing GfxLib to identify the 
      new type of chunk. The second dword contains the image color depth in 
      bytes per pixel. The third and fourth dwords contain the image width 
      and height respectively, effectively removing the image size limit 
      enforced by the old-style image chunks. The fifth dword contains the 
      pixel row pitch in bytes; this tells how many bytes a row of pixels 
      in the image takes up. The pitch in new-style chunks is always padded 
      to a multiple of 16, to allow pixels' row data to be aligned on the 
      paragraph boundary. The remaining 3 dwords (total 12 bytes) of the 
      header are currently unused and reserved for future use. The final 
      size of the image is:

         size = 32 + ( ( ( ( width * bytes_per_pixel ) + &hF ) and not &hF 
         ) * height )

   The format of images created by ImageCreate and Get depend on the 
   dialect used. In the -lang fb dialect, images will be created with the 
   new-style header.  In the -lang fblite and -lang qb dialects, the 
   old-style image header is created.

   All graphics primitives can work with both old-style and new-style image 
   chunks.  For easy access to image information, ImageInfo can be used to 
   obtain useful properties of an image buffer - such as its dimensions, 
   color depth, pitch, and a pointer to the pixel data - whichever format 
   is used.
   It is also possible to access the image header directly to access this 
   information.  For more information on acessing the header structure, 
   please refer to this example.

See also
   * Screen (Graphics)
   * ScreenRes
   * Get (Graphics)
   * Put (Graphics)
   * ImageCreate
   * ImageInfo
   * Trans
   * Alpha



-------------------------------------------------------------- KeyPgAsm ----
Asm

Code block that allows the use of architecture-specific instructions.

Syntax
   Asm
      architecture-dependent instructions
   End Asm

      Or

   Asm architecture-dependent instructions

Description
   The Asm block is used to insert specific machine-code instructions in a 
   program in order to perform operations that cannot be carried out using 
   the features of the language or to hand-optimize performance-sensitive 
   sections of code.

   The current FreeBASIC compiler currently only produces code for Intel 
   80x86-based machines; however, in the future, the compiler might be 
   ported to a platform which does not support the same instruction set.  
   Therefore, Asm blocks should only be used when necessary, and a 
   FreeBASIC-only alternative should be provided if possible.

   The return value of a function may be set by using the Function keyword 
   within brackets as shown in the example below.

   Asm block comments have the same syntax as usual FreeBASIC Comments  - 
   use FreeBASIC-like " ' " comments, not " ; " as usual in assembly code. 

   x86 Specific:

      Syntax
         The syntax of the inline assembler is a simplified form of Intel 
         syntax.  Intel syntax is used by the majority of x86 assemblers, 
         such as MASM, TASM, NASM, YASM and FASM. In general, the 
         destination of an instruction is placed first, followed by the 
         source. Variables and functions defined by a program may be 
         referenced in an Asm block.  The assembler used by FreeBASIC is 
         GAS, using the .intel_syntax noprefix directive, and Asm blocks 
         are passed through unmodified, except for the substitution of 
         local variable names for stack frame references, and commenting 
         removal.

         Instruction syntax is mostly the same as FASM uses, one important 
         difference is that GAS requires size settings to be followed by 
         the word "ptr".

   ' Assuming "n" is a FB global or local ULONG variable
   mov  eax, [n]        ' OK: size is apparent from eax
   inc  [n]             ' Not OK: size is not given
   inc  dword [n]       ' Not OK: size given, but still not accepted by GAS
   inc  dword Ptr [n]   ' OK: "ptr" is needed by GAS here

      Register Preservation
         When an Asm block is opened, the registers ebx, esi, and edi are 
         pushed to the stack, when the block is closed, these registers are 
         popped back from the stack.  This is because these registers are 
         required to be preserved by most or all OS's using the x86 CPU.  
         You can therefore use these registers without explicitly 
         preserving them yourself. You should not change esp and ebp, since 
         they are usually used to address local variables. 

      Register Names
         The names of the registers for the x86 architecture are written as 
         follows in an Asm block:
         * 4-byte integer registers: eax, ebx, ecx, edx, ebp, esp, edi, 
           esi
         * 2-byte integer registers: ax, bx, cx, dx, bp, sp, di, si (low 
           words of 4-byte e- registers)
         * 1-byte integer registers: al, ah, bl, bh, cl, ch, dl, dh (low 
           and high bytes of 2-byte -x registers)
         * Floating-point registers: st(0), st(1), st(2), st(3), st(4), 
           st(5), st(6), st(7)
         * MMX registers (aliased onto floating-point registers): mm0, mm1
           , mm2, mm3, mm4, mm5, mm6, mm7
         * SSE registers: xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7

      Instruction Set

      See these external references:
         * Original Intel 80386 manual from 1986
         * Latest Intel Pentium 4 manuals
         * NASM x86 Instruction Reference (Please note that NASM is not 
           the assembler used by FreeBASIC, but this page provides a good 
           overview of x86 instructions)

      Unsafe instructions
         Note that the FreeBASIC compiler produces 32-bit protected-mode 
         code for the x86 which usually runs in an unprivileged user level; 
         therefore, privileged and sensitive instructions will assemble 
         fine, but possibly won't work correctly or cause a runtime 
         "General Protection Fault", "Illegal instruction", or SIGILL 
         error. The following are the privileged and sensitive instructions 
         as of the Intel Pentium 4 and Xeon:

         * cli *1
         * clts
         * hlt
         * in *1
         * ins *1
         * int *1               
         * into *1               
         * invd
         * invlpg
         * lgdt
         * lidt
         * lldt
         * lmsw
         * ltr
         * mov to/from CRn, DRn, TRn
         * out *1
         * outs *1
         * rdmsr
         * rdpmc *2
         * rdtsc *2
         * sti *1
         * str
         * wbinvd
         * wrmsr
         * all SSE2 and higher instructions *2

          *1: sensitive to IOPL, fine in DOS 
          *2: sensitive to permission bits in CR4, see below

   The privileged instructions will work "correctly" in DOS when running on 
   a Ring 0 DPMI kernel, like the (non-default) Ring 0 version of CWSDPMI, 
   WDOSX or D3X, nevertheless most of them are not really useful and 
   dangerous when executed from DPMI code. RDTSC (Read Time Stamp Counter) 
   has been shown to be allowed by most, or all OS'es.

   However the usefulness of RDTSC has been diminished with the advent of 
   multi-core and hibernating CPUs. SSE2 and higher instructions are 
   disabled "by default" after CPU initialization, Windows and Linux 
   usually do enable them, in DOS it is business of the DPMI host: HDPMI32 
   will enable them, CWSDPMI won't. The INT instruction is usable in the 
   DOS version/target only, note that it works slightly differently from 
   real mode DOS, see also FaqDOS.

   The segment registers (cs, ds, es, fs, gs) should not be changed from an 
   Asm block, except in certain cases with the DOS port (note that they do 
   NOT work the same way as in real-mode DOS, see also FaqDOS). The 
   operating system or DPMI host is responsible for memory management; the 
   meaning of segments (selectors) in protected mode is very different from 
   real-mode memory addressing.

   Note that those "unsafe" instructions are not guaranteed to raise a 
   "visible" crash even when ran with insufficient privilege - the OS or 
   DPMI host can decide to "emulate" them, either functionally (reading 
   from some CRx works under HDPMI32), or "dummy" (nothing happens, 
   instruction will pass silently, like a NOP).

Example
   '' This is an example for the x86 architecture.
   Function AddFive(ByVal num As Long) As Long
      Asm
         mov eax, [num]
         Add eax, 5
         mov [Function], eax
      End Asm
   End Function

   Dim i As Long = 4

   Print "4 + 5 ="; AddFive(i)

   4 + 5 = 9

   FreeBASIC's Assembler is AS / GAS, the assembler of GCC, so an external 
   program. Some quirks apply:
      * The error lines  returned by FBC for Asm blocks are not related 
        the FB source file. As FBC simply displays the errors returned by 
        AS , the lines are related to the assembly file. To make FreeBASIC 
        preserve them, the compiler must be invoked with the -R option 
        ("don't delete ASM files").
      * The label names are case sensitive inside Asm blocks.

Dialect Differences
   * Not available in the -lang qb dialect unless referenced with the 
     alias __Asm.

Differences from QB
   * New to FreeBASIC

See also
   * Function
   * Naked



---------------------------------------------------- ProPgErrorHandling ----
Error Handling

Handling runtime errors.

   FreeBASIC can handle the errors in the following ways:
   * By default the program does nothing with the errors - they are 
     silently ignored and code continues. In this case code should process 
     possible errors in the next line by using the Err function.
   * If compiled with -e, -ex or -exx options, FreeBASIC uses QB-like 
     error handling.
   * Future OOP versions of FreeBASIC may have a java-like 
     TRY..CATCH...FINALLY exception handler implemented.

   NOTE: The following information is valid unless the error produces an OS 
   General Protection Fault (for example if the program writes outside the 
   process memory area). In these cases the OS will immediately stop the 
   program and issue an error: nothing can avoid it from inside FreeBASIC.

Default error handling
   The default FreeBASIC behavior is to set the ERR variable and continue. 

   Dim As Integer e
   Open "xzxwz.zwz" For Input As #1
   e = Err
   Print e
   Sleep

   (The example program supposes there is no xzxwz.zwz file). The program 
   does not stop; it sets the ERR variable and continues. The error can be 
   processed in the next line.

   Some IO functions such as Open and Put #... can be used in function 
   form, returning an error number or zero if successful.

   Print Open ("xzxwz.zwz" For Input As #1)
   Sleep

QuickBASIC-like error handling
   If the  -e, -ex or -exx switch is used at compile time, the program is 
   expected to have a QB-like error handler enabled. If no handler 
   processes the error, the program stops with an error.

   Notice: if QB-Like error handling is used, the programmer should be 
   prepared to handle all error conditions.

   '' Compile with QB (-lang qb) dialect

   '$lang: "qb"

   On Error Goto FAILED
   Open "xzxwz.zwz" For Input As #1
   On Error Goto 0
   Sleep
   End

   FAILED:
   Dim e As Integer
   e = Err
   Print e
   Sleep
   End

   On Error sets an error handling routine which the program will jump to 
   when an error is found. On Error Goto 0 disables the error handling.

   If an error handling routine is not set when an error occurs, the 
   program will stop and send the console an error message.

   Aborting program due To runtime Error 2 (file Not found)

   The error handler routine can be at the end of the program, as in QB. 
   The On Local Error statement allows the setting of a local error handler 
   routine at the end of the same Sub or Function in which the error 
   occurs.

   '' Compile with -e
   '' The -e command line option is needed to enable error handling.

   Declare Sub foo
     foo
   Sleep

   Sub foo
      
      Dim filename As String
      Dim errmsg As String
      filename = ""
      On Local Error Goto fail
     Open filename For Input Access Read As #1
      Print "No error"
      On Local Error Goto 0
      Exit Sub
      
     fail:
     errmsg = "Error " & Err & _
            " in function " & *Erfn & _
            " on line " & Erl
     Print errmsg
      
   End Sub

   If the -e switch is used (whatever the -lang dialect), the error handler 
   must terminate the program. 
   With (-ex or -exx) and -lang qb dialect only, the error routine can end 
   by using Resume (retries the statement that caused the error) or 
   Resume Next (continues at the next instruction) .

Error codes
   See Runtime Error Codes for a listing of runtime error numbers and their 
   associated meaning.

   No user error code range is defined. If Error is used to set an error 
   code it is wise to use high values to avoid collisions with the list of 
   built-in error codes. (This built-in list may be expanded later.)

See also
   * Error Handling Functions
   * Runtime Error Codes



-------------------------------------------------------- CatPgDddefines ----
Intrinsic Defines

Preprocessor symbols defined by the compiler.

Description
   Intrinsic defines are set by the compiler and may be used as any other 
   defined symbol.  Intrinsic defines often convey information about the 
   state of the compiler, either in general or at a specific point in the 
   compilation process.  Most intrinsic defines are associated with a 
   value.

Platform Information
   Defines that provide information on the system.
Version Information
   Defines that provide information on the fbc compiler version being used.
Command-line switches
   Defines that provide information with the command-line switches used 
   with fbc.
Environment Information
   Defines that provide information about the operating system environment.
Context-specific Information
   Defines that provide context information about the compilation process.
Constants
   Built-in constants.

Platform Information
   __FB_WIN32__
      Defined if compiling for Windows.
   __FB_LINUX__
      Defined if compiling for Linux.
   __FB_DOS__
      Defined if compiling for DOS.
   __FB_CYGWIN__
      Defined if compiling for Cygwin.
   __FB_FREEBSD__
      Defined if compiling for FreeBSD.
   __FB_NETBSD__
      Defined if compiling for NetBSD.
   __FB_OPENBSD__
      Defined if compiling for OpenBSD.
   __FB_DARWIN__
      Defined if compiling for Darwin.
   __FB_XBOX__
      Defined if compiling for Xbox.
   __FB_BIGENDIAN__
      Defined if compiling on a system using big-endian byte-order.
   __FB_PCOS__
      Defined if compiling for a common PC OS (e.g. DOS, Windows, OS/2).
   __FB_UNIX__
      Defined if compiling for a Unix-like OS.
   __FB_64BIT__
      Defined if compiling for a 64bit target.
   __FB_ARM__
      Defined if compiling for the ARM architecture.

Version Information
   __FB_VERSION__
      Defined as a string literal of the compiler version.
   __FB_VER_MAJOR__
      Defined as an integral literal of the compiler major version number.
   __FB_VER_MINOR__
      Defined as an integral literal of the compiler minor version number.
   __FB_VER_PATCH__
      Defined as an integral literal of the compiler patch number.
   __FB_MIN_VERSION__
      Macro to check for a minimum compiler version.
   __FB_BUILD_DATE__
      Defined as a string literal of the compiler build date.
   __FB_SIGNATURE__ 
      Defined as a string literal of the compiler signature.

Command-line switches
   __FB_ASM__
      Defined to either "intel" or "att" depending on -asm.
   __FB_BACKEND__
      Defined to either "gas" or "gcc" depending on -gen.
   __FB_GCC__
      True (-1) if -gen gcc is used, false (0) otherwise.
   __FB_GUI__
      True (-1) if the "-s gui" switch was used, false (0) otherwise.
   __FB_MAIN__
      Defined if compiling a module with an entry point.
   __FB_DEBUG__
      True (-1) if the "-g" switch was used, false (0) otherwise.
   __FB_ERR__
      Zero (0) if neither the "-e", "-ex" or "-exx" switches were used.
   __FB_FPMODE__
      Defined as "fast" if compiling for fast SSE math, "precise" 
      otherwise.
   __FB_FPU__
      Defined as "sse" if compiling for SSE floating point unit, or "x87" 
      for normal x87 floating-point unit.
   __FB_LANG__
      Defined to a string literal of the "-lang" dialect used.
   __FB_MT__
      True (-1) if the "-mt" switch was used, false (0) otherwise.
   __FB_OUT_DLL__
      True (-1) in a module being compiled and linked into a shared 
      library, false (0) otherwise.
   __FB_OUT_EXE__
      True (-1) in a module being compiled and linked into an executable, 
      false (0) otherwise.
   __FB_OUT_LIB__
      True (-1) in a module being compiled and linked into a static 
      library, zero (0) otherwise.
   __FB_OUT_OBJ__
      True (-1) in a module being compiled only, zero (0) otherwise.
   __FB_SSE__
      Defined if compiling for SSE floating point unit.
   __FB_VECTORIZE__
      Defined as the level of automatic vectorization (0 to 2)
Environment Information
   __FB_ARGC__
      Defined as an integer literal of the number of command-line arguments 
      passed to the program.
   __FB_ARGV__
      Defined as a ZString Ptr Ptr to the command line arguments passed to 
      the program.
   __DATE__
      Defined as a string literal of the compilation date in "mm-dd-yyyy" 
      format.
   __DATE_ISO__
      Defined as a string literal of the compilation date in "yyyy-mm-dd" 
      format.
   __TIME__
      Defined as a string literal of the compilation time.
   __PATH__
      Defined as a string literal of the absolute path of the module.

Context-specific Information
   __FILE__ and __FILE_NQ__
      Defined as the name of the module.
   __FUNCTION__ and __FUNCTION_NQ__
      Defined as the name of the procedure where it's used.
   __LINE__
      Defined as an integer literal of the line of the module where it's 
      used.
   __FB_OPTION_BYVAL__
      True (-1) if parameters are declared by value by default, zero (0) 
      otherwise.
   __FB_OPTION_DYNAMIC__
      True (-1) if all arrays are variable-length, zero (0) otherwise.
   __FB_OPTION_ESCAPE__
      True (-1) if string literals are processed for escape sequences, zero 
      (0) otherwise.
   __FB_OPTION_GOSUB__
      True (-1) if gosub support is enabled, zero (0) otherwise.
   __FB_OPTION_EXPLICIT__
      True (-1) if variables and objects need to be explicitly declared, 
      zero (0) otherwise.
   __FB_OPTION_PRIVATE__
      True (-1) if all procedures are private by default, zero (0) 
      otherwise.

Constants
   False and True
      Intrinsic constants for the Boolean data type.



--------------------------------------------------------- ProPgCruntime ----
C Standard Library Functions

This is a list of function prototypes in the standard C library in 
alphabetical order and a list of prototypes grouped by functionality. 

Alphabetical List
Buffer Manipulation
Character Classification and Conversion
Data Conversion
Directory Manipulation
File Manipulation
Stream I/O
Low level I/O
Mathematics
Memory Allocation
Process Control
Searching and Sorting
String Manipulation
Time

Description
   The Comments column contains a very brief description of the use of the 
   function. The list is not complete, however it provides information on 
   the major functions in the C Runtime Library. It should, at the very 
   least, indicate what functions are available in the standard C library 
   allow you to do more investigation on your own.  Some of the C library 
   functions documented elsewhere may not be available in FreeBASIC.  Check 
   the appropriate include file for more information. 

   Note: The following prototypes are not the official FreeBASIC prototypes 
   (see the include files), however, they will give you enough information 
   to properly use the functions. 

   The Include File column contains the name of the file which you must 
   include, using the #include directive at the beginning of your program. 
   If you don't include the appropriate include file, the program either 
   will not compile, or it will compile apparently correctly but give 
   incorrect results when run.  All of the C Runtime headers are located in 
   the crt directory; for example, if the specified header is math.bi, use 
   #include "crt/math.bi" or #include "crt\math.bi", our just #include 
   "crt.bi" including all the others.

   The Prototype column contains the following information: 
      * The name of the function; 
      * The parameters required for the function in parenthesis, together 
        with the data-type of the parameters; 
      * The data-type of the value returned by the function. 

   For example atoi(a as zstring ptr) as integer means that the function 
   atoi returns a value of type integer and requires a character zstring 
   ptr as its argument. 

   Note: In order to make calling the C runtime functions very easy, any 
   string type argument may be directly passed to a procedure referring to 
   a parameter declared as 'zstring ptr'. The compiler performs itself an 
   automatic conversion (without warning message) between any string type 
   argument and the 'zstring ptr' type parameter.

Alphabetical List

      +--------+----------------------------------------------------------------------------+------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
      |Name    |Prototype (with parameters)                                                 |Include File|Comments                                                                                                                                                                                                      |
      |abs_    |abs_(n as integer) as integer                                               |stdlib.bi   |Returns the absolute value (i.e. positive value)                                                                                                                                                              |
      |acos_   |acos_(a as double) as double                                                |math.bi     |Returns the inverse cosine (angle in radians)                                                                                                                                                                 |
      |asin_   |asin_(a as double) as double                                                |math.bi     |Returns the inverse sine (angle in radians)                                                                                                                                                                   |
      |atan_   |atan_(a as double) as double                                                |math.bi     |Returns the inverse tan (angle in radians)                                                                                                                                                                    |
      |atan2_  |atan2_(y as double, x as double) as double                                  |math.bi     |Returns the inverse tan (pass the opposite as y and the adjacent as x)                                                                                                                                        |
      |atoi    |atoi(s as zstring ptr) as integer                                           |stdlib.bi   |Converts a character zstring of digits to a number of type integer.                                                                                                                                           |
      |atof    |atof(s as zstring ptr) as double                                            |stdlib.bi   |Converts a character zstring of digits to a number of type double.                                                                                                                                            |
      |calloc  |calloc(NumElts as integer, EltSiz as integer) as any ptr                    |stdlib.bi   |Allocates memory. Returns a pointer to a buffer for an array having NumElts elements, each of size EltSiz bytes.                                                                                              |
      |ceil    |ceil(d as double) as double                                                 |math.bi     |Returns the nearest whole number above the value passed.                                                                                                                                                      |
      |clearerr|clearerr(s as FILE ptr)                                                     |stdio.bi    |Clears the error indicators on a file stream (read or write).                                                                                                                                                 |
      |cos_    |cos_(ar as double) as double                                                |math.bi     |Returns the cosine of an angle measured in radians.                                                                                                                                                           |
      |cosh    |cosh(x as double) as double                                                 |math.bi     |Returns the hyperbolic cosine of an angle measured in radians.                                                                                                                                                |
      |div     |div(num as integer, denom as integer) as div_t                              |stdlib.bi   |Returns the quotient and remainder of a division as a structure of type div_t.                                                                                                                                |
      |ecvt    |ecvt(x as double) as zstring ptr                                            |math.bi     |Converts a number to a zstring.                                                                                                                                                                               |
      |exit_   |exit_(status as integer)                                                    |stdlib.bi   |Exits a program. It will flush file buffers and closes all opened files, and run any functions called by atexit().                                                                                            |
      |exp_    |exp_(a as double) as double                                                 |math.bi     |Returns the value of e raised to the power of the argument (Inverse to natural logarithm).                                                                                                                    |
      |fabs    |fabs(d as double) as double                                                 |math.bi     |Returns the absolute value (i.e. positive value) of type double.                                                                                                                                              |
      |fclose  |fclose(s as FILE ptr) as FILE ptr                                           |stdio.bi    |Closes a file. Returns 0 if successful otherwise EOF.                                                                                                                                                         |
      |feof    |feof(s as FILE ptr) as integer                                              |stdio.bi    |Returns value of end-of-file indicator . (0 if not eof). Indicator will clear itself but can be reset by clearerr().                                                                                          |
      |ferror  |ferror(s as FILE ptr) as integer                                            |stdio.bi    |Returns error indicator for a stream (0 if no error). Error indicator is reset by clearerr() or rewind().                                                                                                     |
      |fflush  |fflush(s as FILE ptr) as integer                                            |stdio.bi    |Flushes (i.e. deletes) a stream (use stdin to flush the stream from the keyboard). Returns 0 if successful.                                                                                                   |
      |fgetc   |fgetc(s as FILE ptr) as integer                                             |stdio.bi    |Single character input (in ASCII) from passed stream (stdin for keyboard).                                                                                                                                    |
      |fgetpos |fgetpos(s as FILE ptr, c as fpos_t ptr) as integer                          |stdio.bi    |Saves the position of the file pointer on stream s at the location pointed to by c.                                                                                                                           |
      |fgets   |fgets(b as zstring ptr, n as integer, s as FILE ptr) as zstring ptr         |stdio.bi    |From the stream s reads up to n-1 characters to buffer b.                                                                                                                                                     |
      |floor   |floor(d as double) as double                                                |math.bi     |Returns the nearest whole number below the value passed.                                                                                                                                                      |
      |fmod    |fmod(x as double, y as double) as double                                    |math.bi     |Calculates the remainder of x divided by y.                                                                                                                                                                   |
      |fopen   |fopen(file as zstring ptr, mode as zstring ptr) as FILE ptr                 |stdio.bi    |Opens a file. Pass the DOS name of the file and a code to indicate whether for reading, writing, or appending. Codes are r for read, w for write, + for read and write, a for append and b to indicate binary.|
      |fprintf |fprintf(s as FILE ptr, fmt as zstring ptr, ...) as integer                  |stdio.bi    |Prints on stream s as many items as there are single % signs in fmt that have matching arguments in the list.                                                                                                 |
      |fputc   |fputc(c as integer, s as FILE ptr) as integer                               |stdio.bi    |Outputs the single character c to the stream s.                                                                                                                                                               |
      |fputs   |fputs(b as zstring ptr, s as FILE ptr) as integer                           |stdio.bi    |Sends the character stream in b to stream s, returns 0 if the operation fails.                                                                                                                                |
      |fread   |fread(buf as any ptr, b as size_t, c as size_t, s as FILE ptr) as integer   |stdio.bi    |Reads the number c items of data of size b bytes from file s to the buffer buf. Returns the number of data items actually read.                                                                               |
      |free    |free(p as any ptr)                                                          |stdlib.bi   |Frees the memory allocation for a pointer p to enable this memory to be used.                                                                                                                                 |
      |freopen |freopen(file as zstring ptr, mode as zstring ptr, s as FILE ptr) as FILE ptr|stdio.bi    |Opens a file for redirecting a stream. e.g. freopen("myfile", "w", stdout) will redirect the standard output to the opened "myfile".                                                                          |
      |frexp   |frexp(x as double, p as integer ptr) as double                              |math.bi     |Calculates a value m so that x equals m times 2 to some power. p is a pointer to m.                                                                                                                           |
      |fscanf  |fscanf(s as FILE ptr, fmt as zstring ptr, ...) as integer                   |stdio.bi    |Reads from stream s as many items as there are % signs in fmt with corresponding listed pointers.                                                                                                             |
      |fseek   |fseek(s as FILE ptr, offset as integer, origin as integer) as integer       |stdio.bi    |Locates a file pointer. With origin 0, 1 or 2 for the beginning, offset bytes into and at the end of the stream.                                                                                              |
      |fsetpos |fsetpos(s as FILE ptr, p as fpos_t ptr) as integer                          |stdio.bi    |Sets the file pointer for the stream s to the value pointed to by p.                                                                                                                                          |
      |ftell   |ftell(s as FILE ptr) as long                                                |stdio.bi    |Locates the position of the file pointer for the stream s.                                                                                                                                                    |
      |fwrite  |fwrite(buf as any ptr, b as integer, c as integer, s as FILE ptr) as integer|stdio.bi    |Writes the number c items of data of size b bytes from the buffer buf to the file s. Returns the number of data items actually written.                                                                       |
      |getc    |getc(s as FILE ptr) as integer                                              |stdio.bi    |Macro for single character input (in ASCII) from passed stream. (stdin for keyboard)                                                                                                                          |
      |getchar |getchar() as integer                                                        |stdio.bi    |Single character input from the standard input                                                                                                                                                                |
      |gets    |gets(b as zstring ptr) as zstring ptr                                       |stdio.bi    |Reads a stream of characters from the standard input until it meets \n or EOF.                                                                                                                                |
      |hypot   |hypot(x as double, y as double) as double                                   |math.bi     |Calculates the hypotenuse from the sides x and y.                                                                                                                                                             |
      |isalnum |isalnum(c as integer) as integer                                            |ctype.bi    |Returns a non zero value if character c is alphabetic or a digit.                                                                                                                                             |
      |isalpha |isalpha(c as integer) as integer                                            |ctype.bi    |Returns a non zero value if character c is alphabetic.                                                                                                                                                        |
      |iscntrl |iscntrl(c as integer) as integer                                            |ctype.bi    |Returns a non zero value if character c is a control character.                                                                                                                                               |
      |isdigit |isdigit(c as integer) as integer                                            |ctype.bi    |Returns a non zero value if character c is a digit.                                                                                                                                                           |
      |isgraph |isgraph(c as integer) as integer                                            |ctype.bi    |Returns a non zero value if character c is alphabetic.                                                                                                                                                        |
      |islower |islower(c as integer) as integer                                            |ctype.bi    |Returns a non-zero value if character c is a lower case character.                                                                                                                                            |
      |isprint |isprint(c as integer) as integer                                            |ctype.bi    |Returns a non zero value if character c is printable.                                                                                                                                                         |
      |ispunct |ispunct(c as integer) as integer                                            |ctype.bi    |Returns a non zero value if character c is a punctuation character.                                                                                                                                           |
      |isspace |isspace(c as integer) as integer                                            |ctype.bi    |Returns a non zero value if character c denotes a space.                                                                                                                                                      |
      |isupper |isupper(c as integer) as integer                                            |ctype.bi    |Returns a non-zero value if character c is an upper case character.                                                                                                                                           |
      |isxdigit|isxdigit(c as integer) as integer                                           |ctype.bi    |Returns a non-zero value if character c is a hex digit (0 to F or f).                                                                                                                                         |
      |ldexp   |ldexp(x as double, n as integer) as double                                  |math.bi     |Returns the product of x and 2 to the power n.                                                                                                                                                                |
      |ldiv    |ldiv(num as long, denom as long) as ldiv_t                                  |stdlib.bi   |Returns the quotient and remainder of a division as a structure of type ldiv_t.                                                                                                                               |
      |log_    |log_(a as double) as double                                                 |math.bi     |Returns the natural logarithm of the argument.                                                                                                                                                                |
      |log10   |log10(a as double) as double                                                |math.bi     |Returns the logarithm to the base 10 of the argument.                                                                                                                                                         |
      |malloc  |malloc(bytes as integer) as any ptr                                         |stdlib.bi   |Allocates memory. Returns a pointer to a buffer comprising storage for the specified size.                                                                                                                    |
      |modf    |modf(d as double, p as double ptr) as double                                |math.bi     |Returns the fractional part of a floating point number d. p points to the integral part expressed as a float.                                                                                                 |
      |perror  |perror(mess as zstring ptr)                                                 |stdio.bi    |Prints on the stream stderr a message passed as the argument.                                                                                                                                                 |
      |pow     |pow(x as double, y as double) as double                                     |math.bi     |Returns x to the power y.                                                                                                                                                                                     |
      |pow10   |pow10(x as double) as double                                                |math.bi     |Returns 10 to the power x (inverse function to log10()).                                                                                                                                                      |
      |printf  |printf(fmt as zstring ptr, ...) as integer                                  |stdio.bi    |Prints on standard output as many items as there are single % signs in fmt with matching arguments in the list.                                                                                               |
      |putc    |putc(c as integer, s as FILE ptr) as integer                                |stdio.bi    |Macro to output the single character c to the stream s.                                                                                                                                                       |
      |putchar |putchar(c as integer) as integer                                            |stdio.bi    |Macro to output the single character c to the standard output.                                                                                                                                                |
      |puts    |puts(b as zstring ptr) as integer                                           |stdio.bi    |Sends the character stream in b to the standard output, returns 0 if operation fails.                                                                                                                         |
      |rand    |rand() as integer                                                           |stdlib.bi   |Returns a pseudo random number. A seed is required. The seed is set with srand.                                                                                                                               |
      |realloc |realloc(p as any ptr, newsize as size_t) as any ptr                         |stdlib.bi   |Allocates memory. Returns a pointer to a buffer for a change in size of object pointed to by p.                                                                                                               |
      |rewind  |rewind(s as FILE ptr)                                                       |stdio.bi    |Clears the error indicators on a file stream (read or write). Necessary before reading an amended file.                                                                                                       |
      |scanf   |scanf(fmt as zstring ptr, ...) as integer                                   |stdio.bi    |Reads from standard input as many items as there are % signs in fmt with corresponding listed pointers.                                                                                                       |
      |sin_    |sin_(ar as double) as double                                                |math.bi     |Returns the sine of an angle measured in radians.                                                                                                                                                             |
      |sinh    |sinh(x as double) as double                                                 |math.bi     |Returns the hyperbolic sine of an angle measured in radians.                                                                                                                                                  |
      |sprintf |sprintf(p as zstring ptr, fmt as zstring ptr, ...) as integer               |stdio.bi    |Prints on zstring p as many items as there are single % signs in fmt that have matching arguments in the list.                                                                                                |
      |sqrt    |sqrt(a as double) as double                                                 |math.bi     |Returns the square root of the value passed. Domain error if value is negative.                                                                                                                               |
      |srand   |srand(seed as uinteger)                                                     |stdlib.bi   |Sets the seed for a random number. A possible seed is the current time.                                                                                                                                       |
      |sscanf  |sscanf(b as zstring ptr, fmt as zstring ptr, ...) as integer                |stdio.bi    |Reads from buffer b as many items as there are % signs in fmt with corresponding listed pointers.                                                                                                             |
      |strcat  |strcat(s1 as zstring ptr, s2 as zstring ptr) as zstring ptr                 |string.bi   |Concatenates (appends) zstring s2 to s1.                                                                                                                                                                      |
      |strchr  |strchr(s as zstring ptr, c as integer) as zstring ptr                       |string.bi   |Returns a pointer to the first occurrence of c in s or NULL if it fails to find one.                                                                                                                          |
      |strcmp  |strcmp(s1 as zstring ptr, s2 as zstring ptr) as integer                     |string.bi   |Compares zstring s2 to s1. Returns 0 or signed difference in ASCII values of first non matching character.                                                                                                    |
      |strcpy  |strcpy(s1 as zstring ptr, s2 as zstring ptr) as zstring ptr                 |string.bi   |Copies s2 into s1.                                                                                                                                                                                            |
      |strcspn |strcspn(s1 as zstring ptr, s2 as zstring ptr) as integer                    |string.bi   |Returns the number of characters in s1 encountered before meeting any of the characters in s2.                                                                                                                |
      |strerror|strerror(n as integer) as zstring ptr                                       |string.bi   |Returns a pointer to a system error message corresponding to the passed error number.                                                                                                                         |
      |strlen  |strlen(s as zstring ptr) as integer                                         |string.bi   |Returns the number of bytes in the null terminated zstring pointed to by s (does not count null).                                                                                                             |
      |strncat |strncat(s1 as zstring ptr, s2 as zstring ptr, n as integer) as zstring ptr  |string.bi   |Concatenates (appends) n bytes from zstring s2 to s1.                                                                                                                                                         |
      |strncmp |strncmp(s1 as zstring ptr, s2 as any ptr, n as integer) as integer          |string.bi   |Compares n bytes of zstring s2 to the same of s1. Returns 0 or signed difference in ASCII values of first non matching character.                                                                             |
      |strncpy |strncpy(s1 as zstring ptr, s2 as zstring ptr, n as integer) as zstring ptr  |string.bi   |Copies n bytes from s2 into s1.                                                                                                                                                                               |
      |strpbrk |strpbrk(s1 as zstring ptr, s2 as zstring ptr) as zstring ptr                |string.bi   |Returns a pointer to the first character encountered in s1 that is also in s2.                                                                                                                                |
      |strrchr |strrchr(s as zstring ptr, c as integer) as zstring ptr                      |string.bi   |Returns a pointer to the last occurrence of c in s or NULL if it fails to find one.                                                                                                                           |
      |strspn  |strspn(s1 as zstring ptr, s2 as zstring ptr) as integer                     |string.bi   |Returns the number of characters in s1 encountered before meeting a character which is not in s2.                                                                                                             |
      |strstr  |strstr(s1 as zstring ptr, s2 as zstring ptr) as zstring ptr                 |string.bi   |Finds the location of the zstring s2 in s1 and returns a pointer to its leading character.                                                                                                                    |
      |strtod  |strtod(s as zstring ptr, p as zstring ptr) as double                        |stdlib.bi   |Converts a zstring to double, provided the zstring is written in the form of a number.                                                                                                                        |
      |strtok  |strtok(s1 as zstring ptr, s2 as zstring ptr) as zstring ptr                 |string.bi   |Returns pointers to successive tokens utilizing the zstring s1. Tokens regarded as separators are listed in s2.                                                                                               |
      |system  |system(command as zstring ptr) as integer                                   |stdlib.bi   |Executes, from within a program, a command addressed to the operating system written as a zstring (e.g. DIR on Windows and DOS and LS on Linux).                                                              |
      |tan_    |tan_(ar as double) as double                                                |math.bi     |Returns the tangent of an angle measured in radians.                                                                                                                                                          |
      |tanh    |tanh(x as double) as double                                                 |math.bi     |Returns the hyperbolic tangent of an angle measured in radians.                                                                                                                                               |
      |tolower |tolower(c as integer) as integer                                            |ctype.bi    |Converts a character from upper case to lower case (uses ASCII code).                                                                                                                                         |
      |toupper |toupper(c as integer) as integer                                            |ctype.bi    |Converts a character from lower case to upper case (uses ASCII code).                                                                                                                                         |
      |ungetc  |ungetc(c as integer, s as FILE ptr) as integer                              |stdio.bi    |Pushes a character c back into the stream s, returns EOF if unsuccessful. Do not push more than one character.                                                                                                |
      +--------+----------------------------------------------------------------------------+------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

Buffer Manipulation

   #include "crt/string.bi"

      +----------------------------------------------------------------+--------------------------------------------------+
      |Prototype (with parameters)                                     |Comments                                          |
      |memchr(s as any ptr, c as integer, n as size_t) as any ptr      |Search for a character in a buffer.               |
      |memcmp(s1 as any ptr, s2 as any ptr, n as size_t) as integer    |Compare two buffers.                              |
      |memcpy(dest as any ptr, src as any ptr, n as size_t) as any ptr |Copy one buffer into another .                    |
      |memmove(dest as any ptr, src as any ptr, n as size_t) as any ptr|Move a number of bytes from one buffer lo another.|
      |memset(s as any ptr, c as integer, n as size_t) as any ptr      |Set all bytes of a buffer to a given character.   |
      +----------------------------------------------------------------+--------------------------------------------------+

Character Classification and Conversion

   #include "crt/ctype.bi"

      +---------------------------------+-------------------------------------+
      |Prototype (with parameters)      |Comments                             |
      |isalnum(c as integer) as integer |True if c is alphanumeric.           |
      |isalpha(c as integer) as integer |True if c is a letter.               |
      |isascii(c as integer) as integer |True if c is ASCII .                 |
      |iscntrl(c as integer) as integer |True if c is a control character.    |
      |isdigit(c as integer) as integer |True if c is a decimal digit.        |
      |isgraph(c as integer) as integer |True if c is a graphical character.  |
      |islower(c as integer) as integer |True if c is a lowercase letter.     |
      |isprint(c as integer) as integer |True if c is a printable character.  |
      |ispunct(c as integer) as integer |True if c is a punctuation character.|
      |isspace(c as integer) as integer |True if c is a space character.      |
      |isupper(c as integer) as integer |True if c is an uppercase letter.    |
      |isxdigit(c as integer) as integer|True if c is a hexadecimal digit.    |
      |toascii(c as integer) as integer |Convert c to ASCII .                 |
      |tolower(c as integer) as integer |Convert c to lowercase.              |
      |toupper(c as integer) as integer |Convert c to uppercase.              |
      +---------------------------------+-------------------------------------+

Data Conversion

   #include "crt/stdlib.bi"

      +---------------------------------------------------------------------------------+--------------------------------------------------------+
      |Prototype (with parameters)                                                      |Comments                                                |
      |atof(string1 as zstring ptr) as double                                           |Convert zstring to floating point value.                |
      |atoi(string1 as zstring ptr) as integer                                          |Convert zstring to an integer value.                    |
      |atol(string1 as zstring ptr) as integer                                          |Convert zstring to a long integer value.                |
      |itoa(value as integer, zstring as zstring ptr, radix as integer) as zstring ptr  |Convert an integer value to a zstring using given radix.|
      |ltoa(value as long, zstring as zstring ptr, radix as integer) as zstring ptr     |Convert long integer to zstring in a given radix.       |
      |strtod(string1 as zstring ptr, endptr as zstring ptr) as double                  |Convert zstring to a floating point value.              |
      |strtol(string1 as zstring ptr, endptr as zstring ptr, radix as integer) as long  |Convert zstring to a long integer using a given radix.  |
      |strtoul(string1 as zstring ptr, endptr as zstring ptr, radix as integer) as ulong|Convert zstring to unsigned long.                       |
      +---------------------------------------------------------------------------------+--------------------------------------------------------+

Directory Manipulation

   #include "crt/io.bi"

      +----------------------------------------------------------------+------------------------------------------+
      |Prototype (with parameters)                                     |Comments                                  |
      |_chdir(path as zstring ptr) as integer                          |Change current directory to given path.   |
      |_getcwd(path as zstring ptr, numchars as integer) as zstring ptr|Returns name of current working directory.|
      |_mkdir(path as zstring ptr) as integer                          |Create a directory using given path name. |
      |_rmdir(path as zstring ptr) as integer                          |Delete a specified directory.             |
      +----------------------------------------------------------------+------------------------------------------+

File Manipulation

   #include "crt/sys/stat.bi"
   #include "crt/io.bi"

      +------------------------------------------------------------------+------------------------------------------+
      |Prototype (with parameters)                                       |Comments                                  |
      |chmod(path as zstring ptr, pmode as integer) as integer           |Change permission settings of a file.     |
      |fstat(handle as integer, buffer as type stat ptr) as integer      |Get file status information.              |
      |remove(path as zstring ptr) as integer                            |Delete a named file.                      |
      |rename_(oldname as zstring ptr, newname as zstring ptr) as integer|rename a file.                            |
      |stat(path as zstring ptr, buffer as type stat ptr) as integer     |Get file status information of named file.|
      |umask(pmode as uinteger) as uinteger                              |Set file permission mask.                 |
      +------------------------------------------------------------------+------------------------------------------+

Stream I/O

   #include "crt/stdio.bi"

      +------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------+
      |Prototype (with parameters)                                                                                 |Comments                                                         |
      |clearerr(file_pointer as FILE ptr)                                                                          |Clear error indicator of stream,                                 |
      |fclose(file_pointer as FILE ptr) as integer                                                                 |Close a file,                                                    |
      |feof(file_pointer as FILE ptr) as integer                                                                   |Check if end of file occurred on a stream.                       |
      |ferror(file_pointer as FILE ptr) as integer                                                                 |Check if any error occurred during file I/0.                     |
      |fflush(file_pointer as FILE ptr) as integer                                                                 |Write out (flush) buffer to file.                                |
      |fgetc(file_pointer as FILE ptr) as integer                                                                  |Get a character from a stream.                                   |
      |fgetpos(file_pointer as FILE ptr, fpos_t current_pos) as integer                                            |Get the current position in a stream.                            |
      |fgets(string1 as zstring ptr, maxchar as integer, file_pointer as FILE ptr) as zstring ptr                  |Read a zstring from a file.                                      |
      |fopen(filename as zstring ptr, access_mode as zstring ptr) as FILE ptr                                      |Open a file for buffered I/0.                                    |
      |fprintf(file_pointer as FILE ptr, format_string as zstring ptr, args) as integer                            |Write formatted output to a file,                                |
      |fputc(c as integer, file_pointer as FILE ptr) as integer                                                    |Write a character to a stream.                                   |
      |fputchar(c as integer) as integer                                                                           |Write a character to stdout.                                     |
      |fputs(string1 as zstring ptr, file_pointer as FILE ptr) as integer                                          |Write a zstring to a stream.                                     |
      |fread(buffer as zstring ptr, size as size_t count as size_t, file_pointer as FILE ptr) as size_t            |Read unformatted data from a stream into a buffer.               |
      |freopen(filename as zstring ptr, access as zstring ptr mode, file_pointer as FILE ptr) as FILE ptr          |Reassign a file pointer to a different file.                     |
      |fscanf(file_pointer as FILE ptr, format as zstring ptr zstring, args) as integer                            |Read formatted input from a stream.                              |
      |fseek(file_pointer as FILE ptr, offset as long, origin as integer) as integer                               |Set current position in file to a new location.                  |
      |fsetpos(file_pointer as FILE ptr, current_pos as fpos_t) as integer                                         |Set current position in file to a new location.                  |
      |ftell(file_pointer as FILE ptr) as long                                                                     |Get current location in file.                                    |
      |fwrite(buffer as zstring ptr, size as size_t, count as size_t file_pointer as FILE ptr) as size_t           |Write unformatted data from a buffer to a stream.                |
      |getc(file_pointer as FILE ptr) as integer                                                                   |Read a character from a stream.                                  |
      |getchar() as integer                                                                                        |Read a character from stdin.                                     |
      |gets(buffer as zstring ptr) as zstring ptr                                                                  |Read a line from stdin into a buffer.                            |
      |printf(format as zstring ptr _string, args) as integer                                                      |Write formatted output to stdout.                                |
      |putc(c as integer, file_pointer as FILE ptr) as integer                                                     |Write a character to a stream.                                   |
      |putchar(c as integer) as integer                                                                            |Write a character to stdout.                                     |
      |puts(string1 as zstring ptr) as integer                                                                     |Write a zstring to stdout.                                       |
      |rewind(file_pointer as FILE ptr)                                                                            |Rewind a file.                                                   |
      |scanf(format_string as zstring ptr, args) as integer                                                        |Read formatted input from stdin.                                 |
      |setbuf(file_pointer as FILE ptr, buffer as zstring ptr)                                                     |Set up a new buffer for the stream.                              |
      |setvbuf(file_pointer as FILE ptr, buffer as zstring ptr, buf_type as integer, buf as size_t size) as integer|Set up new buffer and control the level of buffering on a stream.|
      |sprintf(string1 as zstring ptr, format_string as zstring ptr, args) as integer                              |Write formatted output to a zstring.                             |
      |sscanf(buffer as zstring ptr, format_string as zstring ptr, args) as integer                                |Read formatted input from a zstring.                             |
      |tmpfile() as FILE ptr                                                                                       |Open a temporary file.                                           |
      |tmpnam(file_name as zstring ptr) as zstring ptr                                                             |Get temporary file name.                                         |
      |ungetc(c as integer, file_pointer as FILE ptr) as integer                                                   |Push back character into stream' s buffer                        |
      +------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------+

Low level I/O

   #include "crt/io.bi"

   So far Win32 only, connects to MSVCRT.DLL (headers missing for other 
   platforms)

      +------------------------------------------------------------------------------+----------------------------------------------------+
      |Prototype (with parameters)                                                   |Comments                                            |
      |_close(handle as integer) as integer                                          |Close a file opened for unbuffered I/O.             |
      |_creat(filename as zstring ptr, pmode as integer) as integer                  |Create a new file with specified permission setting.|
      |_eof(handle as integer) as integer                                            |Check for end of file.                              |
      |_lseek(handle as integer, offset as long, origin as integer) as long          |Go to a specific position in a file.                |
      |_open(filename as zstring ptr, oflag as integer, pmode as uinteger) as integer|Open a file for low-level I/O.                      |
      |_read(handle as integer, buffer as zstring ptr, length as uinteger) as integer|Read binary data from a file into a buffer.         |
      |_write(handle as integer, buffer as zstring ptr, count as uinteger) as integer|Write binary data from a buffer to a file.          |
      +------------------------------------------------------------------------------+----------------------------------------------------+

Mathematics

   #include "crt/math.bi"

      +---------------------------------------------------+----------------------------------------------------------+
      |Prototype (with parameters)                        |Comments                                                  |
      |abs_(n as integer) as integer                      |Get absolute value of an integer.                         |
      |acos_(x as double) as double                       |Compute arc cosine of x.                                  |
      |asin_(x as double) as double                       |Compute arc sine of x.                                    |
      |atan_(x as double) as double                       |Compute arc tangent of x.                                 |
      |atan2_(y as double, x as double) as double         |Compute arc tangent of y/x.                               |
      |ceil(x as double) as double                        |Get smallest integral value that exceeds x.               |
      |cos_(x as double) as double                        |Compute cosine of angle in radians.                       |
      |cosh(x as double) as double                        |Compute the hyperbolic cosine of x.                       |
      |div(number as integer, denom as integer) as div_t  |Divide one integer by another.                            |
      |exp_(x as double) as double                        |Compute exponential of x.                                 |
      |fabs(x as double) as double                        |Compute absolute value of x.                              |
      |floor(x as double) as double                       |Get largest integral value less than x.                   |
      |fmod(x as double, y as double) as double           |Divide x by y with integral quotient and return remainder.|
      |frexp(x as double, expptr as integer ptr) as double|Breaks down x into mantissa and exponent of no.           |
      |labs(n as long) as long                            |Find absolute value of long integer n.                    |
      |ldexp(x as double, exp as integer) as double       |Reconstructs x out of mantissa and exponent of two.       |
      |ldiv(number as long, denom as long) as ldiv_t      |Divide one long integer by another.                       |
      |log_(x as double) as double                        |Compute log(x).                                           |
      |log10(x as double) as double                       |Compute log to the base 10 of x.                          |
      |modf(x as double, intptr as double ptr) as double  |Breaks x into fractional and integer parts.               |
      |pow(x as double, y as double) as double            |Compute x raised to the power y.                          |
      |rand() as integer                                  |Get a random integer between 0 and 32767.                 |
      |random(max_num as integer) as integer              |Get a random integer between 0 and max_num.               |
      |randomize()                                        |Set a random seed for the random number generator.        |
      |sin_(x as double) as double                        |Compute sine of angle in radians.                         |
      |sinh(x as double) as double                        |Compute the hyperbolic sine of x.                         |
      |sqrt(x as double) as double                        |Compute the square root of x.                             |
      |srand(seed as uinteger)                            |Set a new seed for the random number generator (rand).    |
      |tan_(x as double) as double                        |Compute tangent of angle in radians.                      |
      |tanh(x as double) as double                        |Compute the hyperbolic tangent of x.                      |
      +---------------------------------------------------+----------------------------------------------------------+

Memory Allocation

   #include "crt/stdlib.bi"

      +-------------------------------------------------------------+-------------------------------------------------------+
      |Prototype (with parameters)                                  |Comments                                               |
      |calloc(num as size_t elems, elem_size as size_t) as any ptr  |Allocate an array and initialise all elements to zero .|
      |free(mem_address as any ptr)                                 |Free a block of memory.                                |
      |malloc(num as size_t bytes) as any ptr                       |Allocate a block of memory.                            |
      |realloc(mem_address as any ptr, newsize as size_t) as any ptr|Reallocate (adjust size) a block of memory.            |
      +-------------------------------------------------------------+-------------------------------------------------------+

Process Control

   #include "crt/stdlib.bi"

      +------------------------------------------------------------------------------------------+-------------------------------------------------------+
      |Prototype (with parameters)                                                               |Comments                                               |
      |abort()                                                                                   |Abort a process.                                       |
      |execl(path as zstring ptr, arg0 as zstring ptr, arg1 as zstring ptr,..., NULL) as integer |Launch a child process (pass command line).            |
      |execlp(path as zstring ptr, arg0 as zstring ptr, arg1 as zstring ptr,..., NULL) as integer|Launch child (use PATH, pass command line).            |
      |execv(path as zstring ptr, argv as zstring ptr) as integer                                |Launch child (pass argument vector).                   |
      |execvp(path as zstring ptr, argv as zstring ptr) as integer                               |Launch child (use PATH, pass argument vector).         |
      |exit_(status as integer)                                                                  |Terminate process after flushing all buffers.          |
      |getenv(varname as zstring ptr) as zstring ptr                                             |Get definition of environment variable,                |
      |perror(string1 as zstring ptr)                                                            |Print error message corresponding to last system error.|
      |putenv(envstring as zstring ptr) as integer                                               |Insert new definition into environment table.          |
      |raise(signum as integer) as integer                                                       |Generate a C signal (exception).                       |
      |system_(string1 as zstring ptr) as integer                                                | Execute a resident operating system command.          |
      +------------------------------------------------------------------------------------------+-------------------------------------------------------+

Searching and Sorting

   #include "crt/stdlib.bi"
            Note: The compare callback function required by bsearch and 
            qsort must be declared as cdecl. It must return a value <0 if 
            its first argument should be located before the second one in 
            the sorted array, >0 if the first argument should be located 
            after the second one, and zero if their relative positions are 
            indifferent (equal values).  

      +-------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------+
      |Prototype (with parameters)                                                                                                                            |Comments                                     |
      |bsearch(key as any ptr, base as any ptr, num as size_t, width as size_t, compare as function(elem1 as any ptr, elem2 as any ptr) as integer) as any ptr|Perform binary search.                       |
      |qsort(base as any ptr, num as size_t, width as size_t, compare as function(elem1 as any ptr, elem2 as any ptr) as integer)                             |Use the quicksort algorithm to sort an array.|
      +-------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------+

String Manipulation

   #include "crt/string.bi"

      +-----------------------------------------------------------------------------------+----------------------------------------------------------+
      |Prototype (with parameters)                                                        |Comments                                                  |
      |stpcpy(dest as zstring ptr, src as zstring ptr) as zstring ptr                     |Copy one zstring into another.                            |
      |strcmp(string1 as zstring ptr, string2 as zstring ptr) as integer                  |Compare string1 and string2 to determine alphabetic order.|
      |strcpy(string1 as zstring ptr, string2 as zstring ptr) as zstring ptr              |Copy string2 to string1.                                  |
      |strerror(errnum as integer) as zstring ptr                                         |Get error message corresponding to specified error number.|
      |strlen(string1 as zstring ptr) as integer                                          |Determine the length of a zstring.                        |
      |strncat(string1 as zstring ptr, string2 as zstring ptr, n as size_t) as zstring ptr|Append n characters from string2 to string1.              |
      |strncmp(string1 as zstring ptr, string2 as zstring ptr, n as size_t) as integer    |Compare first n characters of two strings.                |
      |strncpy(string1 as zstring ptr, string2 as zstring ptr, n as size_t) as zstring ptr|Copy first n characters of string2 to string1.            |
      |strnset(string1 as zstring ptr, c as integer, size _t n) as zstring ptr            |Set first n characters of zstring to c.                   |
      |strrchr(string1 as zstring ptr, c as integer) as zstring ptr                       |Find last occurrence of character c in zstring.           |
      +-----------------------------------------------------------------------------------+----------------------------------------------------------+

Time

   #include "crt/time.bi"

      +----------------------------------------------+-------------------------------------------------------------+
      |Prototype (with parameters)                   |Comments                                                     |
      |asctime(time as type tm ptr) as zstring ptr   |Convert time from type tm to zstring.                        |
      |clock() as clock_t                            |Get elapsed processor time in clock ticks.                   |
      |ctime(time as time_t ptr) as zstring ptr      |Convert binary time to zstring.                              |
      |difftime(time_t time2, time_t time1) as double|Compute the difference between two times in seconds.         |
      |gmtime(time as time_t ptr) as type tm ptr     |Get Greenwich Mean Time (GMT) in a tm structure.             |
      |localtime(time as time_t ptr) as type tm ptr  |Get the local time in a tm structure.                        |
      |time_(timeptr as time_t ptr) as time_t        |Get current time as seconds elapsed since 0 hours GMT 1/1/70.|
      +----------------------------------------------+-------------------------------------------------------------+

See also
   * #include



----------------------------------------------------------- ProPgFileIO ----
File I/O with FreeBASIC

In FreeBASIC, there are 4 possible ways to perform file I/O:

1. Using the built-in BASIC commands like Open , Get, Put, and Close. This 
way is mostly portable across all platforms supported by FreeBASIC. Open 
files are identified by "file numbers", that are specific to FreeBASIC and 
can't be passed into functions from below.

2. Using the C stream I/O functions like fopen, fread, ftell, fclose (see 
Stream I/O in C Standard Library Functions) of the C library FreeBASIC 
relies on. This is slightly faster than and adds a few features beyond 
method above, and still well portable. Open files are identified by file 
pointers, as in the C language, again unique to this access method.  The 
FileAttr function can be used to return a stream I/O pointer from a file 
number as in 1. above.

3. Using the C low-level I/O functions like _open, _read, _write, _close 
(see Low Level I/O in C Standard Library Functions). Those functions should 
be portable, but so far headers are available for Win32 only, so code using 
them will not compile to any other platform by now.

4. Talk directly to the OS kernel (DOS: use DOS and DPMI INT's , Win32: use 
API calls like CreateFile, WriteFile). This is no longer portable. Files 
are identified by handles generated by and specific to the OS kernel.

This example shows methods 1. and 2. described above:

Example
   '==== File I/O example / 2018-05-18 ====

   Dim As String fileName = "test_123.tmp"
   Dim As ULong buffer(0 To 99) '100 x 4 bytes
   Dim As Integer numItems, result

   Print !"\n==== Using the C Runtime (CRT) file I/O ====\n"

   #include Once "crt/stdio.bi"

   Dim As FILE Ptr filePtr

   'open in binary writing mode
   filePtr = fopen(fileName, "wb")
   If filePtr <> 0 Then
      'write 75 x 4 = 300 bytes
      numItems = fwrite(@buffer(0), SizeOf(buffer(0)), 75, filePtr)
      Print "Number of bytes written: " & Str(numItems * SizeOf(buffer(0)))
      Print "Number of items written: " & Str(numItems)
      fclose(filePtr)
   Else
      Print "Failed to open " & fileName & " for writing"
   End If

   'open in binary reading mode
   filePtr = fopen(fileName, "rb")
   If filePtr <> 0 Then
      'skip the first 25 items
      If fseek(filePtr, SizeOf(buffer(0)) * 25, SEEK_SET) <> 0 Then
         Print "Failed to seek (set file stream position)"
      End If
      'try to read the next 100 items
      numItems = fread(@buffer(0), SizeOf(buffer(0)), 100, filePtr)
      Print "Number of bytes read: " & Str(numItems * SizeOf(buffer(0)))
      Print "Number of items read: " & Str(numItems)
      fclose(filePtr)
   Else
      Print "Failed to open " & fileName & " for reading"
   End If

   result = remove(fileName) 'delete file
   If result = 0 Then Print "Removed: " & fileName

   Print !"\n==== Using the FreeBASIC file I/O ====\n"

   Dim As Long fileNum
   Dim As Integer numBytes

   fileNum = FreeFile
   'open in binary writing mode
   If Open(fileName, For Binary, Access Write, As fileNum) = 0 Then
      'write 75 x 4 = 300 bytes
      result = Put(fileNum, , buffer(0), 75) 'No @buffer(0)
      numBytes = Seek(fileNum) - 1 'FreeBASIC file position is 1-based
      Print "Number of bytes written: " & Str(numBytes)
      Print "Number of items written: " & Str(numBytes \ SizeOf(buffer(0)))
      Close(fileNum)
   Else
      Print "Failed to open " & fileName & " for writing"
   End If

   'open in binary reading mode
   If Open(fileName, For Binary, Access Read, As fileNum) = 0 Then
      'skip the first 25 items
      Seek fileNum, 25 * SizeOf(buffer(0)) + 1 'Note: +1 & seek(...) not allowed
      'try to read the next 100 items
      result = Get(fileNum, , buffer(0), 100, numBytes)
      Print "Number of bytes read: " & Str(numBytes)
      Print "Number of items read: " & Str(numBytes \ SizeOf(buffer(0)))
      Close(fileNum)
   Else
      Print "Failed to open " & fileName & " for reading"
   End If

   result = Kill(fileName) 'delete file
   If result = 0 Then Print "Killed: " & fileName

   Print !"\n==== End ====\n"

 

See also
   * File I/O Functions
   * C Standard Library Functions
   * Get (File I/O Command)



---------------------------------------------------- CommunityTutorials ----
Community Tutorials

Tutorials submitted by the FreeBASIC community:
 Getting Started
   *Getting Started with FreeBASIC by SJ Zero
   *Using libraries in FreeBASIC by SJ Zero
   *Using the Mouse in FreeBASIC by MystikShadows
   *Get Information into your program by TekRat
   *Using Dynamic Arrays in FreeBASIC by SephKnows
   *Beginners Guide to Types as Objects (Part 1) by YetiFoot
   *Beginners Guide to Types as Objects (Part 2) by YetiFoot
   *Introduction to Variable Scope by rdc
   *Introduction to Arrays by rdc
   *Introduction to the Type Def by rdc
   *New To Programming? by The FB Community
   *Compiling a BIG QB program by Antoni

Game Programming
   * How to Program a Game: Lesson 1 by Lachie Dazdarian
   * Managing A High Score Table by Lachie Dazdarian

Flow Control Statements
   *The IF Statement by rdc
   *The Select Case Statement by rdc

Pre Processor
   *Conditional Compilation And You by AetherFox

Memory Management
   *Introduction to Pointers by rdc
   *Pointers, Data Types and Memory by rdc
   *The Pointer Data Type by rdc
   *Using Linked Lists by Parker
   *Dynamic Arrays in Types by rdc

  Intermediate Techniques
   *Introduction to Function Overloading in FreeBASIC by :stylin:

Mathematics
   *Different ways angles are measured by RandyKeeling
   *A Brief Introduction To Trigonometry by RandyKeeling

Windows API
   *Introduction to Message-Based Programming by rdc

Libraries
   *Interfacing with C by UtenNavn
   *SDL_NET by Paragon
   *Using FreeBASIC Built Libraries with GCC by Jeff Marshall

Object Oriented Programming
   *Introduction to the Extended Type by rdc
   *Simulating Polymorphism by rdc
   *OOP in non-OOP languages by KevinWhitefoot
   *Const Qualifiers and You by notthecheatr

FBgfx
   *Creating and Understanding Your FBgfx Img and Font Buffer by The FB 
     Community



----------------------------------------------------------- CodeLibrary ----
Community Code Library

 FreeBASIC Code, Games, and Libraries.  Written in FreeBASIC, by FreeBASIC 
Community Members.

Code Editors & IDEs 
   FBEdit, an IDE for FB by KetilO (Win32)
   WinFBE Editor and Visual Designer, an IDE for FB by Paul Squires (Win32,Win64)
   VISG GUI Builder (WIN) by mrhx

Graphics Code
   Demos
   Animated Clouds by Zamaster
   Island Generation by rdc
   Plasma Generation by Zamaster

   Graphics Functions and Primitives
   AntiAliased Bezier Curves by Acetoline
   Antialiased Circles by Acetoline
   Ellipse Renderer by Pritchard
   Catmull-rom Splines by relsoft	Bezier vs Catmull-rom by relsoft
   Accurate Image Scaler by KristopherWindsor
   Spline Curve by Zamaster
   Rotozoom by Dr_D

   Colors and Palettes
   24bit to 16bit color width by Eternal_Pain
   HSV Color Space by Antoni

   Formats
   fbpng library by yetifoot

   3D
   Tree Generation by Zamaster
   Quadtree-Based Renderer by relsoft

   Animation
   ASCII Animation Example by Pritchard
   Chain-Like Animation Tutorial by Lachie Dazdarian

Sound Code
   Mic Input using FMod by mambazo
   Using the PC Speaker by several
   Wave synthesizer by Zamaster

Math Code
   FBMath by jdebord
   A* Pathfinding by dumbledore
   Fraction Library by Zamaster
   Big Number Wrapper by Yetifoot
   BCD arithmetics by srvaldez
   10Byte extended float by srvaldez, included in FB examples
   CRC Calculation by Fragmeister

   Physics simulation
   Atom smash simulation by coderjeff
   2d rigid body library by coderjeff
   Irrlicht wrapper + Newton Intergrated by SiskinEDGE

Text/Parser Code
   Expression Parser by yetifoot
   Turing Machine by Zamaster
   Roman Numeral to Integer Conversion by stylin
   Unicode console calender, by zippy and voodooattack
   FB source to  highlighted HTML by Kristopher Windsor
   Portable help (not .chm) viewer by coderjeff
   Lisp interpreter by coderjeff

   Cryptography
   MARS encryption by Zamaster
   AES Encryption/Decryption by Zamaster
   DES/LUCIFER Encryption/Decryption by Zamaster
   MD5 Calculator by DOS386
   Tiger Hash by Mindless

FreeBASIC Games
   FreeBASIC Games Directory by Lachie Dazdarian

   Featured Games:
   Kingdoms by Piptol
   Lynn's Legacy by cha0s and Josiah Tobin
   Relativity by Lithium
   Star Cage by Lachie Dazdarian
   100 Line Tetris by Deleter
   Any PNG or JPEG as a Jigsaw Puzzle by Mysoft

GUI Code
   In Game GUI by coderJeff
   Zine GUI by VonGodric
   WX GUI example by ciw1973
   KwikGUI (WIN/LIN/DOS) by Vincent DeCampo
   FB_GUI by BasicScience

Networking- Web Code
   FB Web Server (Win) by parakeet
   FB Server side scripting (uses the server above) by fishhf
   ChiSock portable sockets library by cha0s

I/O Code
   Text Input by Pritchard & sir_mud
   ConLib Console library with PCopy by cha0s
   Lock Mouse to Grid Positions by Pritchard

   Serial Port
   Drive a Parallax servo controller by phishguy
   Modbus device finder by Antoni
   Serial port terminal program by Antoni

OS Specific Code

   Windows
   ServiceFB (Win) by zerospeed
   FBWinPrint 1.0 by vdecampo
   In memory dialogs by MichaelW
   Talking program usin Win Voice API, by coder guy 
   Using GfxLib in Windows API by MichaelW 
   Print a bitmap file by MichaelW
   ShellExecute wrapper by RayBritton
   FBWiki to chm format converter by coderjeff
   FB ODBC library by KaraK
   Get a file from an URL by Sisophon

   Linux
   Printing on Linux by coderJeff
   Using GfxLib on Gtk by caseih

   DOS
   Detect system codepage by DrV
   Calling an Interrupt requiring a pointer by DrV
   Access BTRIEVE files by mjs
   "GetDiskFreeSpaceEx" Check for disk total/free space on FAT32 by DOS386
   DPMI host detection version/capabilities by DrV

Data structures and special-purpose UDTs
   Boolean Type by Imortis
   Safe FBstring Type by stylin
   FreeBASIC Memory Leak Detector by DrV & Others
   Auto-deallocating 'Smart' Pointers by stylin
   UDTs for Properties by Pritchard

Miscellaneous Code
   FreeBASIC Extended Library
   FB  CAD by owen
   FBstd C++ Lib Port (W.I.P.) by stylin
   Testly by zerospeed
   Portable way to add a resource to a program  by voodooattack
   CPU Identification by MichaelW
   Cpu Cycle counter for benchmarking of code by MichaelW
   Use of the FBGfx built-in LZW routines by Lillo
   Using FB dll's in RapidQ programs by JohnK

Community Websites/Links
   External Library Documentation
   Sourceforge
   FreeBASIC Games Directory

This is a place to post worthy projects/code snippets for FreeBASIC, in 
their relative categories.  To add a page, link to either its wiki page, 
website, or thread on the FreeBASIC Forums.  State the project name and who 
it's by.  Sections may be broken down into their own separate pages some 
time in the future.  Note:  Due to FB being in Beta stage of development, 
earlier coded projects may need to be reconfigured or recompiled to work on 
later versions of FreeBASIC.





============================================================================
  EXTERNAL LIBRARIES INDEX
  ------------------------



============================================================================
    Graphical/test-based user interfaces

------------------------------------------------------------ ExtLibcgui ----
CGUI

Library for making GUIs in a simple way.

Website: http://cgui.sourceforge.net/index.html, http://www.allegro.cc/resou
rce/Libraries/GUI/CGUI
Platforms supported: Win32, Linux
Headers to include: cgui.bi
Header version: 2.0.4
Example Usage: yes, in examples/GUI/CGUI/

   


---------------------------------------------------------- ExtLibcurses ----
Curses

Standardized console user interface library

Website: http://pdcurses.sourceforge.net/ and http://www.gnu.org/software/nc
urses/
Platforms supported: DOS, Win32, Linux
Headers to include: curses.bi
Header versions: pdcurses 3.4, ncurses 5.9
Note: On Win32 systems pdcurses is used, on Linux it uses the standard 
ncurses library.
Examples: yes, in examples/console/curses/

Example
   #include Once "curses.bi"

   initscr()
   cbreak()
   noecho()
   start_color()

   '' The default pair 0 will have the console's default colors

   '' Set pair 1 to be white/blue
   init_pair(1, COLOR_WHITE, COLOR_BLUE)

   '' Select pair 1, so from now on output will be white text on blue background
   attrset(COLOR_PAIR(1))

   printw(!"Hello, world!\n")

   '' Reset to pair 0
   attrset(COLOR_PAIR(0))

   '' Sleep
   printw(!"Waiting for keypress...\n")
   getch()

   endwin()

   


------------------------------------------------------------- ExtLibgtk ----
GTK+, The GIMP ToolKit

Cross-platform Graphical User Interface library

Website: http://www.gtk.org
Platforms supported: Win32, Linux
Headers to include: gtk/gtk.bi
Example Usage: yes, in examples/GUI/GTK+/
Header version: 2.24.27, 3.14.10

By default, gtk/gtk.bi will use the GTK+ 2 API.
Define __USE_GTK3__ before including gtk/gtk.bi to use GTK+ 3.

Example
   #include Once "gtk/gtk.bi"

   Dim Shared As GtkWidget Ptr win

   Private Sub on_clicked cdecl(ByVal button As GtkButton Ptr, ByVal userdata As gpointer)
      Static As Integer clickcount = 0
      clickcount += 1
      gtk_window_set_title(GTK_WINDOW(win), "clicked " & clickcount & " times")
   End Sub

   gtk_init(NULL, NULL)

   win = gtk_window_new(GTK_WINDOW_TOPLEVEL)
   gtk_window_set_title(GTK_WINDOW(win), "A small GTK+ example")
   gtk_window_set_default_size(GTK_WINDOW(win), 300, 200)
   gtk_container_set_border_width(GTK_CONTAINER(win), 20)

   g_signal_connect(G_OBJECT(win), "destroy", G_CALLBACK(@gtk_main_quit), NULL)

   Dim As GtkWidget Ptr button = gtk_button_new_with_label("Click me!")
   gtk_container_add(GTK_CONTAINER(win), button)

   g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(@on_clicked), NULL)

   gtk_widget_show_all(win)

   gtk_main()



------------------------------------------------------------- ExtLibIUP ----
IUP

Portable toolkit for building graphical user interfaces.

Website: http://www.tecgraf.puc-rio.br/iup/
Platforms supported: Win32, Linux
Headers to include: IUP/iup.bi
Header version: 3.13
Example Usage: yes, in examples/GUI/IUP/



------------------------------------------------------------- ExtLibwxc ----
wx-c, C Interface for WxWidgets

Cross-platform Graphical User Interface library

Website: http://wxnet.sourceforge.net/
Platforms supported: Win32, Linux
Headers to include: wx-c/wx.bi
Header version: 0.9.0.2
Example Usage: yes, in examples/GUI/wx-c/



--------------------------------------------------------- ExtLibwindows ----
Windows API

Standard API for all Windows Systems, used for example for creating Windows 
GUIs (forms and controls), socket programming, inter-process communication, 
and so much more.

Website: http://msdn.microsoft.com/en-us/library/ee663300.aspx
Platforms supported: Win32, Linux (using WINE)
Headers to include: windows.bi
Examples: yes, in examples/win32/



------------------------------------------------------------- ExtLibX11 ----
X11

The X Windowing System is widely used on Linux as the layer that 
coordinates drawing to the screen by providing windows. It also delivers 
events such as mouse and keyboard input from the kernel to applications. It 
is designed to run as a server that can be contacted through a specific 
protocol. The client's side of the protocol is implemented by libraries 
such as the old Xlib or the more modern XCB. Applications can use these to 
create windows and draw to them. However, typically most developers will 
choose to use a GUI library such as GTK+ (which has an X11 backend) 
instead.

Website: http://www.x.org/, http://xcb.freedesktop.org/
Platforms supported: Linux
Headers to include: X11/*.bi




============================================================================
    Graphics

--------------------------------------------------------- ExtLiballegro ----
Allegro

Game programming library

Website: http://alleg.sourceforge.net/index.html
Platforms supported: Win32, Linux, DOS
Headers to include: allegro.bi (Allegro 4) or allegro5/allegro.bi (Allegro 
5)
Header version: 4.4.2, 5.0.11
Example Usage: yes, in examples/graphics/Allegro/



------------------------------------------------------------ ExtLibDUGL ----
DUGL

Graphics and game programming library

Website: http://dugl.50webs.com
Platforms supported: DOS
Headers to include: DUGL.BI (not yet included with FB, see link below)
Example of usage: see link below
Note: use DUGL 1.13 or newer (see link below), older version have a bug and 
do crash when used with FB

See forum thread: http://www.freebasic.net/forum/viewtopic.php?t=11046

   


------------------------------------------------------------ ExtLibcaca ----
caca

A colour ASCII art library.

Website: http://libcaca.zoy.org/
Platforms supported: Win32, Linux, DOS
Headers to include: caca.bi (new API) or caca0.bi (old API)
Header version: libcaca-0.99.beta19
Example Usage: yes, in examples/console/caca/

   


----------------------------------------------------------- ExtLibcairo ----
Cairo

2D graphics library with support for multiple output devices. It can be 
used to draw on multiple different surfaces, such as the FB graphics 
window, in-memory pixel buffers, a GTK+ widget or a Win32 window or device 
context.

Website: http://www.cairographics.org
Platforms supported: Win32, Linux
Headers to include: cairo/cairo.bi
Header version: 1.14.2
Examples: yes, in examples/graphics/cairo/

Example
   '' Example showing cairo being used to draw into the FB graphics window
   #include Once "cairo/cairo.bi"

   Const SCREEN_W = 400
   Const SCREEN_H = 300

   ScreenRes SCREEN_W, SCREEN_H, 32

   '' Create a cairo drawing context, using the FB screen as surface.
   Var surface = cairo_image_surface_create_for_data(ScreenPtr(), CAIRO_FORMAT_ARGB32, SCREEN_W, SCREEN_H, SCREEN_W * SizeOf(ULong))

   Var c = cairo_create(surface)

   ScreenLock()

   '' Draw the entire context white.
   cairo_set_source_rgba(c, 1, 1, 1, 1)
   cairo_paint(c)

   '' Draw a red line
   cairo_set_line_width(c, 1)
   cairo_set_source_rgba(c, 1, 0, 0, 1)
   cairo_move_to(c, 0, 0)
   cairo_line_to(c, SCREEN_W - 1, SCREEN_H - 1)
   cairo_stroke(c)

   ScreenUnlock()

   Sleep

   '' Clean up the cairo context
   cairo_destroy(c)

 last reviewed: MrSwiss, 2018-05-05 -- changed: SizeOf(Integer) to SizeOf
(ULong) reason: 32/64 compatibility 

---------------------------------------------------------- ExtLibdislin ----
DisLin

Library of subroutines and functions that display data graphically.

Website: http://www.mps.mpg.de/dislin/
Platforms supported: Win32, Linux
Headers to include: dislin.bi
Header version: from 2005



-------------------------------------------------------- ExtLibfreeglut ----
Free alternative to the OpenGL Utility Toolkit

Just like GLUT, freeglut is a helper library that can be used to create Open
GL applications. It allows easy creation of windows with OpenGL drawing 
contexts and callback-based input event handling.

Website: http://freeglut.sourceforge.net/
Platforms supported: Win32, Linux
Headers to include: GL/freeglut.bi
Header version: 3.0.0



------------------------------------------------------- ExtLibfreeimage ----
FreeImage

FreeImage is an Open Source library project for developers who would like 
to support popular graphics image formats like PNG, BMP, JPEG, TIFF and 
others as needed by today's multimedia applications. FreeImage is easy to 
use, fast, multithreading safe, compatible with all 32-bit versions of 
Windows, and cross-platform (works both with Linux and Mac OS X).

Website: http://freeimage.sourceforge.net/
Platforms supported: Win32, Linux
Headers to include: FreeImage.bi
Header version: 3.15.1
Example included: yes, in examples/files/FreeImage

Example
Here follows an example of using FreeImage in FreeBASIC.  If using Windows 
you will require freeimage.dll which is available from the FreeImage site.

   '' Code example for loading all common image types using FreeImage.
   '' The example loads an image passed as a command line argument.

   '' The function FI_Load returns a null pointer (0) if there was an error during
   '' loading.  Otherwise it returns a 32-bit PUT compatible buffer.

   #include "FreeImage.bi"
   #include "crt.bi"
   #include "fbgfx.bi"

   Function FI_Load(filename As String) As Any Ptr
      If Len(filename) = 0 Then
         Return NULL
      End If

      '' Find out the image format
      Dim As FREE_IMAGE_FORMAT form = FreeImage_GetFileType(StrPtr(filename), 0)
      If form = FIF_UNKNOWN Then
         form = FreeImage_GetFIFFromFilename(StrPtr(filename))
      End If

      '' Exit if unknown
      If form = FIF_UNKNOWN Then
         Return NULL
      End If

      '' Always load jpegs accurately
      Dim As UInteger flags = 0
      If form = FIF_JPEG Then
         flags = JPEG_ACCURATE
      End If

      '' Load the image into memory
      Dim As FIBITMAP Ptr image = FreeImage_Load(form, StrPtr(filename), flags)
      If image = NULL Then
         '' FreeImage failed to read in the image
         Return NULL
      End If

      '' Flip the image so it matches FB's coordinate system
      FreeImage_FlipVertical(image)

      '' Convert to 32 bits per pixel
      Dim As FIBITMAP Ptr image32 = FreeImage_ConvertTo32Bits(image)

      '' Get the image's size
      Dim As UInteger w = FreeImage_GetWidth(image)
      Dim As UInteger h = FreeImage_GetHeight(image)

      '' Create an FB image of the same size
      Dim As fb.Image Ptr sprite = ImageCreate(w, h)

      Dim As Byte Ptr target = CPtr(Byte Ptr, sprite + 1)
      Dim As Integer target_pitch = sprite->pitch

      Dim As Any Ptr source = FreeImage_GetBits(image32)
      Dim As Integer source_pitch = FreeImage_GetPitch(image32)

      '' And copy over the pixels, row by row
      For y As Integer = 0 To (h - 1)
         memcpy(target + (y * target_pitch), _
               source + (y * source_pitch), _
               w * 4)
      Next

      FreeImage_Unload(image32)
      FreeImage_Unload(image)

      Return sprite
   End Function

   ScreenRes 640, 480, 32

   Dim As String filename = Command(1)

   Dim As Any Ptr image = FI_Load(filename)
   If image <> 0 Then
      Put (0, 0), image
      ImageDestroy(image)
   Else
      Print "Problem while loading file : " & filename
   End If

   Sleep



------------------------------------------------------- ExtLibfreetype2 ----
Freetype2

A Free, High-Quality, and Portable Font Engine

Website: http://www.freetype.org
Platforms supported: Win32, Linux
Headers to include: freetype2/freetype.bi
Header version: 2.5.5
Examples: yes, in examples/graphics/FreeType/

Example
   '' Example of rendering a char using freetype

   #include "freetype2/freetype.bi"

   #ifdef __FB_LINUX__
   Const TTF_FONT = "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf"
   #else
   Const TTF_FONT = "Vera.ttf"
   #endif

   Dim As FT_Library library
   If (FT_Init_FreeType(@library) <> 0) Then
      Print "FT_Init_FreeType() failed" : Sleep : End 1
   End If

   ''
   '' Load a font and render an '@' character on to a bitmap
   ''

   Dim As FT_Face face
   If (FT_New_Face(library, TTF_FONT, 0, @face) <> 0) Then
      Print "FT_New_Face() failed (font file '" & TTF_FONT & "' not found?)" : Sleep : End 1
   End If

   If (FT_Set_Pixel_Sizes(face, 0, 200) <> 0) Then
      Print "FT_Set_Pixel_Sizes() failed" : Sleep : End 1
   End If

   If (FT_Load_Char(face, Asc("@"), FT_LOAD_DEFAULT) <> 0) Then
      Print "FT_Load_Char() failed" : Sleep : End 1
   End If

   If (FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL) <> 0) Then
      Print "FT_Render_Glyph() failed" : Sleep : End 1
   End If

   ''
   '' Draw the rendered bitmap
   ''

   ScreenRes 320, 200, 32

   Dim As FT_Bitmap Ptr bitmap = @face->glyph->bitmap

   For y As Integer = 0 To (bitmap->rows - 1)
      For x As Integer = 0 To (bitmap->Width - 1)
         Dim As Integer col = bitmap->buffer[y * bitmap->pitch + x]
         PSet(x, y), RGB(col, col, col)
      Next
   Next

   Sleep



-------------------------------------------------------------- ExtLibgd ----
GD

Open source code library for the dynamic creation of images by programmers.

Website: http://www.libgd.org
Platforms supported: Win32, Linux
Headers to include: gd.bi
Header version: 2.1.0 development version
Examples: yes, in examples/files/GD/



---------------------------------------------------------- ExtLibgiflib ----
GIFLIB

GIFLIB is a package of portable tools and library routines for working with 
GIF images

Website: http://giflib.sourceforge.net/intro.html
Platforms supported: Win32, Linux, DOS
Headers to include: gif_lib.bi
Header version: 4.2.1, 5.0.4 (#define __GIFLIB_VER__ to 4 or 5 if needed; 
default = 5)
Examples: yes, in examples/files/GIFLIB/



------------------------------------------------------------ ExtLibGLUT ----
GLUT, the OpenGL Utility Toolkit

GLUT is a helper library that can be used to create OpenGL applications. It 
allows easy creation of a window with an OpenGL drawing context and also 
handles events such as mouse and keyboard input or timers. GLUT appears to 
be no longer maintained, however there is an active alternative: freeglut.

Website: http://www.opengl.org/resources/libraries/glut/
Platforms supported: Win32
Headers to include: GL/glut.bi
Header version: 3.7
Examples: in examples/graphics/OpenGL/



------------------------------------------------------------ ExtLibGLFW ----
GLFW, an OpenGL library

GLFW is a helper library that can be used to create OpenGL applications. It 
allows the creation of a window with an OpenGL drawing context and input 
handling while still allowing the program to have its own main loop.

Website: http://www.glfw.org/
Platforms supported: Win32, Linux
Headers to include: GL/glfw.bi, GLFW/glfw3.bi
Header version: 2.7.9, 3.1.1
Examples: in examples/graphics/OpenGL/



------------------------------------------------------------- ExtLibgrx ----
GRX

2D graphics library

Website: http://grx.gnu.de/
Platforms supported: Win32, Linux, DOS
Headers to include: grx/grx20.bi
Header version: 2.4.6
Examples: in examples/graphics/grx/



-------------------------------------------------------------- ExtLibIL ----
DevIL

A full featured cross-platform image library.

Website: http://openil.sourceforge.net/
Platforms supported: Win32, Linux
Headers to include: IL/il.bi, IL/ilu.bi, IL/ilut.bi
Header version: 1.7.8
Examples: in examples/files/DevIL/

Example
   '' DevIL example

   #include Once "IL/il.bi"

   '' Version check
   If (ilGetInteger(IL_VERSION_NUM) < IL_VERSION) Then
      Print "DevIL version is different"
      End 1
   End If

   '' Good practice to explicitely initialize it
   ilInit()

   '' Load a bitmap
   Dim As ILuint fblogo
   ilGenImages(1, @fblogo)
   ilBindImage(fblogo)

   Print "Loading fblogo.bmp..."
   ilLoadImage("fblogo.bmp")

   '' Save a copy
   Print "Saving a copy, fblogo-copy.bmp..."
   ilEnable(IL_FILE_OVERWRITE)
   ilSaveImage("fblogo-copy.bmp")

   '' Clean up
   ilDeleteImages(1, @fblogo)



------------------------------------------------------------ ExtLibjapi ----
Java Application Programming Interface

Open source free software GUI toolkit using Java's AWT Toolkit

Website: http://www.japi.de/
Platforms supported: Win32, Linux
Headers to include: japi.bi
Header version: from 2005



--------------------------------------------------------- ExtLibjpeglib ----
jpeglib

Cross-platform library for reading/writing jpeg images

Website: http://ijg.org/
Platforms supported: Win32, Linux, DOS
Headers to include: jpeglib.bi
Header version: 6.2, 7.0, 8.4, 9.0 (#define __JPEGLIB_VER__ to one of 
6,7,8,9 if needed; default = 9)
Example Usage: yes, in examples/files/jpeglib



-------------------------------------------------------- ExtLibjpgalleg ----
JPGAlleg

JPGalleg is a small addon for Allegro that adds JPG images handling 
capabilities to the library

Website: http://www.ecplusplus.com/index.php?page=projects&pid=1
Platforms supported: Win32, Linux
Headers to include: jpgalleg.bi
Header version: 2.5



---------------------------------------------------------- ExtLiblibpng ----
libPNG

Allows reading and writing PNG images.

Website: http://www.libpng.org/pub/png/libpng.html
Platforms supported: Win32, Linux, DOS
Headers to include: png.bi
Header versions: 1.2.53, 1.4.16, 1.5.21, 1.6.16
Examples: in examples/files/libpng/

When #including png.bi, you can #define __LIBPNG_VERSION to one of 12, 14, 1
5, 16 in order to select the desired libpng version. The default is the 
latest version.

Overriding the default allows you to match the exact libpng version on your 
system (interesting for Linux distros which, for example, use the libpng 
1.2 series instead of the latest version).



---------------------------------------------------------- ExtLibOpenGL ----
OpenGL, The Open Graphics Language

OpenGL is a standardized and widely used cross-platform 3D graphics 
library.

Usually OpenGL support comes as part of the system and the graphics 
drivers. There are many different projects providing a library that 
implements the main OpenGL API, and which one is used depends on the 
platform and system setup. For example, on Windows, the client API is 
implemented in Microsoft's opengl32.dll, while on Linux, there is for 
example the free Mesa3D project, which provides a libGL implementation. It 
depends on the used library or system setup which way the OpenGL API does 
its rendering, typically it uses OpenGL hardware drivers and is 
hardware-accelerated, but there also is software-rendered OpenGL (e.g. 
standalone Mesa3D). The system's graphics hardware drivers may provide 
additional OpenGL extensions, access to which is again system dependant.

Besides plain OpenGL, there are several utility, helper and wrapper 
libraries, such as GLUT, freeglut and GLFW, and even FreeBASIC's built-in 
graphics library has an OpenGL mode, see Screen And Fb.Gfx_Opengl.

Websites:
OpenGL standard: http://www.opengl.org
Mesa3D: http://mesa3d.org/
Windows OpenGL: http://msdn.microsoft.com/en-us/library/dd374278.aspx

Platforms supported: Win32, Linux
Headers to include: GL/gl.bi
Header version: Mesa-3D 10.5.1, MinGW-w64 3.3.0
Examples: yes, in examples/graphics/OpenGL/



---------------------------------------------------------- ExtLibpdflib ----
PDFlib

Portable library for dynamically generating PDF documents

Website: http://www.pdflib.com
Platforms supported: Win32, Linux
Headers to include: pdflib.bi
Header version: 4.0.2
Examples: in examples/files/pdflib/



------------------------------------------------------------- ExtLibSDL ----
SDL, the Simple DirectMedia Layer

Cross-platform mulitmedia library

Website: http://www.libsdl.org
Platforms supported: Win32, Linux
Headers to include: SDL/SDL.bi or SDL2/SDL.bi
Header version: SDL 1.2.15, SDL2 2.0.3
Examples: yes, in examples/graphics/SDL/



--------------------------------------------------------- ExtLibtinyptc ----
TinyPTC

A small and easy to use framebuffer graphics library.

Website: http://sourceforge.net/projects/tinyptc/
Platforms supported: Win32, Linux, DOS
Headers to include: tinyptc.bi
Examples: in examples/graphics/tinyptc/




============================================================================
    Music/Sound, Audio/Video

------------------------------------------------------------ ExtLibbass ----
BASS

Audio library for use in Windows with a Beta Version for Linux.

Website: http://www.un4seen.com/bass.html
Platforms supported: Win32, Linux (beta)
Headers to include: bass.bi
Header version: 2.4.8
Examples: in examples/sound/BASS/

Example
   #include Once "bass.bi"

   Const SOUND_FILE = "test.mod"

   If (BASS_GetVersion() < MAKELONG(2,2)) Then
      Print "BASS version 2.2 or above required!"
      End 1
   End If

   If (BASS_Init(-1, 44100, 0, 0, 0) = 0) Then
      Print "Could not initialize BASS"
      End 1
   End If

   Dim As HMUSIC test = BASS_MusicLoad(False, @SOUND_FILE, 0, 0, BASS_MUSIC_LOOP, 0)
   If (test = 0) Then
      Print "BASS could not load '" & SOUND_FILE & "'"
      BASS_Free()
      End 1
   End If

   BASS_ChannelPlay(test, False)

   Print "Sound playing; waiting to keypress to stop and exit..."
   Sleep

   BASS_ChannelStop(test)
   BASS_MusicFree(test)
   BASS_Stop()
   BASS_Free()



--------------------------------------------------------- ExtLibbassmod ----
BASSMOD

BASSMOD is a MOD only (XM, IT, S3M, MOD, MTM, UMX) version of BASS - useful 
for demos, or anything else where you want to play some MOD music.

Website: http://www.un4seen.com/bassmod.html
Platforms supported: Win32, Linux
Headers to include: bassmod.bi
Header version: 2.0
Examples: in examples/sound/BASS/

Example
   #include Once "bassmod.bi"

   Const SOUND_FILE = "test.mod"

   If (BASSMOD_GetVersion() < 2) Then
      Print "BASSMOD version 2 or above required!"
      End 1
   End If

   If (BASSMOD_Init(-1, 44100, 0) = 0) Then
      Print "Could not initialize BASSMOD"
      End 1
   End If

   If (BASSMOD_MusicLoad(False, SOUND_FILE, 0, 0, BASS_MUSIC_LOOP) = 0) Then
      Print "BASSMOD could not load '" & SOUND_FILE & "'"
      BASSMOD_Free()
      End 1
   End If

   BASSMOD_MusicPlay()

   Print "Sound playing; waiting for keypress to stop and exit..."
   Sleep

   BASSMOD_MusicStop()
   BASSMOD_MusicFree()
   BASSMOD_Free()



----------------------------------------------------------- ExtLibFlite ----
Flite

Flite is a run-time speech synthesis engine.

Website: http://www.speech.cs.cmu.edu/flite/
Platforms supported: Win32, Linux
Headers to include: flite/flite.bi
Header version: 1.4, machine-translated only



------------------------------------------------------------ ExtLibfmod ----
FMOD

Audio library supporting just about any format.

Website: http://www.fmod.org/index.php/products#FMOD3ProgrammersAPI
Platforms supported: Win32, Linux
Headers to include: fmod.bi
Header version: 3.75
Examples: in examples/sound/FMOD/

Example
   #include Once "fmod.bi"

   Const SOUND_FILE = "test.mod"

   If (FSOUND_GetVersion() < FMOD_VERSION) Then
      Print "FMOD version mismatch"
      End 1
   End If

   If (FSOUND_Init(44100, 32, 0) = 0) Then
      Print "Could not initialize FMOD"
      End 1
   End If

   Dim As FMUSIC_MODULE Ptr song = FMUSIC_LoadSong(SOUND_FILE)
   If (song = 0) Then
      Print "FMOD could not load '" & SOUND_FILE & "'"
      FSOUND_Close()
      End 1
   End If

   FMUSIC_PlaySong(song)

   Print "Sound playing; waiting for keypress to stop and exit..."
   Sleep

   FMUSIC_FreeSong(song)
   FSOUND_Close()

   '' mp3 player based on FMOD

   #include Once "fmod.bi"

   Const SOUND_FILE = "test.mp3"

   Sub print_all_tags(ByVal stream As FSOUND_STREAM Ptr)
      Dim As Integer count = 0
      FSOUND_Stream_GetNumTagFields(stream, @count)

      For i As Integer = 0 To (count - 1)
         Dim As Integer tagtype, taglen
         Dim As ZString Ptr tagname, tagvalue
         FSOUND_Stream_GetTagField(stream, i, @tagtype, @tagname, @tagvalue, @taglen)
         Print Left(*tagname, taglen)
      Next
   End Sub

   Function get_tag _
      ( _
         ByVal stream As FSOUND_STREAM Ptr, _
         ByVal tagv1 As ZString Ptr, _
         ByVal tagv2 As ZString Ptr _
      ) As String

      Dim tagname As ZString Ptr, taglen As Integer

      FSOUND_Stream_FindTagField(stream, FSOUND_TAGFIELD_ID3V1, tagv1, @tagname, @taglen)
      If (taglen = 0) Then 
         FSOUND_Stream_FindTagField(stream, FSOUND_TAGFIELD_ID3V2, tagv2, @tagname, @taglen)
      End If

      Return Left(*tagname, taglen)
   End Function

      If (FSOUND_GetVersion < FMOD_VERSION) Then
         Print "FMOD version " + Str(FMOD_VERSION) + " or greater required!"
         End 1
      End If 

      If (FSOUND_Init(44100, 4, 0) = 0) Then
         Print "Could not initialize FMOD"
         End 1
      End If

      FSOUND_Stream_SetBufferSize(50)

      Dim As FSOUND_STREAM Ptr stream = FSOUND_Stream_Open(SOUND_FILE, FSOUND_MPEGACCURATE, 0, 0)
      If (stream = 0) Then 
         Print "FMOD could not load '" & SOUND_FILE & "'"
         FSOUND_Close()
         End 1
      End If

      '' Read out mp3 tags to show some meta information
      Print "Title:", get_tag(stream, "TITLE", "TIT2")
      Print "Album:", get_tag(stream, "ALBUM", "TALB")
      Print "Artist:", get_tag(stream, "ARTIST", "TPE1")
      ''print_all_tags(stream)

      Print "Playing mp3, press a key to exit..."
      FSOUND_Stream_Play(FSOUND_FREE, stream)

      While (Inkey() = "")
         If (FSOUND_Stream_GetPosition(stream) >= FSOUND_Stream_GetLength(stream)) Then
            Exit While
         End If
         Sleep 50, 1
      Wend
      
      FSOUND_Stream_Stop(stream)
      FSOUND_Stream_Close(stream)
      FSOUND_Close()



------------------------------------------------------- ExtLibMediaInfo ----
MediaInfo

MediaInfo is a cross-platform library allowing you to read out technical 
and tag information from audio and video files in various formats.

Website: http://mediainfo.sourceforge.net/
Platforms supported: Win32, Linux
Headers to include: MediaInfo.bi
Header version: from October 2011



---------------------------------------------------------- ExtLibmpg123 ----
mpg123

libmpg123 is the decoder library used by the mpg123 MPEG player.

Website: http://mpg123.org/
Platforms supported: Win32, Linux
Headers to include: mpg123.bi
Header version: from 2010, machine-translated only



------------------------------------------------------------- ExtLibogg ----
libogg

Ogg multimedia container format creation/decoder library

Website: http://www.xiph.org/ogg/
Platforms supported: Win32, Linux
Headers to include: ogg/ogg.bi
Header version: from 2007



-------------------------------------------------------------- ExtLibal ----
OpenAL

OpenAL is a cross-platform 3D audio API appropriate for use with gaming 
applications and many other types of audio applications. ALUT is the OpenAL 
utility toolkit, a library providing additional functions to work with OpenA
L.

Website: http://www.openal.org
Platforms supported: Win32, Linux
Headers to include: AL/al.bi, AL/alut.bi
Header version: openal-soft-1.16.0, freealut 1.1.0
Examples: in examples/sound/OpenAL/



------------------------------------------------------- ExtLibPortAudio ----
PortAudio

PortAudio is a cross-platform audio I/O library that allows programs to 
access the system's audio devices to record or play sounds.

Website: http://www.portaudio.com/
Platforms supported: Win32, Linux
Headers to include: portaudio.bi
Header version: from 2010, machine-translated only



--------------------------------------------------------- ExtLibsndfile ----
libsndfile

libsndfile is a library allowing programs to access or modify audio files 
in various formats, for example .wav files, and also convert between them.

Website: http://www.mega-nerd.com/libsndfile/
Platforms supported: Win32, Linux
Headers to include: sndfile.bi
Header version: 1.0.X



------------------------------------------------------------- ExtLibVLC ----
libVLC

Audio/video playback library from the VLC media player.

Website: http://www.videolan.org/, http://wiki.videolan.org/Libvlc
Platforms supported: Win32, Linux
Headers to include: vlc/*.bi
Header version: 1.1.x



---------------------------------------------------------- ExtLibvorbis ----
libvorbis

Ogg Vorbis audio compression library

Website: http://xiph.org/vorbis/
Platforms supported: Win32, Linux
Headers to include: vorbis/vorbisenc.bi, vorbis/vorbisfile.bi
Header version: from 2007




============================================================================
    Database

------------------------------------------------------------ ExtLibGDBM ----
GDBM, the GNU Database manager

Provides database functions using extensible hashing, primarily for storing 
key/data pairs to data files

Website: http://www.gnu.org.ua/software/gdbm/
Platforms supported: Win32, Linux
Headers to include: gdbm.bi
Header version: from 2010



----------------------------------------------------------- ExtLibmysql ----
MySQL

High-Quality, widely used database engine.

Website: http://www.mysql.org
Platforms supported: Win32, Linux
Headers to include: mysql/mysql.bi
Header version: 4.0.17
Examples: in examples/database/



------------------------------------------------------ ExtLibpostgresql ----
PostgreSQL

Free software object-relational database management system 

Website: http://www.postgresql.org/
Platforms supported: Win32, Linux
Headers to include: postgresql/postgres_ext.bi
Header version: from 2006
Example Usage: yes, in examples/database/

   


---------------------------------------------------------- ExtLibsqlite ----
SQLite

Small C library that implements a self-contained, embeddable, 
zero-configuration SQL database engine.

Website: http://sqlite.org
Platforms supported: Win32, Linux, DOS
Headers to include: sqlite2.bi or sqlite3.bi
Header versions: 2.8.17, 3.7.8
Examples: in examples/database/




============================================================================
    Development Helpers

----------------------------------------------------------- ExtLibCUnit ----
CUnit

Lightweight system for writing, administering, and running unit tests in C.

Website: http://cunit.sourceforge.net/
Platforms supported: Win32, Linux, DOS
Headers to include: CUnit/CUnit.bi
Header version: 2.1-3
Examples: in examples/misc/CUnit/



------------------------------------------------------------ ExtLibgdsl ----
GDSL, The Generic Data Structures Library

The Generic Data Structures Library is a collection of routines for generic 
data structures.

Website: http://home.gna.org/gdsl/
Platforms supported: Win32, Linux, DOS
Headers to include: gdsl/gdsl.bi
Header version: from 2005
Examples: in examples/misc/gdsl/



--------------------------------------------------------- ExtLibgettext ----
gettext

An internationalization library/toolchain

Website: http://www.gnu.org/software/gettext/gettext.html
Platforms supported: Win32, Linux, DOS
Headers to include: libintl.bi, gettext-po.bi
Header version: from 2010, 0.17



---------------------------------------------------------- ExtLibaspell ----
GNU Aspell

Free and Open Source spell checker.

Website: http://aspell.net/
Platforms supported: Win32, Linux
Headers to include: aspell.bi
Header version: 0.60.6.1

Example
   '' GNU-ASspell example, converted from http://aspell.net/win32/

   #include Once "aspell.bi"

   Dim As AspellConfig Ptr spell_config = new_aspell_config()

   '' Change this to suit the installed dictionary language if desired
   aspell_config_replace(spell_config, "lang", "en_CA")

   '' Create speller object
   Dim As AspellCanHaveError Ptr possible_err = new_aspell_speller(spell_config)
   If (aspell_error_number(possible_err) <> 0) Then
      Print *aspell_error_message(possible_err)
      End 1
   End If
   Dim As AspellSpeller Ptr speller = to_aspell_speller(possible_err)

   Dim As String word
   Do
      Print 
      Input "Enter a word (blank to quit): ", word
      If (Len(word) = 0) Then
         Exit Do
      End If

      If (aspell_speller_check(speller, StrPtr(word), Len(word)) <> 0) Then
         Print "Word is Correct"
      Else
         Print "Suggestions:"
         Dim As AspellStringEnumeration Ptr elements = _
            aspell_word_list_elements(aspell_speller_suggest(speller, StrPtr(word), Len(word)))
         Do
            Dim As Const ZString Ptr w = aspell_string_enumeration_next(elements)
            If (w = 0) Then
               Exit Do
            End If
            Print "   "; *w
         Loop
         delete_aspell_string_enumeration(elements)
      End If

      ' - Report the replacement
      'aspell_speller_store_repl(speller, misspelled_word, size,
      '                          correctly_spelled_word, size);

      ' - Add to session or personal dictionary
      'aspell_speller_add_to_session|personal(speller, word, size)
   Loop

   delete_aspell_speller(speller)



------------------------------------------------------------- ExtLibbfd ----
BFD, the Binary File Descriptor Library

Provides an API to read and write object files in many different object 
file formats. libbfd is the core of the GNU binutils.

Website: http://sourceware.org/binutils/
Platforms supported: Win32, Linux, DOS
Headers to include: bfd.bi
Header version: binutils versions from 2.16 to 2.25

Define __BFD_VER__ to 216, 217, 218, ..., 225 to include the bfd header for 
the corresponding binutils version.

Example
   #define __BFD_VER__ 217
   #include "bfd.bi"




============================================================================
    Embeddable Languages

------------------------------------------------------------- ExtLibjni ----
JNI, The Java Native Interface

Standard programming interface for writing Java native methods and 
embedding the Java virtual machine into native applications.

Website: http://download.oracle.com/javase/6/docs/technotes/guides/jni/index.html, http://java.sun.com/docs/books/jni/
Platforms supported: Win32, Linux
Headers to include: jni.bi
Header version: from 2006
Examples: in examples/other-languages/Java/

Example

   Three files:

   * mylib.bas - A DLL writting in FreeBASIC

   #include "jni.bi"
      
   '' Note: The mangling must be "windows-ms" or the JRE won't find any function
   Extern "windows-ms"
      Function Java_MyLib_add( env As JNIEnv Ptr, obj As jobject, l As jint, r As jint ) As jint Export
         Return l + r
      End Function
   End Extern

   * Mylib.java - The Java class that represents the interface to the 
     FreeBASIC code and ensures the FreeBASIC DLL is loaded

   (cpp)
   Class MyLib {
   	Public native Int Add( Int l, Int r );
   	Static {
   		System.loadLibrary( "mylib" );
   	}
   }

   * Test.java - The Java main() that uses the Mylib class

   (cpp)
   Class Test {
   	Public Static void main(String[] args) {
   		MyLib Lib = New MyLib();
   		System.out.println( "2+2=" + lib.add( 2, 2 ) ); 
   	}
   }

   Steps to test it:

   * Compile the FreeBASIC DLL: fbc mylib.bas -dll
   * Compile the two Java classes: javac Mylib.java Test.java
   * Run the Test class: java Test



----------------------------------------------------------- ExtLibjsonc ----
json-c

A JSON implementation in C

Website: http://oss.metaparadigm.com/json-c/
Platforms supported: Win32, Linux
Headers to include: json-c/json.bi
Header version: 0.9 (not sure)



------------------------------------------------------------- ExtLibFfi ----
libffi

LibFFI is a foreign function interface library allowing programs to 
arbitrarily call native function without pointers and to bind function 
pointers to generic functions which take variable arguments via closures. 
It is used to bind native code in modern scripting languages.

Website: http://sourceware.org/libffi/
Platforms supported: Windows, Linux, DOS
Headers to include: ffi.bi
Header version: 3.1

Example
   Hello world:
   #include "ffi.bi"

   ' Simple "puts" equivalent function
   Function printer cdecl (ByVal s As ZString Ptr) As Integer
      Print *s
      Return 42
   End Function

   ' Initialize the argument info vectors
   Dim s As ZString Ptr
   Dim args(0 To 0) As ffi_type Ptr = {@ffi_type_pointer}
   Dim values(0 To 0) As Any Ptr = {@s}

   ' Initialize the cif
   Dim cif As ffi_cif
   Dim result As ffi_status
   result = ffi_prep_cif( _
      @cif,              _ ' call interface object
      FFI_DEFAULT_ABI,   _ ' binary interface type
      1,                 _ ' number of arguments
      @ffi_type_uint,    _ ' return type
      @args(0)           _ ' arguments
   )

   ' Call function
   Dim return_value As Integer
   If result = FFI_OK Then
      s = @"Hello world"
      ffi_call(@cif, FFI_FN(@printer), @return_value, @values(0))

      ' values holds a pointer to the function's arg, so to
      ' call puts() again all we need to do is change the
      ' value of s */
      s = @"This is cool!"
      ffi_call(@cif, FFI_FN(@printer), @return_value, @values(0))
      Print Using "Function returned &"; return_value
   End If

   Closures:
   #include "ffi.bi"

   ' Acts like puts with the file given at time of enclosure. 
   Sub Printer cdecl(ByVal cif As ffi_cif Ptr, ByVal ret As Any Ptr, ByVal args As Any Ptr Ptr, ByVal File As Any Ptr)
      Write #*CPtr(Integer Ptr, file), **CPtr(ZString Ptr Ptr, args[0])
      *CPtr(UInteger Ptr, ret) = 42
   End Sub

   ' Allocate the closure and function binding
   Dim PrinterBinding As Function(ByVal s As ZString Ptr) As Integer
   Dim closure As ffi_closure Ptr 
   closure = ffi_closure_alloc(SizeOf(ffi_closure), @PrinterBinding)

   If closure <> 0 Then
      ' Initialize the argument info vector
      Dim args(0 To 0) As ffi_type Ptr = {@ffi_type_pointer}
      
      ' Initialize the call interface
      Dim cif As ffi_cif
      Dim prep_result As ffi_status = ffi_prep_cif( _
         @cif,            _ ' call interface object
         FFI_DEFAULT_ABI, _ ' binary interface type
         1,               _ ' number of arguments
         @ffi_type_uint,  _ ' return type
         @args(0)         _ ' arguments
      ) 
      If prep_result = FFI_OK Then
         ' Open console file to send to PrinterBinding as user data
         Dim ConsoleFile As Integer = FreeFile()
         Open Cons For Output As ConsoleFile
         
         ' Initialize the closure, setting user data to the console file
         prep_result = ffi_prep_closure_loc( _
            closure,         _ ' closure object
            @cif,            _ ' call interface object
            @Printer,        _ ' actual closure function
            @ConsoleFile,    _ ' user data, our console file #
            PrinterBinding   _ ' pointer to binding
         )
         If prep_result = FFI_OK Then
            ' Call binding as a natural function call
            Dim Result As Integer
            Result = PrinterBinding("Hello World!")
            Print Using "Returned &"; Result
         End If
         
         Close ConsoleFile
      End If
   End If

   ' Clean up
   ffi_closure_free(closure)



------------------------------------------------------------- ExtLibJit ----
libjit

LibJIT is a fairly straightforward, lightweight library for runtime 
compilation with a simple and stable ABI.

Website: http://www.gnu.org/software/libjit/
Platforms supported: Windows, Linux, DOS
Headers to include: jit.bi
Header version: git a8293e141b79c28734a3633a81a43f92f29fc2d7

Example
   '' Simple mul/add example

   #include "jit.bi"

   ' initialize libjit
   Dim context As jit_context_t = jit_context_create()
   jit_context_build_start(context)

   ' define function mul_add(x, y, z)
   Dim params(0 To 2) As jit_type_t = {jit_type_int, jit_type_int, jit_type_int}
   Dim signature As jit_type_t = jit_type_create_signature( _  
      jit_abi_cdecl,  _ ' C-style function
      jit_type_int,   _ ' Return type
      @params(0),     _ ' Parameter array
      3,              _ ' Number of components
      1               _ ' Count references?
   )
   Dim mul_add As jit_function_t = jit_function_create(context, signature)

   ' build function (result = (x*y)+z)
   Dim As jit_value_t x, y, z, temp1, temp2
   x = jit_value_get_param(mul_add, 0)
   y = jit_value_get_param(mul_add, 1)
   temp1 = jit_insn_mul(mul_add, x, y)
   z = jit_value_get_param(mul_add, 2)
   temp2 = jit_insn_add(mul_add, temp1, z)
   jit_insn_return(mul_add, temp2)

   ' compile function function
   jit_function_compile(mul_add)
   jit_context_build_end(context)

   ' call function
   Dim As Integer a=3, b=5, c=2, result
   Dim args(0 To 2) As Integer Ptr = {@a, @b, @c}
   jit_function_apply(mul_add, @args(0), @result)
   Print Using "mul__add(&, &, &) = &"; a; b; c; result

   ' clean up libjit
   jit_context_destroy(context)

   '' GCD calculation example

   #include "jit.bi"

   ' initialize libjit
   Dim context As jit_context_t = jit_context_create()
   jit_context_build_start(context)

   ' define function gcd(x as uinteger, y as uinteger) as uinteger
   Dim params(0 To 1) As jit_type_t = {jit_type_uint, jit_type_uint}
   Dim signature As jit_type_t = jit_type_create_signature( _  
      jit_abi_cdecl,  _ ' C-style function
      jit_type_uint,  _ ' Return type
      @params(0),     _ ' Parameter array
      2,              _ ' Number of components
      1               _ ' Count references?
   )
   Dim gcd As jit_function_t = jit_function_create(context, signature)

   ' build function
   ' check x = y
   Dim As jit_value_t x, y, x_eq_y
   x = jit_value_get_param(gcd, 0)
   y = jit_value_get_param(gcd, 1)
   x_eq_y = jit_insn_eq(gcd, x, y)

   ' if x = y, return x
   Dim label_x_ne_y As jit_label_t = jit_label_undefined
   jit_insn_branch_if_not(gcd, x_eq_y, @label_x_ne_y)
   jit_insn_return(gcd, x)

   ' else if...
   jit_insn_label(gcd, @label_x_ne_y)

   ' check x < y
   Dim As jit_value_t x_lt_y
   Dim label_x_gte_y As jit_label_t = jit_label_undefined
   x_lt_y = jit_insn_lt(gcd, x, y)
   jit_insn_branch_if_not(gcd, x_lt_y, @label_x_gte_y)

   ' if x < y, return gcd(x, y-x)
   Dim As jit_value_t gcd_args(0 To 2), gcd_result
   gcd_args(0) = x
   gcd_args(1) = jit_insn_sub(gcd, y, x)
   gcd_result = jit_insn_call( _
      gcd,          _ ' where we are calling from
      "gcd",        _ ' function name
      gcd,          _ ' function reference
      0,            _ ' signature = auto
      @gcd_args(0), _ ' arguments
      2,            _ ' argument count
      0             _ ' flags = nothing special
   )
   jit_insn_return(gcd, gcd_result)

   ' else...
   jit_insn_label(gcd, @label_x_gte_y)

   ' return gcd(x-y, y)
   gcd_args(0) = jit_insn_sub(gcd, x, y)
   gcd_args(1) = y
   gcd_result = jit_insn_call( _
      gcd,          _ ' where we are calling from
      "gcd",        _ ' function name
      gcd,          _ ' function reference
      0,            _ ' signature = auto
      @gcd_args(0), _ ' arguments
      2,            _ ' argument count
      0             _ ' flags = nothing special
   )
   jit_insn_return(gcd, gcd_result)

   ' compile function
   jit_function_compile(gcd)
   jit_context_build_end(context)

   ' call function
   Dim As jit_uint a=21, b=14, result
   Dim As jit_uint Ptr args(0 To 1) = {@a, @b}
   jit_function_apply(gcd, @args(0), @result)
   Print Using "gcd(&, &) = &"; a; b; result

   ' clean up libjit
   jit_context_destroy(context)



------------------------------------------------------------- ExtLibLua ----
Lua

Lightweight, embeddable scripting engine using the Lua language.

Website: http://www.lua.org/
Platforms supported: Win32, Linux, DOS
Headers to include: Lua/lua.bi
Header version: 5.2.3
Examples: in examples/other-languages/Lua/



---------------------------------------------------- ExtLibspidermonkey ----
SpiderMonkey

Embeddable javascript engine.

Website: http://www.mozilla.org/js/spidermonkey/
Platforms supported: Win32, Linux
Headers to include: spidermonkey/jsapi.bi
Header version: from 2006

Example
   '' Evaluating javascript code
   #include Once "spidermonkey/jsapi.bi"

   Dim Shared As JSClass global_class = _
   ( _
      @"global", 0, _
      @JS_PropertyStub, @JS_PropertyStub, @JS_PropertyStub, @JS_PropertyStub, _
      @JS_EnumerateStub, @JS_ResolveStub, @JS_ConvertStub, @JS_FinalizeStub _
   )

   Dim As JSRuntime Ptr rt = JS_NewRuntime(1048576 /'memory limit'/)
   Dim As JSContext Ptr cx = JS_NewContext(rt, 4096 /'stack size'/)
   Dim As JSObject Ptr global = JS_NewObject(cx, @global_class, NULL, NULL) 

   JS_InitStandardClasses(cx, global)

   '' This string could also be read in from a file or as part of HTTP data etc.
   Const TEST_SCRIPT = _
      !"function fact(n)           \n" + _
      !"{                          \n" + _
      !"    if (n <= 1)            \n" + _
      !"        return 1;          \n" + _
      !"                           \n" + _
      !"    return n * fact(n - 1);\n" + _
      !"}                          \n" + _
      !"                           \n" + _
      !"    fact(5)                \n"

   Dim As jsval rval
   If (JS_EvaluateScript(cx, global, TEST_SCRIPT, Len(TEST_SCRIPT), "localhost", 1, @rval) = 0) Then
      Print "JS_EvaluateScript failed"
      Sleep
      End 1
   End If

   Print "result: " & *JS_GetStringBytes(JS_ValueToString(cx, rval))

   JS_DestroyContext(cx)
   JS_DestroyRuntime(rt)

   '' Callback example: Functions that are used by the Javascript code,
   '' but are implemented in FB.
   #include Once "spidermonkey/jsapi.bi"

   Dim Shared As JSClass global_class = _
   ( _
      @"global", 0, _
      @JS_PropertyStub, @JS_PropertyStub, @JS_PropertyStub, @JS_PropertyStub, _
      @JS_EnumerateStub, @JS_ResolveStub, @JS_ConvertStub, @JS_FinalizeStub _
   )

   Private Function print_callback cdecl _
      ( _
         ByVal cx As JSContext Ptr, _
         ByVal obj As JSObject Ptr, _
         ByVal argc As uintN, _
         ByVal argv As jsval Ptr, _
         ByVal rval As jsval Ptr _
      ) As JSBool

      If (argc < 1) Then
         Return 0
      End If

      Print *JS_GetStringBytes(JS_ValueToString(cx, argv[0]))

      Return 1
   End Function

   Private Function ucase_callback cdecl _
      ( _
         ByVal cx As JSContext Ptr, _
         ByVal obj As JSObject Ptr, _
         ByVal argc As uintN, _
         ByVal argv As jsval Ptr, _
         ByVal rval As jsval Ptr _
      ) As JSBool
      
      If (argc < 1) Then
         Return 0
      End If
      
      '' Get the first argument
      Dim As ZString Ptr arg1 = JS_GetStringBytes(JS_ValueToString(cx, argv[0]))
      
      '' Get a buffer for the result string
      Dim As ZString Ptr result = JS_malloc(cx, Len(*arg1) + 1)

      '' Do the work
      *result = UCase(*arg1)

      '' Return it in rval
      *rval = STRING_TO_JSVAL(JS_NewString(cx, result, Len(*result)))

      Return 1
   End Function

      Dim As JSRuntime Ptr rt = JS_NewRuntime(1048576 /'memory limit'/)
      Dim As JSContext Ptr cx = JS_NewContext(rt, 4096 /'stack size'/)
      Dim As JSObject Ptr global = JS_NewObject(cx, @global_class, NULL, NULL) 

      JS_InitStandardClasses(cx, global)

      JS_DefineFunction(cx, global, "print", @print_callback, 1, 0) 
      JS_DefineFunction(cx, global, "ucase", @ucase_callback, 1, 0) 

      Const TEST_SCRIPT = "print(ucase('hello'));" 

      Dim As jsval rval
      If (JS_EvaluateScript(cx, global, TEST_SCRIPT, Len(TEST_SCRIPT), "localhost", 1, @rval) = 0) Then
         Print "JS_EvaluateScript failed"
         Sleep
         End 1
      End If

      JS_DestroyContext(cx)
      JS_DestroyRuntime(rt)




============================================================================
    Cryptography

-------------------------------------------------------- ExtLibcryptlib ----
cryptlib

A powerful security toolkit which allows even inexperienced crypto 
programmers to easily add encryption and authentication services to their 
software.

Website: http://www.cs.auckland.ac.nz/~pgut001/cryptlib/
Platforms supported: Win32, Linux
Headers to include: cryptlib.bi
Header version: from 2005
Examples: in examples/math/cryptlib/

Example
   #include Once "cryptlib.bi"

   Function calc_hash( ByVal filename As String, ByVal algo As CRYPT_ALGO_TYPE ) As String
      Const BUFFER_SIZE = 8192
      Dim As Byte buffer( 0 To BUFFER_SIZE-1 )

      '' create a new context using the wanted algorithm
      Dim As CRYPT_CONTEXT ctx
      cryptCreateContext( @ctx, CRYPT_UNUSED, algo )

      '' open input file in binary mode
      Dim As Integer f = FreeFile()
      If( Open( filename For Binary Access Read As #f ) <> 0 ) Then
         Return ""
      End If

      '' read until end-of-file
      Do Until( EOF( f ) )
         Dim As Integer oldpos = Seek( f )
         Get #f, , buffer()
         Dim As Integer readlength = Seek( f ) - oldpos
         '' encrypt
         cryptEncrypt( ctx, @buffer(0), readlength )
      Loop

      '' close input file
      Close #f

      '' finalize
      cryptEncrypt( ctx, 0, 0 )

      '' get the hash result
      Dim As Long buffersize = BUFFER_SIZE
      cryptGetAttributeString( ctx, CRYPT_CTXINFO_HASHVALUE, @buffer(0), @buffersize )

      '' convert to hexadecimal
      Dim As String result = ""
      For i As Integer = 0 To buffersize-1
         result += Hex( buffer(i) )
      Next
      
      '' free the context
      cryptDestroyContext( ctx )

      Return result
   End Function

      Dim As String filename = Trim( Command(1) )
      If( Len( filename ) = 0 ) Then
         Print "Usage: hash.exe filename"
         End -1
      End If

      '' init cryptlib
      cryptInit( )

      '' calculate hashes
      Print "md5:  "; calc_hash( filename, CRYPT_ALGO_MD5 )
      Print "sha1: "; calc_hash( filename, CRYPT_ALGO_SHA1 )

      '' shutdown cryptlib
      cryptEnd( )

      Sleep

   


------------------------------------------------------------ ExtLibUUID ----
UUID library

The UUID library can be used to generate universally unique identifiers. 
It's part of the e2fsprogs utilities.

Website: http://e2fsprogs.sourceforge.net/
Platforms supported: Win32, Linux
Headers to include: uuid.bi
Header version: from 2010




============================================================================
    Mathematics

---------------------------------------------------------- ExtLibbigint ----
big_int

Library for using arbitrarily large integers. Note: This library seems to 
be dead, a possible alternative is gmp.

Website: http://valyala.narod.ru/big_int/ (Russian) [the site apparently is 
gone]
Github: https://github.com/valyala/big_int
Platforms supported: Win32, Linux
Headers to include: big_int/big_int.bi
Header version: from 2005
Examples: in examples/math/big_int/

Example
   #include Once "big_int/big_int_full.bi"

   Sub print_num(ByVal num As big_int Ptr)
      Dim As big_int_str Ptr s = big_int_str_create(1)
      If (s = 0) Then
         Exit Sub
      End If

      If (big_int_to_str(num, 10, s) <> 0) Then
         Exit Sub
      End If

      Print *s->Str;

      big_int_str_destroy(s)
   End Sub

      Dim As big_int Ptr bignum = big_int_create(1)

      big_int_from_int(2, bignum)
      big_int_pow(bignum, 65536, bignum)

      Print "2^65536 = ";
      print_num(bignum)
      Print

      big_int_destroy(bignum)



-------------------------------------------------------- ExtLibChipmunk ----
Chipmunk Physics

Chipmunk is a physics library designed specifically for 2D games.

Website: http://chipmunk-physics.net/
Platforms supported: Win32, Linux
Headers to include: chipmunk/chipmunk.bi
Header version: 4.1.0



------------------------------------------------------------- ExtLibgmp ----
gmp, The GNU Multiple Precision Arithmetic Library

Free library for arbitrary precision arithmetic, operating on signed 
integers, rational numbers, and floating point numbers.

Website: http://www.gmplib.org
Platforms supported: Win32, Linux
Headers to include: gmp.bi
Header version: 4.1.4

Example
   #include Once "gmp.bi"

   Dim As mpz_ptr bignum = Allocate(SizeOf(__mpz_struct))
   mpz_init_set_si(bignum, 2)
   mpz_pow_ui(bignum, bignum, 65536)

   Print "2^65536 = ";
   Dim As ZString Ptr s = mpz_get_str(0, 10, bignum)
   Print *s;
   Deallocate(s)
   Print

   mpz_clear(bignum)
   Deallocate(bignum)

   


------------------------------------------------------------- ExtLibgsl ----
gsl, The GNU Scientific Library

Provides a wide range of mathematical routines such as random number 
generators, special functions and least-squares fitting.

Website: http://www.gnu.org/software/gsl/, Windows port: http://gnuwin32.sou
rceforge.net/packages/gsl.htm 
Platforms supported: Win32, Linux
Headers to include: gsl/*.bi
Header version: 1.6
Examples: in examples/math/GSL/

Example
   '' Elementary math example
   #include "gsl/gsl_math.bi"

   '' Raise the value of 3.141 to the fourth power
   ? "3.141 ^ 4 = "; gsl_pow_4(3.141)
   ?

   '' Find the hypotenuse of a right triangle with sides 3 and 4 
   ? "The hypotenuse of a right triangle with sides of length 3 and 4 is"; gsl_hypot(3,4)
   ?

   Sleep

   '' Matrix example
   #include "gsl/gsl_matrix.bi"

   '' gsl uses the c-style row major order, unlike VB or Fortran 
   ? "A 3x3 matrix" 
   Dim As gsl_matrix Ptr m = gsl_matrix_alloc(3, 3)
   For i As Integer = 0 To 2
      For j As Integer = 0 To 2
         gsl_matrix_set (m, i, j, 0.23 + 100*i + j)
      Next
   Next

   For i As Integer = 0 To 2
      For j As Integer = 0 To 2
         Print "m(";i;",";j;") = "; gsl_matrix_get (m, i, j)
      Next
   Next
   ?

   gsl_matrix_transpose(m)

   ? "And its transpose"
   For i As Integer = 0 To 2
      For j As Integer = 0 To 2
         Print "m(";i;",";j;") = "; gsl_matrix_get (m, i, j)
      Next
   Next

   Sleep



---------------------------------------------------------- ExtLibnewton ----
Newton

The Newton Physics Engine is an integrated solution for real time 
simulation of physics environments. 

Website: http://newtondynamics.com/
Platforms supported: Win32, Linux
Headers to include: Newton.bi
Header version: from 2005
Examples: in examples/math/Newton/



------------------------------------------------------------- ExtLibode ----
ODE, the Open Dynamics Engine

Open source, high performance library for simulating rigid body dynamics.

Website: http://www.ode.org/
Platforms supported: Win32, Linux
Headers to include: ode/ode.bi
Header version: 0.11.1
Examples: in examples/math/ODE/




============================================================================
    Networking

--------------------------------------------------------- ExtLibcgiutil ----
cgi-util

Small C library for creating CGI programs for Websites.

Website: http://www.newbreedsoftware.com/cgi-util/
Platforms supported: Win32, Linux
Headers to include: cgi-util.bi



------------------------------------------------------------ ExtLibcurl ----
curl

Free and easy-to-use client-side URL transfer library supporting almost 
every protocol.

Website: http://curl.haxx.se/libcurl/
Platforms supported: Win32, Linux, DOS
Headers to include: curl.bi
Header version: 7.44.0
Examples: in examples/network/curl/

Example
   '' Curl HTTP Get example

   #include Once "curl.bi"
   #include Once "crt/string.bi"

   '' this callback will be called when any data is received
   Private Function write_callback cdecl _
      ( _
         ByVal buffer As Byte Ptr, _
         ByVal size As Integer, _
         ByVal nitems As Integer, _
         ByVal outstream As Any Ptr _
      ) As Integer

      Static As ZString Ptr zstr = 0
      Static As Integer maxbytes = 0

      Dim As Integer bytes = size * nitems

      '' current zstring buffer too small?
      If( maxbytes < bytes ) Then
         zstr = Reallocate( zstr, bytes + 1 )
         maxbytes = bytes
      End If

      '' "buffer" is not null-terminated, so we must dup it and add the null-term
      memcpy( zstr, buffer, bytes )
      zstr[bytes] = 0

      '' just print it..
      Print *zstr

      Return bytes
   End Function

      '' init
      Dim As CURL Ptr curl = curl_easy_init( )
      If( curl = 0 ) Then
         End 1
      End If

      '' set url and callback
      curl_easy_setopt( curl, CURLOPT_URL, "freebasic.net" )
      curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, @write_callback )

      '' execute..
      curl_easy_perform( curl )

      '' shutdown
      curl_easy_cleanup( curl )



--------------------------------------------------------- ExtLibFastCGI ----
FastCGI

Open extension to CGI that provides high performance without the 
limitations of server specific APIs.

Website: http://www.fastcgi.com
Platforms supported: Win32, Linux
Headers to include: fastcgi/fastcgi.bi, fastcgi/fcgiapp.bi, 
fastcgi/fcgi_stdio.bi
Header version: 2.4.1-SNAP-0311112127

Example
   #include "fastcgi/fcgi_stdio.bi"

   Dim As Integer count = 0
   While (FCGI_Accept() >= 0)
      count += 1
      Print !"Content-type: text/html\r\n"
      Print !"\r\n"
      Print "<title>FastCGI Hello!</title>"
      Print "<h1>FastCGI Hello!</h1>"
      Print Using "Request number ### running on host <i>&</i>"; count; *getenv("SERVER_NAME");
   Wend



---------------------------------------------------------- ExtLibZeroMQ ----
ZeroMQ

High-performance asynchronous messaging library

Website: http://www.zeromq.org/
Platforms supported: Win32, Linux
Headers to include: zmq/zmq.bi
Header version: 2.1.10




============================================================================
    eXtensible Markup Language (XML)

----------------------------------------------------------- ExtLibexpat ----
Expat

Stream oriented XML parser library with several useful features.

Website: http://expat.sourceforge.net/
Platforms supported: Win32, Linux
Headers to include: expat.bi
Header version: 1.95.8
Examples: in examples/xml/

Example
   '' XML file parser command line tool based on libexpat

   '' Can use zstring or wstring (libexpat or libexpatw):
   '#define XML_UNICODE

   #include Once "expat.bi"
   #include Once "crt/mem.bi"

   #ifndef False
   #define False 0
   #endif
   #define NULL 0

   Const BUFFER_SIZE = 1024

   Type Context
      As Integer nesting
      As XML_char * (BUFFER_SIZE+1) text
      As Integer textlength
   End Type

   Dim Shared As Context ctx

   '' Callback called by libexpat when begin of XML tag is found
   Sub elementBegin cdecl _
      ( _
         ByVal userdata As Any Ptr, _
         ByVal element As Const XML_char Ptr, _
         ByVal attributes As Const XML_char Ptr Ptr _
      )

      '' Show its name
      Print Space(ctx.nesting);*element;

      '' and its attributes (attributes are given as an array of XML_char pointers
      '' much like argv, for each attribute there will apparently be the one
      '' element representing the name and a second element representing the
      '' specified value)
      While (*attributes)
         Print " ";**attributes;
         attributes += 1
         Print "='";**attributes;"'";
         attributes += 1
      Wend
      Print

      ctx.nesting += 1
      ctx.text[0] = 0
      ctx.textlength = 0
   End Sub

   '' Callback called by libexpat when end of XML tag is found
   Sub elementEnd cdecl(ByVal userdata As Any Ptr, ByVal element As Const XML_char Ptr)
      '' Show text collected in charData() callback below
      Print Space(ctx.nesting);ctx.text
      ctx.text[0] = 0
      ctx.textlength = 0
      ctx.nesting -= 1
   End Sub

   Sub charData cdecl _
      ( _
         ByVal userdata As Any Ptr, _
         ByVal chars As Const XML_char Ptr, _  '' Note: not null-terminated
         ByVal length As Integer _
      )

      '' This callback will apparently recieve every data between xml tags
      '' (really?), including newlines and space.

      '' Append to our buffer, if there still is free room, so we can print it out later
      If (length <= (BUFFER_SIZE - ctx.textlength)) Then
         memcpy(@ctx.text[ctx.textlength], @chars[0], length * SizeOf(XML_char))
         ctx.textlength += length
         ctx.text[ctx.textlength] = 0
      End If
   End Sub

   ''
   '' Main
   ''

      Dim As String filename = Command(1)
      If (Len(filename) = 0) Then
         Print "Usage: expat <xmlfilename>"
         End 1
      End If

      Dim As XML_Parser parser = XML_ParserCreate(NULL)
      If (parser = NULL) Then
         Print "XML_ParserCreate failed"
         End 1
      End If

      ''XML_SetUserData(parser, userdata_pointer)
      XML_SetElementHandler(parser, @elementBegin, @elementEnd)
      XML_SetCharacterDataHandler(parser, @charData)

      If (Open(filename, For Input, As #1)) Then
         Print "Could not open file: '";filename;"'"
         End 1
      End If

      Static As UByte buffer(0 To (BUFFER_SIZE-1))

      Dim As Integer reached_eof = False
      Do
         Dim As Integer size = BUFFER_SIZE
         Dim As Integer result = Get(#1, , buffer(0), size, size)
         If (result Or (size <= 0)) Then
            Print "File input error"
            End 1
         End If

         reached_eof = (EOF(1) <> False)

         If (XML_Parse(parser, @buffer(0), size, reached_eof) = False) Then
            Print filename & "(" & XML_GetCurrentLineNumber(parser) & "): Error from XML parser: "
            Print *XML_ErrorString(XML_GetErrorCode(parser))
            End 1
         End If
      Loop While (reached_eof = False)

      XML_ParserFree(parser)



---------------------------------------------------------- ExtLiblibxml ----
libxml2

De-facto standard library for accessing xml files.

Website: http://xmlsoft.org/
Platforms supported: Win32, Linux
Headers to include: libxml/*.bi
Header version: 2.6.17
Examples: in examples/xml/

Example
   #include Once "libxml/xmlreader.bi"
   #define NULL 0

   Dim As String filename = Command(1)
   If( Len( filename ) = 0 ) Then
      Print "Usage: libxml filename"
      End 1
   End If

   Dim As xmlTextReaderPtr reader = xmlReaderForFile( filename, NULL, 0 )
   If (reader = NULL) Then
      Print "Unable to open "; filename
      End 1
   End If

   Dim As Integer ret = xmlTextReaderRead( reader )
   Do While( ret = 1 )
      Dim As Const ZString Ptr constname = xmlTextReaderConstName( reader )
      Dim As Const ZString Ptr value = xmlTextReaderConstValue( reader )

      Print xmlTextReaderDepth( reader ); _
         xmlTextReaderNodeType( reader ); _
         " "; *constname; _
         xmlTextReaderIsEmptyElement(reader); _
         xmlTextReaderHasValue( reader ); _
         *value

      ret = xmlTextReaderRead( reader )
   Loop

   xmlFreeTextReader( reader )

   If( ret <> 0 ) Then
      Print "failed to parse: "; filename
   End If

   xmlCleanupParser( )
   xmlMemoryDump()



--------------------------------------------------------- ExtLiblibxslt ----
libxslt

XSLT itself is a an XML language to define transformation for XML.

Website: http://xmlsoft.org/XSLT/
Platforms supported: Win32, Linux
Headers to include: libxslt/libxslt.bi
Header version: 1.1.13



------------------------------------------------------------ ExtLibmxml ----
mxml, Mini-XML

Mini-XML is a small XML parsing library that you can use to read XML and 
XML-like data files in your application without requiring large 
non-standard libraries.

Website: http://www.minixml.org/
Platforms supported: Win32, Linux
Headers to include: mxml.bi
Header version: 2.7




============================================================================
    Regular Expressions

------------------------------------------------------------ ExtLibpcre ----
PCRE, Perl Compatible Regular Expressions

Consists of a set of functions that implement regular expression pattern 
matching using the same syntax and semantics as Perl 5.

Website: http://www.pcre.org
Platforms supported: Win32, Linux
Headers to include: pcre.bi, pcre16.bi, prceposix.bi
Version: 8.31
Examples: in examples/regex/PCRE/



------------------------------------------------------------- ExtLibtre ----
TRE (regex matching library)

Lightweight, robust, and efficient POSIX compliant regexp matching library

Website: http://laurikari.net/tre/
Platforms supported: Win32, Linux
Headers to include: tre/tre.bi, tre/regex.bi
Header version: 0.8.0
Examples: in examples/regex/TRE/




============================================================================
    Compression

----------------------------------------------------------- ExtLibbzip2 ----
libbzip2

libbzip2 is the library implementing .bz2 file or in-memory compression and 
extraction, with interfaces similar to zlib.

Website: http://bzip.org/
Platforms supported: Win32, Linux, DOS
Headers to include: bzlib.bi
Header version: 1.0.6
Examples: in examples/compression/



------------------------------------------------------------- ExtLibZip ----
libzip

Easy-to-use library for creating, reading out or modifying .zip archives.

Website: http://www.nih.at/libzip/
Platforms supported: Win32, Linux, DOS
Headers to include: zip.bi
Header version: 0.11.2
Examples: in examples/compression/

Example
   '' .zip unpacking using libzip
   #include Once "zip.bi"

   Sub create_parent_dirs(ByVal file As ZString Ptr)
      '' Given a path like this:
      ''	foo/bar/baz/file.ext
      '' Do these mkdir()'s:
      ''	foo
      ''	foo/bar
      ''	foo/bar/baz
      Dim As UByte Ptr p = file
      Do
         Select Case (*p)
         Case Asc("/")
            *p = 0
            MkDir(*file)
            *p = Asc("/")
         Case 0
            Exit Do
         End Select
         p += 1
      Loop
   End Sub

   '' Asks libzip for information on file number 'i' in the .zip file,
   '' and then extracts it, while creating directories as needed.
   Private Sub unpack_zip_file(ByVal zip As Any Ptr, ByVal i As Integer)
      #define BUFFER_SIZE (1024 * 512)
      Static As UByte chunk(0 To (BUFFER_SIZE - 1))
      #define buffer (@chunk(0))

      '' Retrieve the filename.
      Dim As String filename = *zip_get_name(zip, i, 0)
      Print "file: " & filename & ", ";

      '' Retrieve the file size via a zip_stat().
      Dim As zip_stat stat
      If (zip_stat_index(zip, i, 0, @stat)) Then
         Print "zip_stat() failed"
         Return
      End If

      If ((stat.valid And ZIP_STAT_SIZE) = 0) Then
         Print "could not retrieve file size from zip_stat()"
         Return
      End If

      Print stat.size & " bytes"

      '' Create directories if needed
      create_parent_dirs(filename)

      '' Write out the file
      Dim As Integer fo = FreeFile()
      If (Open(filename, For Binary, Access Write, As #fo)) Then
         Print "could not open output file"
         Return
      End If

      '' Input for the file comes from libzip
      Dim As Any Ptr fi = zip_fopen_index(zip, i, 0)
      Do
         '' Write out the file content as returned by zip_fread(), which
         '' also does the decoding and everything.
         '' zip_fread() fills our buffer
         Dim As Integer bytes = _
            zip_fread(fi, buffer, BUFFER_SIZE)
         If (bytes < 0) Then
            Print "zip_fread() failed"
            Exit Do
         End If

         '' EOF?
         If (bytes = 0) Then
            Exit Do
         End If

         '' Write <bytes> amount of bytes of the file
         If (Put(#fo, , *buffer, bytes)) Then
            Print "file output failed"
            Exit Do
         End If
      Loop

      '' Done
      zip_fclose(fi)
      Close #fo
   End Sub

   Sub unpack_zip(ByRef archive As String)
      Dim As Any Ptr zip = zip_open(archive, ZIP_CHECKCONS, NULL)
      If (zip = NULL) Then
         Print "could not open input file " & archive
         Return
      End If

      '' For each file in the .zip... (really nice API, thanks libzip)
      For i As Integer = 0 To (zip_get_num_entries(zip, 0) - 1)
         unpack_zip_file(zip, i)
      Next

      zip_close(zip)
   End Sub

      unpack_zip("test.zip")

   '' .zip packing using libzip
   #include "zip.bi"

   Sub zipAddFileFromString(ByVal fname As ZString Ptr, ByVal id_d As ZString Ptr, ByVal myData As ZString Ptr)
      Dim As Any Ptr pzo
      Dim As Any Ptr pzsb
      
      pzo = zip_open(fname, ZIP_CREATE, 0)
      If pzo = 0 Then End
      
      pzsb = zip_source_buffer(pzo, myData, Len(*myData), 0)
      If pzsb = 0 Then End
      
      zip_file_add(pzo, id_d, pzsb, ZIP_FL_OVERWRITE)
      zip_close(pzo)
      
      Print "OK"
   End Sub

   Dim As String mytext, myzipfile, myfile

   myText    = "<My text           >......6...3..2"
   myZipFile = "26.zip"
   myFile    = "file3.txt"

   zipAddFileFromString(myZipFile, myFile, myText)

   myFile    = "BIMBO/file3.txt"
   zipAddFileFromString(myZipFile, myFile, myText)

   Sleep



------------------------------------------------------------ ExtLibLzma ----
liblzma

Configurable compression library based around the LZMA algorithm with 
zlib-like API. liblzma is the heart of the xz-utils used to handle the 
.lzma and .xz file formats. It is based on 7-Zip's LZMA SDK.

Website: http://tukaani.org/xz/
Platforms supported: Win32, Linux, DOS
Headers to include: lzma.bi
Header version: 5.0.2
Examples: in examples/compression/



------------------------------------------------------------- ExtLibLzo ----
LZO

LZO is a compression library offering fast compression and very fast 
decompression.

Website: http://www.oberhumer.com/opensource/lzo/
Platforms supported: Win32, Linux, DOS
Headers to include: lzo/lzo.bi
Header version: 2.02

Example
   #include "lzo/lzo1x.bi"

   Dim inbuf As ZString Ptr = @"string to compress (or not, since it's so short)"
   Dim inlen As Integer = Len(*inbuf) + 1
   Dim complen As lzo_uint = 100
   Dim compbuf As ZString Ptr = Allocate(complen)
   Dim decomplen As lzo_uint = 100
   Dim decompbuf As ZString Ptr = Allocate(decomplen)
   Dim workmem As Any Ptr

   Print "initializing LZO: ";
   If lzo_init() = 0 Then
      Print "ok"
   Else
      Print "failed!"
      End 1
   End If

   Print "compressing '" & *inbuf & "': ";

   workmem = Allocate(LZO1X_1_15_MEM_COMPRESS)

   If lzo1x_1_15_compress(inbuf, inlen, compbuf, @complen, workmem) = 0 Then
      Print "ok (" & inlen & " bytes in, " & complen & " bytes compressed)"
   Else
      Print "failed!"
      End 1
   End If

   Deallocate(workmem)

   Print "decompressing: ";

   workmem = Allocate(LZO1X_MEM_DECOMPRESS)

   If lzo1x_decompress(compbuf, complen, decompbuf, @decomplen, NULL) = 0 Then
      Print "ok: '" & *decompbuf & "' (" & complen & " bytes compressed, " & decomplen & " bytes decompressed)"
   Else
      Print "failed!"
      End 1
   End If

   Deallocate(workmem)



--------------------------------------------------------- ExtLibquicklz ----
QuickLZ

Cross-platform fast compression library

Website: http://www.quicklz.com
Platforms supported: Win32, Linux, DOS
Headers to include: quicklz.bi
Header version: 1.5.0
Example: examples/compression/QuickLZ.bas



------------------------------------------------------------ ExtLibzlib ----
zlib

Loss-less data compression library using the Deflate algorithm unencumbered 
by patents.

Website: http://www.zlib.net
Platforms supported: Win32, Linux, DOS
Headers to include: zlib.bi
Header version: 1.2.8
Examples: in examples/compression/

Example
   zlib-based PNG save & load code: 
   http://www.freebasic.net/forum/viewtopic.php?t=3936

   In-memory compression example:
   '' Zlib compress/decompress example, by yetifoot

   #include Once "zlib.bi"

   Dim As Integer errlev

   '' This is the size of our test data in bytes.
   Dim As Integer src_len = 100000

   Print "ZLib test - Version " & *zlibVersion()
   Print
   Print "Test data size      : " & src_len & " bytes." 

   '' The size of the destination buffer for the compressed data is calculated by
   '' the compressBound function.
   Dim As Integer dest_len = compressBound(src_len)

   '' Allocate our needed memory.
   Dim As UByte Ptr src = Allocate(src_len)
   Dim As UByte Ptr dest = Allocate(dest_len)

   '' Fill the src buffer with random, yet still compressable data.
   For i As Integer = 0 To src_len - 1
      src[i] = Rnd * 4
   Next

   '' Store the crc32 checksum of the input data, so we can check if the 
   '' uncompression has worked.
   Dim As UInteger crc = crc32(0, src, src_len)

   '' Perform the compression.  dest_len is passed as its address, because when
   '' the function returns it will contain the size of the compressed data.
   errlev = compress(dest, @dest_len, src, src_len)
   If errlev <> 0 Then
      '' If the function returns a value other than 0 then an error occured.
      Print "**** Error during compress - code " & errlev & " ****"
   End If
   Print "Compressed to       : " & dest_len & " bytes."

   '' NOTE: in normal use in a program, you would store the src_len, in order to
   '' be able to tell uncompress the output size.  However in this example we can
   '' just leave it in src_len.  The same goes for dest_len, which is the compressed
   '' datas size.

   '' Wipe the src buffer before we uncompress to it, so that we can check if the 
   '' decompression has worked.
   For i As Integer = 0 To src_len - 1
      src[i] = 0
   Next

   '' Perform a decompression.  This time we uncompress the data back to src.  
   '' src_len is passed as its address, because when
   '' the function returns it will contain the size of the uncompressed data.
   errlev = uncompress(src, @src_len, dest, dest_len)
   If errlev <> 0 Then
      '' If the function returns a value other than 0 then an error occured.
      Print "**** Error during uncompress - code " & errlev & " ****"
   End If
   Print "Uncompressed to     : " & src_len & " bytes."

   '' Make sure the checksum of the uncompressed data matches our original data.
   If crc <> crc32(0, src, src_len) Then
      Print "crc32 checksum      : FAILED"
   Else
      Print "crc32 checksum      : PASSED"
   End If

   '' Free the buffers used in the test.
   Deallocate(src)
   Deallocate(dest)

   Print
   Print "Press any key to end . . . "
   Sleep




============================================================================
    System APIs

------------------------------------------------------------- ExtLibCRT ----
CRT, the C Runtime Library

Standard C language functions. On Windows, this is implemented in 
msvcrt.dll (however, there also are version-specific msvcrXX.dlls, the Micro
soft Visual C++ runtimes). On Linux, the C runtime is typically implemented 
by glibc. For DOS, FreeBASIC uses DJGPP, which provides a libc library.

Websites: http://msdn.microsoft.com/en-us/library/59ey50w6.aspx, http://www.
gnu.org/software/libc/, http://www.delorie.com/djgpp/
Platforms supported: Win32, Linux, DOS
Headers to include: crt.bi
Function reference: C Runtime Functions
MSDN function reference: http://msdn.microsoft.com/en-us/library/634ca0c2.as
px



------------------------------------------------------------- ExtLibdos ----
DOS API

Provides access to low-level BIOS and DOS calls.

Website: http://freedos.org
Platforms supported: DOS
Headers to include: dos/dos.bi
Examples: in examples/DOS/



------------------------------------------------------ ExtLibdisphelper ----
disphelper

Disphelper is a COM helper library that can be used in plain C. No MFC or 
ATL is required. It allows you to call COM objects with an easy printf 
style syntax.

Website: http://disphelper.sourceforge.net/
Platforms supported: Win32, Linux (using WINE)
Headers to include: disphelper/disphelper.bi
Header version: from 2005

Example
   '' HTTP GET example, using MSXML2

   #define UNICODE
   #include "disphelper/disphelper.bi"

   DISPATCH_OBJ(objHTTP)

   dhInitialize(True)
   dhToggleExceptions(True)

   dhCreateObject("MSXML2.XMLHTTP.4.0", NULL, @objHTTP)

   dhCallMethod(objHTTP, ".Open(%s, %s, %b)", "GET", "http://sourceforge.net", False)
   dhCallMethod(objHTTP, ".Send")

   Dim As ZString Ptr szResponse
   dhGetValue("%s", @szResponse, objHTTP, ".ResponseText")

   Print "Response: "; *szResponse
   dhFreeString(szResponse)

   SAFE_RELEASE(objHTTP)
   dhUninitialize(True)

   '' IExplorer example

   #define UNICODE
   #include "disphelper/disphelper.bi"

   Sub navigate(ByRef url As String)
      DISPATCH_OBJ(ieApp)
      dhInitialize(True)
      dhToggleExceptions(True)

      dhCreateObject("InternetExplorer.Application", NULL, @ieApp)
      dhPutValue(ieApp, "Visible = %b", True)
      dhCallMethod(ieApp, ".Navigate(%s)", url)

      SAFE_RELEASE(ieApp)
      dhUninitialize(True)
   End Sub

      navigate("www.freebasic.net")

   '' VB Script example

   #define UNICODE
   #include "disphelper/disphelper.bi"

   '' This function runs a script using the MSScriptControl.
   '' Optionally returns a result.
   Sub RunScript _
      ( _
         ByVal result_identifier As LPWSTR, _
         ByVal result As LPVOID, _
         ByVal script As LPWSTR, _
         ByVal language As LPWSTR _
      )

      DISPATCH_OBJ(control)
      If (SUCCEEDED(dhCreateObject("MSScriptControl.ScriptControl", NULL, @control))) Then
         If (SUCCEEDED(dhPutValue(control, ".Language = %T", language))) Then
            dhPutValue(control, ".AllowUI = %b", True)
            dhPutValue(control, ".UseSafeSubset = %b", False)

            If (result) Then
               dhGetValue(result_identifier, result, control, ".Eval(%T)", script)
            Else
               dhCallMethod(control, ".Eval(%T)", script)
            End If
         End If
      End If

      SAFE_RELEASE(control)
   End Sub

      dhInitialize(True)
      dhToggleExceptions(True)

      '' VBScript sample
      RunScript(NULL, NULL, !"MsgBox(\"This Is a VBScript test.\" & vbcrlf & \"It worked!\",64 Or 3)", "VBScript")

      '' JScript sample
      Dim As Integer result
      RunScript("%d", @result, "Math.round(Math.pow(5, 2) * Math.PI)", "JScript")
      Print "Result ="; result

      Print "Press any key to exit..."
      Sleep

      dhUninitialize(True)



------------------------------------------------------------ ExtLibGLib ----
GLib

Universal utility library most commonly used with GTK+ and GNOME. Provides 
a main loop implementation for event-based programming, portable 
multi-threading, portable file/pipe I/O, many utilities such as command 
line parsing, timers, XML parsing, regular expressions, Unicode 
manipulation, and also general-purpose data structures.

Website: http://developer.gnome.org/glib/
Platforms supported: Linux, Win32
Headers to include: glib.bi
Version: 2.42.2
Examples: in examples/misc/glib/



--------------------------------------------------------- ExtLibwindows ----
Windows API

Standard API for all Windows Systems, used for example for creating Windows 
GUIs (forms and controls), socket programming, inter-process communication, 
and so much more.

Website: http://msdn.microsoft.com/en-us/library/ee663300.aspx
Platforms supported: Win32, Linux (using WINE)
Headers to include: windows.bi
Examples: yes, in examples/win32/



------------------------------------------------------------- ExtLibX11 ----
X11

The X Windowing System is widely used on Linux as the layer that 
coordinates drawing to the screen by providing windows. It also delivers 
events such as mouse and keyboard input from the kernel to applications. It 
is designed to run as a server that can be contacted through a specific 
protocol. The client's side of the protocol is implemented by libraries 
such as the old Xlib or the more modern XCB. Applications can use these to 
create windows and draw to them. However, typically most developers will 
choose to use a GUI library such as GTK+ (which has an X11 backend) 
instead.

Website: http://www.x.org/, http://xcb.freedesktop.org/
Platforms supported: Linux
Headers to include: X11/*.bi





============================================================================
  USING THE FREEBASIC COMPILER
  ----------------------------


---------------------------------------------------- CompilerInstalling ----
Installing

Installing FreeBASIC, any additionally needed packages, and perhaps a text 
editor or IDE.

Note: If the user specifies directory names during the installation of the 
different components, it is recommended in the chosen names to use only 
alphanumeric ASCII characters without accent and preferably not any space, 
otherwise some paths might not work as expected.

Windows 32bit

   * Download the latest FreeBASIC-x.xx.x-win32.zip package, or the latest 
     FreeBASIC-x.xx.x-win32.exe installer (not recommended for Windows 7 
     and later versions).
   * Depending on the chosen method:
      * Zip package: Extract it where you like, for example at 
        ...\FreeBASIC (no further installation required to use fbc).
      * Installer (not recommended for Windows 7 and later versions): Run 
        it and click through it. The installer will install FreeBASIC at 
        C:\%ProgramFiles%\FreeBASIC, or if you chose a different 
        installation directory, in your chosen directory. Start Menu 
        shortcuts to the website will be installed as well.
   * Unless you already have a source code editor or IDE, you should 
     install one too, as FreeBASIC itself does not include one. An IDE can 
     be used to write and save .bas files and to launch the FreeBASIC 
     Compiler to compile them. The following IDEs are known to explicitly 
     support FreeBASIC:
      * FBIDE
      * FBEdit
      * WinFBE Editor and Visual Designer

   To uninstall FreeBASIC:
         * If previously installed using zip package: simply deleted the 
           directory where you extracted it.
         * If previously installed using installer: remove it from the 
           system's list of installed software (Add/remove programs, 
           Uninstall or change a program).

Windows 64bit

   * Download the latest FreeBASIC-x.xx.x-win64.zip package.
   * Extract it where you like, for example at ...\FreeBASIC (no further 
     installation required to use fbc).
   * You may want to install a source code editor or IDE; also see the 
     Windows 32bit section.

   To uninstall FreeBASIC, simply deleted the directory where you extracted 
   it.

Linux

   * Download the latest 
     FreeBASIC-x.xx.x-linux-x86.tar.gz (32bit) or FreeBASIC-x.xx.x-linux-x86_64.tar.gz (64bit) package
   * Extract the archive, for example by doing right-click -> Extract 
     Here, or manually in a terminal:

   $ cd Downloads
   $ tar xzf FreeBASIC-x.xx.x-linux-x86.tar.gz

         * The FreeBASIC compiler can be used from where it was extracted. 
           Usually it is installed into the /usr/local system directory 
           though, so that the fbc program is available through-out the 
           whole system. To do that, run the included installation script:

   $ cd FreeBASIC-x.xx.x-linux-x86
   $ sudo ./install.sh -i

      The install.sh script can also be given a path as in ./install.sh -i 
      /usr if you prefer to install into a directory other than the default 
      /usr/local. This default is a good choice though, as it avoids mixing 
      with the content of /usr which is usually managed by the 
      distribution's packaging tool.

   * FreeBASIC requires several additional packages to be installed before 
     it can be used to compile executables. In general, these are:

         * binutils
         * libc development files (installing gcc will typically install 
           these too)
         * gcc
         * libncurses development files
         * X11 development files (for FB graphics programs)
         * libffi development files (for the ThreadCall keyword)
         * gpm (general purpose mouse) daemon and libgpm (only needed for 
           GetMouse support in the Linux console)

      The actual package names to install vary depending on the GNU/Linux 
      distribution.

      For native development (32bit FB on 32bit system, or 64bit FB on 
      64bit system):
         * Debian/Ubuntu:
            * gcc
            * libncurses5-dev
            * libffi-dev
            * libgl1-mesa-dev
            * libx11-dev libxext-dev libxrender-dev libxrandr-dev 
              libxpm-dev
         * Fedora:
            * gcc
            * ncurses-devel
            * libffi-devel
            * mesa-libGL-devel
            * libX11-devel libXext-devel libXrender-devel libXrandr-devel 
              libXpm-devel
         * OpenSUSE:
            * gcc
            * ncurses-devel
            * libffi46-devel
            * xorg-x11-devel

      For 32bit development on a 64bit system:
         * Debian/Ubuntu:
            * gcc-multilib
            * lib32ncurses5-dev
            * libx11-dev:i386 libxext-dev:i386 libxrender-dev:i386 
              libxrandr-dev:i386 libxpm-dev:i386
            * (See comment below re Ubuntu 10.04 LTS)
         * OpenSUSE:
            * gcc-32bit
            * ncurses-devel-32bit
            * xorg-x11-devel-32bit
            * xorg-x11-libX11-devel-32bit
            * xorg-x11-libXext-devel-32bit
            * xorg-x11-libXrender-devel-32bit
            * xorg-x11-libXpm-devel-32bit
            * libffi46-devel-32bit

               * Unless you already have a text editor or IDE, you should 
                 install one too, as FreeBASIC itself does not include one. 
                 An IDE can be used to write and save .bas files and to 
                 launch the FreeBASIC Compiler to compile them. The 
                 following IDEs are known to explicitly support FreeBASIC:
      * Geany

   To uninstall FreeBASIC from /usr/local, you can run the install.sh 
   script again, but with the -u option: sudo ./install.sh -u

DOS

   * Download the latest FreeBASIC-x.xx.x-dos.zip archive
   * Find a place for FreeBASIC with at least 13 MiB free space.
   * Unpack the ZIP archive, making sure that the directory structure as 
     used inside the archive is preserved ("PKUNZIP -d" for example). 
   * The top-level directory is named FreeBASIC-x.xx.x-dos (will be 
     truncated to "FREEBASI" in DOS without full LFN support), so you might 
     want to rename it then to a convenient DOS-compliant name not longer 
     than 8 characters and containing no white-spaces, like "FB".
   * All the important files used by the compiler (includes, libs) inside 
     the archive do have DOS-compliant names, therefore DOSLFN is not 
     required to use FreeBASIC, however, some examples and texts do have 
     longer names and will be truncated when extracted without full LFN 
     support.  

   (Note: you can install the DOS version "over" the Windows one or 
   vice-versa, or "merge" those installations later, but rename the FBC.EXE 
   file of the previous installation to FBCW.EXE , FBCD.EXE or such, or it 
   will be overwritten by the new one. Other platform specific files are 
   placed in subdirectories making sure that they won't conflict.)

Compiling under Ubuntu 10.04 LTS, 64-bit:
This comment applies to FB 1.01.0, and may apply to other builds also.
Install all of the Libraries listed above; some of the entries ending in 
â€œ:i386â€� may throw â€œnot foundâ€� errors.
To verify that youâ€™re using a 64-bit build, use: â€œuname -aâ€� or 
â€œuname -mâ€� (itâ€™ll show x86_64 for 64-bit, i386 for 32-bit).
Then, when running FBC, an error may appear: â€œerror while loading shared 
libraries: libtinfo.so.5: cannot open shared object file: No such file or 
directoryâ€�.

â€œlibtinfo.so.5â€� is available as a separate library in Ubuntu 11.10+, 
but it is built into â€œncurses.so.5â€� in 10.04 LTS. So, we need to 
re-direct the libtinfo references into the ncurses.so.5 libraries:
   * Issue: find / -name 'libtinfo.so.5' - just to verify that there are 
     no confusing references to these libraries anywhere. Any references 
     should be checked, and probably deleted?
   * Change to the folder containing the FBC executable (perhaps 
     â€œ/usr/local/bin/â€�).
   * Issue: ldd fbc - it will list the various library folder(s) being 
     searched (probably â€œ/lib32â€� in most cases).
   * Issue: sudo ln -s /lib32/libncurses.so.5 /lib32/libtinfo.so.5 
     (assuming â€œ/lib32â€� was emitted in the previous step).
   * Issue: sudo ln -s /lib32/libtinfo.so.5     /lib32/libtinfo.so 
     (assuming â€œ/lib32â€�...)
   * Retry!
   * [Unrelated point: if "private" Libraries are needed for compiles, 
     they were expected to be in /usr/local/lib/freebasic/. Now, they may 
     have to be in /usr/local/lib/freebasic/linux-x86/].
   * [Mike Kennedy, Jan, 2015. (This note was not acceptable as a standard 
     "comment" - I don't know why?)].

See also
   * Invoking the Compiler
   * Compiler Command Line Options



-------------------------------------------------- CompilerRequirements ----
Requirements

Windows version
   * The FreeBASIC compiler (fbc.exe) and the executables generated by it, 
     need at least Windows 98 to run.
   * The msvcrt.dll (the Microsoft's C runtime library) must be present 
     (note: it wasn't shipped with Windows 95, but it's installed by many 
     applications and can be also downloaded at: Microsoft).
   * The gfx routines will use DirectX 5.0 or later if found on the host 
     system, otherwise they'll fall back on standard Win32 GDI which will 
     work on any Windows system.
   * Unicode wide strings (WSTRING's) only work in Windows 
     NT/2000/XP/2003/Vista or above. Applications that depend on 
     wide-strings will run in Windows 98/Me, but no input/output will work 
     if the character set isn't Latin-based, because those platforms don't 
     support Unicode strings. Windows 95 has most Unicode API functions 
     missing; applications using wide strings won't even be loaded by this 
     specific OS.

Linux version
   * The FreeBASIC compiler (fbc) and the executable generated by it 
     depend on libc, libm, libpthread, libdl and libncurses. These are all 
     standard Linux libraries and should be available by default on all 
     modern distros.
   * When using the gfx routines, the dependencies will increase. 
     FreeBASIC gfx programs will also need libX11, libXext, libXpm, 
     libXrender and libXrandr to be installed on the host system to be 
     executed. This is usually not a problem as long as there's a recent 
     X11 server installed in the system (at least XFree86 4.3.0 or any 
     X.org version).
   * If having a working X11 installation is enough to run FreeBASIC gfx 
     programs, it may be not enough to compile them; you may need to 
     install the X11 development libraries from your Linux packages 
     repository.
   * Unicode wide-strings (WSTRING's) with non-ASCII character sets can 
     only be displayed in console if the locale is set to an UTF-8 version 
     - most modern distros come with support that and char sets other than 
     latin may work only in xterm.

DOS version
   * Official requirement: A DPMI (DOS Protected-Mode Interface) server 
     must be present to run fbc.exe and any executable generated by it. 
     This is not as bad as it looks.  It simply means, that the 
     "CWSDPMI.EXE" file (cca 20 KiB) must be present in the same directory 
     or a place where the PATH environment variable points to. CWSDPMI 
     package: homer.rice.edu...cwsdpmi (note: FreeDOS comes with it already 
     installed). Further, there is a possibility to bypass this problem, 
     and to use alternatively HDPMI, for details see DOS related FAQ .
   * You need a 80386 or newer CPU and cca 4 MiB of RAM. For compiling of 
     large programs or libraries, you will need more. Similar applies to 
     executables generated by FBC, those using FB's graphics library 
     however will need a better/faster CPU (200 MHz (?), work in progress, 
     code not yet fully optimized, and exact minimum not known by now). FBC 
     and executables generated by it need an FPU (80387, 80487, always 
     built-in since Pentium). This requirement can by bypassed using 
     "EMU387" (auto-loaded if needed, but not included in FB packages, see 
     delorie.com/djgpp/... ), or by avoiding floats and (non-trivial) 
     removing float-related startup code.
   * The DOS version should run in any DOS, like FreeDOS, 
     [Enhanced-]DR-DOS (do not use the DR-EMM386's included DPMI, use 
     CWSDPMI or HDPMI), or MS-DOS.  It also works properly under a number 
     of "DOS box" environments that emulate a DOS system, such as the 
     Windows NTVDM; however, some of these environments are not implemented 
     faithfully and contain bugs, so caution should be exercised.
   * Long filenames are supported under systems that supply the long 
     filename API defined by Windows 95, including DOS with an LFN TSR (for 
     example DOSLFN (1) (2)).  Long filename support is not required to use 
     the compiler; however, care must be taken in unpacking the 
     distribution, for example, with a Windows program which creates short 
     names with numeric tails (FREEBA~1) instead of truncating to 8 
     characters (FREEBASI).  The filenames of all files in the distribution 
     should be truncated to 8.3 if the compiler is to be used without long 
     filename support.
   * There are a few limitations, see DOS related FAQ .

See also
   * Installing FreeBASIC
   * Compiler Command Line Options
and
   * Compiler FAQ
   * Win32 related FAQ
   * DOS related FAQ
   * LINUX related FAQ



------------------------------------------------------- CompilerRunning ----
Running

Invoking the compiler after installation.

Windows
   The compiler can be manually invoked from the command-line, or 
   automatically by your IDE/Code Editor. If you're using an IDE, you will 
   usually have to tell it where the compiler was installed, so it can find 
   it. How exactly to do that depends on the IDE. 

   To compile manually, you should append the FreeBASIC installation 
   directory to your PATH environment variable, separating it from previous 
   entries using a semi-colon. Now you can simply use "fbc" from the 
   command prompt, instead of always having to type in the full path (e.g. 
   "C:\FreeBASIC\fbc.exe").

   Then, open a console/command prompt/MS DOS prompt, in the same directory 
   as your program. To compile your program, you can use:

      C:\mystuff\myprogram\> fbc myprogram.bas

   and myprogram.exe will be created in the same directory.

   A console can be launched in a specific directory from Explorer by using 
   Microsoft's "Open Command Window Here" PowerToy on Windows XP. On 
   Windows Vista & above you can SHIFT+RightClick on a folder in Explorer 
   to see the 'Open Command Window Here' option. As a last resort, you can 
   also select Start -> Run, type "cmd" and hit Enter, and use the "cd" 
   command to change the current directory.

   Note: You can in fact invoke the compiler from any directory you like, 
   but you have to specifiy the correct path to your program, so the 
   compiler can find it, for example:

      C:\> fbc mystuff\myprogram\myprogram.bas

   The resulting executable will still be put in the same directory as the 
   program.

Linux
   If the install.sh script was successfully executed with enough 
   priviledges, the compiler binary should have been copied 
   /usr/local/bin/fbc, allowing any user access to the compiler from any 
   directory.

   From the prompt, type,

       fbc

   to see a list of options.  To compile the "Hello, world!" example 
   program, navigate to the directory where the FreeBASIC examples were 
   installed (/usr/local/share/freebasic), and type,

      fbc examples/misc/hello.bas

   and a ./hello executable file will be created in the examples/misc 
   directory.

Linux (standalone)
   If the install script install-standalone.sh was successfully executed 
   with enough privileges, a link to the compiler binary should have been 
   created at /usr/bin/fbc, allowing any user access to the compiler from 
   any directory. If it was not possible to create the link, you may want 
   to alter your PATH environmental variable to be able to invoke the 
   compiler from any directory. Navigate to the directory where FreeBASIC 
   was installed.

   From the prompt, type,

       fbc

   to see a list of options. To compile the "Hello, world!" example program 
   type,

      fbc examples/misc/hello.bas

   and a ./hello executable file will be created in the examples/misc 
   directory.

DOS
   Navigate to the directory where FreeBASIC was installed. For example, if 
   FreeBASIC is installed in the directory C:\FB, type,

      C:
      CD FB

   Some DOSes accept "CDD C:\FB" as well. You can also add the FreeBASIC 
   directory to your PATH environment variable (usually something like "SET 
   PATH=C:\FB\;%PATH%") so you can invoke the compiler from any directory.

   At the prompt, type,

      fbc

   to see a list of options. To compile the "Hello, world!" example program 
   type,

      fbc examples\misc\hello.bas

   and a hello.exe executable file will be created in the examples\misc 
   directory.

See also
   * Installing FreeBASIC
   * Compiler Command Line Options
   * Compiler FAQ



------------------------------------------------------- CompilerCmdLine ----
fbc command-line

Using the fbc command-line.

   The official FreeBASIC distribution comes with fbc, FreeBASIC's flagship 
   compiler. fbc is a command line compiler, and can be launched from the 
   console - from DOS, the Windows command prompt or a Linux shell. Running 
   fbc from the console without any arguments displays a list of available 
   options, or command-line switches, that can be used to adjust the 
   behavior of the compiler.

   At its simplest, fbc takes a source file as a command-line argument and 
   produces an executable file. It does this by compiling the source file 
   (.bas) into an assembly (.asm) file, then compiling this into an object 
   file (.o) using GAS and finally linking using LD this object file to 
   other object files and libraries it needs to run, producing the final 
   executable file. The assembly and compiled object files are deleted at 
   this point by default. For example, the following command,

      fbc foo.bas

   produces the executable foo.exe in DOS and Windows, and ./foo in Linux. 
   fbc can accept multiple source files at once, compile and link them all 
   into one executable. For example, the following command,

      fbc foo.bas bar.bas baz.bas

   produces the executable foo.exe in DOS and Windows, and ./foo in Linux. 
   Since foo.bas was listed first, it will be the main entry point into the 
   executable, and also provide its name. To specify a different entry 
   point or executable name, use the "-m" and "-x" switches, respectively. 
   To have, for example, baz.bas provide the main entry point into an 
   executable called foobar.exe, you would use

      fbc -x foobar.exe -m baz foo.bas bar.bas baz.bas

   The "-x" switch names the executable verbatim, so in Linux, the 
   executable produced from the above command would be called ./foobar.exe.

Syntax
   fbc [ options ] [ input_list ]

   Where input_list is a list of filenames. Accepted files are:

         +--------------+--------------------------------+
         |File extension|Description                     |
         |.bas          |FreeBASIC source file           |
         |.a            |Library                         |
         |.o            |Object file                     |
         |.rc           |Resource script (Windows only)  |
         |.res          |Compiled resource (Windows only)|
         |.xpm          |X icon pixmap (Linux only)      |
         +--------------+--------------------------------+

Source code
   -b < name >
      Add a source file to compilation
   -i < name >
      Add a path to search for include files
   -include < name >
      Include a header file on each source compiled
   -d < name=val >
      Add a preprocessor's define
   -lang < name >
      Select language mode: fb, fblite, qb, deprecated
   -forcelang < name >
      Select language mode: fb, fblite, qb, deprecated (overrides 
      statements in code)

Code generation
   -target < platform >
      Set the target platform for cross compilation
   -gen < backend >
      Sets the compiler backend (default is 'gas')
   -asm < format >
      Sets the assembler format for Asm block
   -arch < type >
      Set target architecture (default: 486)
   -O < level >
      Set the optimization level (-gen gcc)
   -vec < level >
      Set level of vector optimizations enabled by the compiler (default: 0
      )
   -fpu < type >
      Set the floating point arithmetics unit (default: FPU)
   -fpmode < type >
      Select between fast and accurate floating-point operations (default: 
      PRECISE)
   -z < value >
      Sets miscellaneous or experimental options
   -pic
      Generate position-independent code (non-x86 Unix shared libs)

Compilation
   -m < name >
      Main file without extension, the entry point (default is the first 
      .bas file on the command line)
   -g
      Add debug info
   -profile
      Enable function profiling
   -e
      Add error checking
   -ex
      Add error checking with RESUME support
   -exx
      Same as -ex, plus array bounds, null-pointer, and error location 
      reporting
   -Wa < opt >
      Pass options to GAS (separated by commas)
   -Wc < opt >
      Pass options to GCC (separated by commas)
   -o < name >
      Set object file path/name (must be passed after the .bas file)

Linking
   -a < name >
      Add an object file to linker's list
   -l < name >
      Add a library file to linker's list
   -p < name >
      Add a path to search for libraries
   -mt
      Link with thread-safe runtime library
   -nodeflibs
      Do not include the default libraries
   -static
      Prefer static libraries over dynamic ones when linking
   -map < name >
      Save the linking map to file name
   -Wl < opt >
      Pass options to LD (separated by commas)
   -export
      Export symbols for dynamic linkage
   -lib
      Create a static library
   -dylib
      Create a DLL, including the import library
   -dll
      Create a DLL, including the import library.  (Same as -dylib)
   -x < name >
      Set executable/library path/name

Behaviour
   -prefix < path >
      Set the compiler prefix path
   -version
      Show compiler version on the command line, do not compile or link
   -v
      Be verbose
   -print < option >
      Display certain information (fblibdir, host, target, x)
   -pp
      Emit the preprocessed input file only, do not compile
   -r
      Compile into intermediate file(s) only, do not assemble or link
   -rr
      Compile into asm file(s) only, do not assemble or link
   -c
      Compile and assemble source file only, do not link
   -R
      Do not delete the intermediate file(s)
   -RR
      Do not delete the asm file(s)
   -C
      Do not delete the object file(s)
   -w < value >
      Set min warning level: all, param, escape, pedantic, next, constness 
      or a value
   -maxerr < val >
      Only stop parsing if <val> errors occurred
   -noerrline
      Do not show source line where error occurred
   -noobjinfo
      Do not read/write compile-time info from/to .o and .a files
   -showincludes
      Display a tree of file names of #included files

Target specific
   -s < name >
      Set subsystem (gui, console)
   -t < value >
      Set stack size in kbytes (default: 1M)

Meta
   @< file >
      Read (additional) command-line options from a file

Example
   fbc myfile.bas
      (With DOS version of FBC, compile and link a DOS executable 
      MYFILE.EXE.)

   fbc -s gui myfile.bas
      (With Windows version of FBC, compile and link a Windows executable 
      myfile.exe. Running the program will not show the console window 
      ("MS-DOS Prompt"))

   fbc -lib module1.bas module2.bas module3.bas -x libmylib.a
      (Compile and link a static library libmylib.a from the three source 
      files)

   fbc -m main_module -c main_module.bas
      (Compile an object file main_module.o and mark it as an entry point)
   fbc -c sub_module.bas
      (Compile an object file sub_module.o)
   fbc -x application.exe main_module.o sub_module.o
      (Link an executable application.exe)

   Note: How to include an icon in a FB executable program
   There is a simple command line option to compile a FB program into an 
   executable with an Icon:
      * Create a *.rc file, for example appicon.rc, with this info:
         FB_PROGRAM_ICON ICON "appicon.ico"
            (where appicon.ico is the name of icon)
      * Then when compiling program, add appicon.rc in the list of files 
        to compile.

See also
   * Compiler Options
   * Installing FreeBASIC
   * Invoking the FreeBASIC compiler





============================================================================
  COMMAND LINE OPTIONS
  --------------------


---------------------------------------------------- CompilerOptoptfile ----
Compiler Option: @file

Read (additional) command-line options from the file

Syntax
      @file

Parameters
   file
      Name of a text file containing command line options. It's possible to 
      use multiple lines in the file. The options may be separated by 
      spaces or line breaks, and support double-quoted strings to allow 
      spaces in parameters (like the real command line). This file can 
      itself contain additional @file options.

Description
   The @file compiler option tells the compiler to parse the specified file 
   to find more command line options. The options found in the file are 
   treated as if they were found on the command line. This can be useful to 
   pass very long command lines to the compiler, for example on DOS, where 
   command lines are limited in length.

Example
options.txt:

   -d TEST=123

opts.bas:
   Print "TEST=" & TEST

   Compile with:

      fbc @options.txt opts.bas

Output:

   TEST=123

See also
   * Using the Command Line



---------------------------------------------------------- CompilerOpta ----
Compiler Option: -a

Add an object file to the linker's list

Syntax
      [ -a ] < object file >

Parameters
   object file
      Name of the object file with extension.

Description
   The -a compiler option adds a compiled object file to the linker's list. 
   The "-a" is optional if the object file name has a ".o" file extension.

See also
   * Compiler Option: -b
   * Using the Command Line



------------------------------------------------------- CompilerOptarch ----
Compiler Option: -arch

Set target architecture for improved/restricted code generation or 
cross-compiling

Syntax
   -arch < architecture >

Parameters
   architecture
      The target architecture. Recognized values:

         * Related to 32bit x86:
            * 386
            * 486 (default for x86)
            * 586
            * 686
            * athlon
            * athlon-xp
            * athlon-fx
            * k8-sse3
            * pentium-mmx
            * pentium2
            * pentium3
            * pentium4
            * pentium4-sse3
         * Related to 64bit x86_64:
            * x86_64, x86-64, amd64
         * Related to 32bit ARM:
            * armv6
            * armv7-a (default for ARM)
         * Related to 64bit ARM (AArch64):
            * aarch64
         * Others:
            * native: For compiling to the architecture which the compiler 
              is running on.
            * 32, 64: For quick cross-compiling to the 32bit or 64bit 
              version of the default architecture.

Description
   The -arch compiler option sets the target CPU architecture. This can be 
   used for multiple purposes:
      * Improving code generation; for example: You can use -arch 686 to 
        override the default -arch 486, and the compiler will generate 
        faster code in some cases, by using certain instructions which were 
        not available on i486 (or other CPUs older than i686).
      * Restricting code generation; for example: You can use -arch 386 to 
        limit the compiler to using only i386-compatible instructions.
      * Cross-compiling; for example: You can use -arch x86_64 on 32bit 
        x86 systems to cross-compile to 64bit x86_64.

   The exact impact which the -arch setting has on code generation depends 
   on the code generation backend that is being used. The x86 ASM backend (
   -gen gas) handles the -arch setting and adjusts code generation 
   accordingly in some cases. When using the GCC backend (-gen gcc), the 
   specified architecture will be passed on to gcc via gcc -march=<...>, 
   causing gcc to generate code for the specified architecture.

   However, -arch only affects newly generated code, but not pre-compiled 
   code such as the FreeBASIC runtime libraries, or any other library from 
   the lib/ directory. For example, using -arch 386 is not necessarily 
   enough to get a pure i386 executable -- it also depends on how all the 
   libraries that will be linked in were compiled.

   The -arch 32 and -arch 64 shortcuts are similar to gcc's -m32/-m64 
   options. On 32bit architectures, -arch 64 is an abbreviation for 
   cross-compiling to the default 64bit version of the architecture (e.g. 
   from 32bit x86 to 64bit x86_64, or 32bit ARM to 64bit AArch64), and 
   -arch 32 does nothing. On 64bit systems, it is the other way round: 
   -arch 32 cross-compiles to the default 32bit architecture, while -arch 
   64 does nothing.

   The -arch native shortcut is similar to gcc's -march=native option. On 
   x86, it causes fbc to try and detect the host CPU automatically based on 
   the cpuid instruction and its availability or results. On other 
   architectures, this will currently simply use the architecture which the 
   compiler itself was built for. Under -gen gcc this will use gcc 
   -march=native.

   Specifying an -arch setting incompatible to the native architecture will 
   trigger cross-compilation, just like the -target option, except that 
   only the target architecture, but not the target operating system, is 
   changed.

See also
   * Using the Command Line
   * -target
   * FB and cross-compiling



-------------------------------------------------------- CompilerOptasm ----
Compiler Option: -asm

Set assembler format for inline assembly under -gen gcc

Syntax
   -asm < format >

Parameters
   format
      The assembler format: intel or att

Description
   The -asm compiler option sets the assembler format for inline Asm blocks 
   when using -gen gcc.

      * -gen gcc -asm intel: FB inline assembly blocks must use FB's usual 
        Intel syntax format. Under -gen gcc, fbc will try to translate it 
        to gcc's format automatically. For example:
   Dim a As Long = 1
   Print a
   Asm
      inc dword Ptr [a]
   End Asm
   Print a

               * -gen gcc -asm att: FB inline assembly blocks must use 
                 gcc's format. For example:
   Dim a As Long = 1
   Print a
   Asm
      "incl %0\n" : "+m" (a) : :
   End Asm
   Print a

   The x86 ASM backend (-gen gas) currently only supports -asm intel and 
   using -asm att results in an error.

See also
   * __FB_ASM__
   * Using the Command Line



---------------------------------------------------------- CompilerOptb ----
Compiler Option: -b

Add a source file to compilation

Syntax
      [ -b ] < source file >

Parameters
   source file
      The name with extension, and optionally a path, of the basic source 
      file.

Description
   The -b option adds a source file to the compilation list. In general, 
   this option is redundant since source files with a .bas extension can be 
   specified without it, but is useful if a source file does not have a 
   .bas extension, or if exists in an other directory.

   To compile and link the source files file1.bas, file2.bas and file3.fb 
   into an executable (file1.exe in DOS/Windows, file1 in Linux), type,

      fbc -b file1.bas file2.bas -b file3.fb

   Note that the -b option was not needed for file1.bas or file2.bas.

See also
   * Compiler Option: -a
   * Using the Command Line



---------------------------------------------------------- CompilerOptc ----
Compiler Option: -c

Compile and assemble source file only, do not link

Syntax
   -c

Description
   The -c option specifies that any source files listed are to be compiled 
   and assembled into object files, and not linked into an executable (the 
   default behavior). When using the "-c" switch, "-m" must be specified 
   when compiling a main source file.

See also
   * Compiler Option: -C
   * Compiler Option: -r
   * Compiler Option: -m
   * Compiler Option: -o
   * Using the Command Line



------------------------------------------------------- CompilerOptcupp ----
Compiler Option: -C

Do not delete the object file(s)

Syntax
   -C

Description
   The -C compiler option causes the object file(s) that are generated 
   during the compile process to not be deleted.

See also
   * Compiler Option: -c
   * Compiler Option: -R
   * Using the Command Line



---------------------------------------------------------- CompilerOptd ----
Compiler Option: -d

Add a preprocessor definition

Syntax
   -d < name=value >
   -d < name >

Parameters
   name
      Name of the preprocessor macro to define.  No parameters are allowed.
   value
      Value to give to the macro.  If omitted, it will be defined as 1

Description
   The -d compiler option adds a preprocessor macro to all source files. 
   The same as using the preprocessor directive #define or #macro.

See also
   * #define
   * #macro
   * Intrinsic Defines
   * Using the Command Line



-------------------------------------------------------- CompilerOptdll ----
Compiler Option: -dll

Create a DLL and import library

Syntax
      -dll

Description
   The -dll compiler option creates a dynamic link library. This creates a 
   DLL under Windows (including the import library), and creates a .so 
   under Linux.

   The intrinsic macro __FB_OUT_DLL__ is set to non-zero (-1) if the -dll 
   option was specified, and set to zero (0) otherwise.

Platform Differences
   * Not supported on the DOS platform.

See also
   * __FB_OUT_DLL__
   * Shared Libraries
   * Using the Command Line



------------------------------------------------------ CompilerOptdylib ----
Compiler Option: -dylib

Create a DLL and import library

Syntax
   -dylib

Description
   The -dylib compiler option creates a dynamic link library. This creates 
   a DLL under Windows (including the import library), and creates a .so 
   under Linux.

   The intrinsic macro __FB_OUT_DLL__ is set to non-zero (-1) if the -dll 
   option was specified, and set to zero (0) otherwise.

Platform Differences
   * Not supported on the DOS platform.

See also
   * __FB_OUT_DLL__
   * Shared Libraries
   * Using the Command Line



---------------------------------------------------------- CompilerOpte ----
Compiler Option: -e

Add error checking

Syntax
   -e

Description
   Adds QuickBASIC-like error checking.

See also
   * __FB_ERR__
   * Compiler Option: -ex
   * Compiler Option: -exx
   * Error Handling
   * Using the Command Line



----------------------------------------------------- CompilerOptearray ----
Compiler Option: -earray

Enable array bounds checking

Syntax
   -earray

Description
   Add array bounds error checking in generated run-time code.  A run-time 
   error is generated if an array index attempts to access an array element 
   that is outside the bounds of the array.

   -earray is automatically implied by the -exx option.

   __FB_ERR__ can be used to determine in user source code if the -earray 
   option was specified or implied on the command line.

See also
   * __FB_ERR__
   * Compiler Option: -exx
   * Error Handling
   * Using the Command Line



---------------------------------------------------- CompilerOpteassert ----
Compiler Option: -eassert

Enable assert() and assertwarn() checking

Syntax
   -eassert

Description
   The -eassert compiler option enables Assert and AssertWarn code 
   generation.

   -eassert is automatically implied by the -g option.

   __FB_ERR__ can be used to determine in user source code if the -eassert 
   option was specified or implied on the command line.

See also
   * __FB_ERR__
   * Assert
   * AssertWarn
   * Compiler Option: -g
   * Debugging
   * Using the Command Line



----------------------------------------------------- CompilerOptedebug ----
Compiler Option: -edebug

Enable __FB_DEBUG__

Syntax
   -edebug

Description
   The -edebug compiler option defines the intrinsic macro __FB_DEBUG__ to 
   enable user debug code.

   The intrinsic macro __FB_DEBUG__ is set to non-zero (-1) if the option 
   was specified, and set to zero (0) otherwise.

   -edebug is automatically implied by the -g option.

   __FB_ERR__ can be used to determine in user source code if the -edebug 
   option was specified or implied on the command line.

See also
   * __FB_DEBUG__
   * __FB_ERR__
   * Compiler Option: -eassert
   * Compiler Option: -debuginfo
   * Compiler Option: -g
   * Debugging
   * Using the Command Line



------------------------------------------------- CompilerOptedebuginfo ----
Compiler Option: -edebuginfo

Add debug information

Syntax
   -edebuginfo

Description
   The -edebuginfo compiler inserts debugging symbols into output files, to 
   use with GDB-compatible debuggers.

   -edebuginfo is automatically implied by the -g option.

   __FB_ERR__ can be used to determine in user source code if the 
   -edebugingo option was specified or implied on the command line.

See also
   * __FB_ERR__
   * Compiler Option: -g
   * Debugging
   * Using the Command Line



-------------------------------------------------- CompilerOptelocation ----
Compiler Option: -elocation

Enable full error location reporting

Syntax
   -elocation

Description
   The -elocation compiler option enables full location reporting in 
   run-time code generation.

   -elocation is automatically implied by the -exx option.

   __FB_ERR__ can be used to determine in user source code if the 
   -elocation option was specified or implied on the command line.

   Note: the intent of this option is for a future fbc feature to optimize 
   out some of the error tracking code associated with error location 
   reporting.  When implemented, only -exx or -elocation will enable the 
   full error location reporting and will be optimized away otherwise.

See also
   * __FB_ERR__
   * Compiler Option: -exx
   * Error Handling
   * Using the Command Line



--------------------------------------------------- CompilerOptenullptr ----
Compiler Option: -enullptr

Enable null-pointer checking

Syntax
   -enullptr

Description
   The -enullptr compiler option enables null-pointer error checking in 
   run-time code generation.  A run-time error is generated if an attempt 
   is made to dereference a null-pointer to a value, or call a null 
   function pointer.

   -enullptr is automatically implied by the -exx option.

   __FB_ERR__ can be used to determine in user source code if the -enullptr 
   option was specified or implied on the command line.

See also
   * __FB_ERR__
   * Compiler Option: -exx
   * Error Handling
   * Using the Command Line



--------------------------------------------------------- CompilerOptex ----
Compiler Option: -ex

Add error checking with Resume support

Syntax
   -ex

Description
   The -ex compiler option adds error handling as with the -e option plus 
   support for Resume.

See also
   * __FB_ERR__
   * Compiler Option: -e
   * Compiler Option: -exx
   * Error Handling
   * Using the Command Line



-------------------------------------------------------- CompilerOptexx ----
Compiler Option: -exx

Add error checking with Resume support and array bounds and null-pointer 
checking

Syntax
   -exx

Description
   The -exx compiler option adds error checking with Resume support, plus 
   array bounds and null-pointer checking (including the procedure 
   pointers).

   Use of the -exx option automatically implies -e, -exx, -earray, 
   -elocation, and -enullptr, error checking and code generation options.

See also
   * __FB_ERR__
   * Compiler Option: -e
   * Compiler Option: -earray
   * Compiler Option: -elocation
   * Compiler Option: -enullptr
   * Compiler Option: -ex
   * Error Handling
   * Using the Command Line



----------------------------------------------------- CompilerOptexport ----
Compiler Option: -export

Export symbols for dynamic linkage

Syntax
   -export

Description
   The -export compiler option exports symbols for dynamic linkage.

See also
   * Export
   * Shared Libraries
   * Using the Command Line



-------------------------------------------------- CompilerOptforcelang ----
Compiler Option: -forcelang

Provides QuickBASIC or backward compatibility

Syntax
   -forcelang dialect

Parameters
   dialect
      The dialect to use in compilation, one of fb (default), fblite, qb or 
      deprecated.

Description
   The -forcelang compiler option changes the way source code is 
   interpreted, and is meant as a tool to users wanting traditional 
   QuickBASIC-like behavior, or behavior deprecated from previous versions 
   of FreeBASIC.  It overrides any #lang statements within the code.

   The intrinsic macro __FB_LANG__ is set to the string name of the dialect 
   specified on the command line, or "fb" by default.

   To learn more about the differences between each of these language 
   dialects, see Compiler Dialects.

   fb

      This is the default dialect, and allows compilation of source code 
      adhering to the most recent version of the FreeBASIC language.

   fblite

      This dialect provides support for FreeBASIC syntax and functionality, 
      but with a more traditional QuickBASIC programming style.

   qb

      This dialect provides the best support for older QuickBASIC code.

   deprecated

      This dialect is for backward compatibility with some previous 
      versions of FreeBASIC, however, this dialect may not exist in future 
      versions.  Programmers should consider using the "fblite" dialect 
      instead.

See also
   * #lang
   * __FB_LANG__
   * Compiler Option: -lang
   * Compiler Dialects
   * Using the Command Line



----------------------------------------------------- compileroptfpmode ----
Compiler Option: -fpmode

Selects faster, less accurate or slower, more precise floating-point math.

Syntax
   -fpmode < mode >

Parameters
   mode
      The floating point mode: FAST | PRECISE.

Description
   The -fpmode compiler option specifies whether speed or precision is more 
   important for floating point math. If this option is not specified, the 
   default is -fpmode PRECISE.

   -fpmode FAST will generate faster, less accurate instructions for 
   certain floating point operations.

   -fpmode PRECISE will generate standard floating point instructions that 
   operate at the default speed and accuracy of the selected floating point 
   unit.

   Currently, the only floating point operations that behave differently 
   when using -fpmode FAST are: Sin(), Cos(), reciprocal, and reciprocal 
   Square Root, all of which must operate on Single precision values.

   Using -fpmode PRECISE is dependent on the -fpu SSE command line option. 
   Using -fpmode PRECISE without using -fpu SSE will generate an error.

See also
   * Using the Command Line
   * Compiler Option: -fpu
   * __FB_FPMODE__



-------------------------------------------------------- CompilerOptfpu ----
Compiler Option: -fpu

Sets the math unit to be used for floating point arithmetics.

Syntax
   -fpu < type >

Parameters
   type
      The floating point unit: X87 | SSE.

Description
   The -fpu compiler option sets the math unit to be used for floating 
   point arithmetics.  If this option is not specified, the default is -fpu 
   X87.

   -fpu X87 will generate floating point instructions for the 387.

   -fpu SSE will generate floating point instructions for SSE and SSE2 with 
   some math support still done by the 387.

   Functions normally return a floating point value (Single or Double) in 
   the st(0) register.  Sometimes, this may be optimized by returning the 
   value in the xmm0 register instead.  This can be specified with 
   Option("Sse") after the return type in a function's declaration or 
   definition.  Option("Sse") is ignored unless the source is compiled with 
   the -fpu SSE command line option.

See also
   * Using the Command Line
   * Option()
   * __FB_FPU__



---------------------------------------------------------- CompilerOptg ----
Compiler Option: -g

Add debug information, define __FB_DEBUG__, and enable asserts

Syntax
   -g

Description
   The -g compiler option inserts debugging symbols into output files, to 
   use with GDB-compatible debuggers.

   The intrinsic macro __FB_DEBUG__ is set to non-zero (-1) if the option 
   was specified, and set to zero (0) otherwise.

   Assert and AssertWarn macros are enabled.

   Use of -g automatically implies -edebug, -edebuginfo, and -eassert, 
   command line options.

   __FB_ERR__ can be used to determine in user source code if the -g option 
   was specified or implied on the command line.

See also
   * __FB_DEBUG__
   * __FB_ERR__
   * Assert
   * AssertWarn
   * Compiler Option: -eassert
   * Compiler Option: -debug
   * Compiler Option: -debuginfo
   * Debugging
   * Using the Command Line



-------------------------------------------------------- CompilerOptgen ----
Compiler Option: -gen

Sets the backend code emitter.

Syntax
   -gen < backend >

Parameters
   backend
      gas for x86 GAS assembly, gcc for GNU C, llvm for LLVM IR.

Description
   The -gen compiler option sets the backend code emitter and assembler.

   -gen gas
      The compiler will emit GAS assembler code to a .asm file which will 
      then be compiled to an object file using 'as'. This is fbc's original 
      x86 code generation backend.

   -gen gcc
      The compiler will emit C code to a .c file which will then be 
      compiled to an .asm file using 'gcc' as a high level assembler. The C 
      backend is intended to make FB portable to more platforms than just 
      x86. This requires gcc to be installed so that fbc can invoke it to 
      compile the C code, also see Installing gcc for -gen gcc.

   -gen llvm
      The compiler will emit LLVM IR code to a .ll file which will then be 
      compiled to an .asm file using 'llc'. The LLVM backend is still a 
      work in progress. It is intended for the same purpose as the C 
      backend, and could theoretically solve some of the C backend's 
      problems, such as debugging meta data support.

See also
   * Tools used by fbc
   * Using the Command Line



---------------------------------------------------------- CompilerOpti ----
Compiler Option: -i

Add a path to search for include files

Syntax
   -i < include path >

Parameters
   include path
      The directory path, relative or absolute, of where to search for 
      include files.

Description
   The -i option allows an additional directory to be used when searching 
   for header files. By default, fbc searches in the current directory, and 
   prefix/inc--in that order--where, prefix is the location where FreeBASIC 
   is installed. A directory specified with the -i option will be searched 
   before these default directories, and when the -i option is used 
   multiple times, fbc will search the directories in the order they are 
   listed on the command-line.

   To search in the subdirectory includes first for header files while 
   compiling the source file file.bas, type,

      fbc -i includes file.bas 

See also
   * #include
   * Compiler Option: -include
   * Header Files
   * Using the Command Line



---------------------------------------------------- CompilerOptinclude ----
Compiler Option: -include

Include a header file on each source compiled

Syntax
   -include < include file >

Parameters
   include file
      The header file name with extension, and optionally a path, to 
      include.

Description
   The -include option has the effect of adding an #include preprocessor 
   directive to the very beginning of each source file before processing 
   it. When used multiple times, the files will be included in the order 
   they are listed on the command-line.

   To include the file header.bi when processing file1.bas and file2.bas, 
   type,

      fbc -include header.bi file1.bas file2.bas

See also
   * #include
   * Compiler Option: -i
   * Header Files
   * Using the Command Line



---------------------------------------------------------- CompilerOptl ----
Compiler Option: -l

Add a library file to the linker's list.

Syntax
   -l < libname >

Parameters
   libname
      Name of the library to link in. The library file name's extension 
      should not be included.  For example, when using -l something, the 
      linker will look for the files:
         * Libsomething.a
         * Libsomething.dll.a (Windows)
         * something.dll (Windows)
         * Libsomething.so (Linux)

Description
   The -l compiler option adds a library file to the linker's list, to be 
   linked into the final executable or library if needed to satisfy 
   dependencies.

See also
   * #inclib
   * Compiler Option: -p
   * Using the Command Line



------------------------------------------------------- CompilerOptlang ----
Compiler Option: -lang

Provides QuickBASIC or backward compatibility

Syntax
   -lang dialect

Parameters
   dialect
      The dialect to use in compilation, one of fb (default), fblite, qb or 
      deprecated.

Description
   The -lang compiler option changes the way source code is interpreted, 
   and is meant as a tool to users wanting traditional QuickBASIC-like 
   behavior, or behavior deprecated from previous versions of FreeBASIC.

   The intrinsic macro __FB_LANG__ is set to the string name of the dialect 
   specified on the command line, or "fb" by default.

   To learn more about the differences between each of these language 
   dialects, see Compiler Dialects.

   fb

      This is the default dialect, and allows compilation of source code 
      adhering to the most recent version of the FreeBASIC language.

   fblite

      This dialect provides support for FreeBASIC syntax and functionality, 
      but with a more traditional QuickBASIC programming style.

   qb

      This dialect provides the best support for older QuickBASIC code.

   deprecated

      This dialect is for backward compatibility with some previous 
      versions of FreeBASIC, however, this dialect may not exist in future 
      versions.  Programmers should consider using the "fblite" dialect 
      instead.

   Note: this command-line option can be overridden by any #lang statements 
   used in the code.

See also
   * #lang
   * __FB_LANG__
   * Compiler Option: -forcelang
   * Compiler Dialects
   * Using the Command Line



-------------------------------------------------------- CompilerOptlib ----
Compiler Option: -lib

Create a static library

Syntax
   -lib

Description
   The -lib compiler option creates a static library.

   The intrinsic macro __FB_OUT_LIB__ is set to non-zero (-1) if the -lib 
   option was specified, and set to zero (0) otherwise.

See also
   * __FB_OUT_LIB__
   * Static Libraries
   * Using the Command Line



---------------------------------------------------------- CompilerOptm ----
Compiler Option: -m

Main file without extension to indicate the main module

Syntax
   -m < source file >

Parameters
   source file
      The name without extension of the main module source file

Description
   The -m compiler option specifies a main entry point for a source file; 
   the argument is the name of a source file minus its extension. If "-m" 
   is not specified, the first source file listed is given a main entry 
   point. When using the "-c" or "-r" switch, "-m" must be specified when 
   compiling a main source file.

   The intrinsic macro __FB_MAIN__ is defined in the main module and not 
   defined in other modules.

See also
   * __FB_MAIN__
   * Compiler Option: -c
   * Compiler Option: -r
   * Using the Command Line



-------------------------------------------------------- CompilerOptmap ----
Compiler Option: -map

Save the linking map to file name

Syntax
   -map < map file >

Parameters
   map file
      Name of the map file to save generated during linking.

Description
   The -map compiler option saves the a map file of the executable made.

See also
   * Using the Command Line



----------------------------------------------------- CompilerOptmaxerr ----
Compiler Option: -maxerr

Set maximum number of errors to report before aborting compilation

Syntax
   -maxerr < value | "inf" >

Parameters
   value | "inf"
      Specifies the maximum number of errors or no maximum if "inf" is 
      given instead of a value.

Description
   The -maxerr compiler option sets the maximum number of errors the 
   compiler must find before stopping. The default is 10. If inf, for 
   infinite, is specified the compiler continues until it finds the end of 
   the source. Useful if an IDE is parsing the error messages.

See also
   * Using the Command Line



--------------------------------------------------------- CompilerOptmt ----
Compiler Option: -mt

Link with thread-safe runtime library

Syntax
   -mt

Description
   The -mt compiler option forces linking with thread-safe runtime library 
   for multithreaded applications. The thread-safe version is always used 
   automatically if the FreeBASIC built-in threading functions are used, so 
   you only need to specify this option if using your own threading 
   routines.

   The intrinsic macro __FB_MT__ is set to non-zero (-1) if the -mt option 
   was specified, and set to zero (0) otherwise.

See also
   * __FB_MT__
   * Using the Command Line



-------------------------------------------------- CompilerOptnodeflibs ----
Compiler Option: -nodeflibs

Do not include the default libraries

Syntax
   -nodeflibs

Description
   The -nodeflibs compiler option causes default libraries not to be used 
   when linking.  The libraries which are normally linked by default can 
   still be used, but only if they are explicitly specified.

See also
   * Using the Command Line



-------------------------------------------------- CompilerOptnoerrline ----
Compiler Option: -noerrline

Do not show source line where error occurred

Syntax
   -noerrline

Description
   The -noerrline compiler option causes reported errors to not show the 
   place in source where error occurred. Useful if an IDE is parsing the 
   error messages.

See also
   * Using the Command Line



-------------------------------------------------- CompilerOptnoobjinfo ----
Compiler Option: -noobjinfo

Do not read/write compile-time info from/to .o and .a files

Syntax
   -noobjinfo

Description
   The -noobjinfo compiler option disables the writing/reading of 
   compile-time library and other linking options from/to .o and .a files. 
   This also disables the use of fbextra.x (the supplemental linker script) 
   for discarding the .fbctinf sections, which is useful when using the 
   gold linker that doesn't support this kind of linker script.

See also
   * Using the Command Line



---------------------------------------------------- CompilerOptnostrip ----
Compiler Option: -nostrip

Do not strip symbol information from the output file

Syntax
   -nostrip

Description
   The -nostrip compiler option explicitly prevents fbc from passing the 
   option to strip (remove) all symbols to the linker.  Object modules and 
   libraries will retain any symbols present after linking.

Platform Differences
   * fbc strips all symbols by default on Dos and Windows platforms only

See also
   * -strip
   * Using the Command Line



---------------------------------------------------------- CompilerOpto ----
Compiler Option: -o

Set object file path/name

Syntax
   -o < output file >

Parameters
   output file
      The name, with optional path, of the object file to create.

Description
   The -o option can be used to specify the file name for the object file 
   created while compiling an input file. By default, the name for the 
   object file (and other temporaries like assembly files) is based on the 
   name of the corresponding input file, but with an .o extension. This 
   option is useful for example in combination with -c, or to force the 
   compiler to create temporary object files in other directories (if, for 
   example, the source code directory is or should be treated as 
   read-only).

   Given -o options are only assigned to input files that need to be 
   compiled, namely *.bas, *.rc, *.res and *.xpm.

   Note: -o options can appear in front of or behind the input file they 
   correspond to, but there cannot be multiple -o options for one input 
   file. For example, these are all accepted:
      fbc 1.bas -o 1.o
      fbc -o 1.o 1.bas
      fbc 1.bas -o 1.o 2.bas -o 2.o
      fbc 1.bas -o 1.o -o 2.o 2.bas
   However, this is an error:
      fbc 1.bas 2.bas -o 1.o -o 2.o

   The -v option makes the compiler show the actual file names that it 
   uses.

See also
   * Compiler Option: -b
   * Compiler Option: -c
   * Using the Command Line



----------------------------------------------- CompilerOptoptimization ----
Compiler Option: -O

Set the optimization level for GCC

Syntax
   -O < level >

Parameters
   level
      The optimization level: 0, 1, 2, 3 or max (3).

Description
   Specifies the optimization level to be passed to GCC when using -gen gcc
   .

See also
   * Compiler Option: -gen gcc
   * Using the Command Line



---------------------------------------------------------- CompilerOptp ----
Compiler Option: -p

Add a path to search for libraries

Syntax
   -p < library path >

Parameters
   library path
      The directory path, relative or absolute, of where to search for 
      library files.

Description
   The -p compiler option adds a path to search for libraries. By default, 
   libraries are looked for in the system FreeBASIC libraries directory and 
   in the current directory.

See also
   * #libpath
   * Using the Command Line



-------------------------------------------------------- CompilerOptpic ----
Compiler Option: -pic

Generate position-independent code (non-x86 Unix shared libs)

Syntax
   -pic

Description
   The -pic compiler option tells the compiler to generate 
   position-independent code. This is needed for creating shared libraries 
   on x86_64 or ARM Linux/BSD platforms except Win64 (and also not on 32bit 
   x86). This option should not be used when creating executables (as 
   opposed to shared libraries) though.

   By default, -pic is enabled when using -dll or -dylib, and disabled for 
   all other compilation modes. Usually you only have to specify -pic if 
   you are using -c or -lib and want to link them into shared libraries 
   later.

   -pic is implemented by passing -fPIC to gcc (when using the -gen gcc 
   backend). The -gen gas backend does not support position-independent 
   code since it only supports 32bit x86 and there is no special 
   position-independent code needed for shared libraries on 32bit x86.

See also
   * Using the Command Line



--------------------------------------------------------- CompilerOptpp ----
Compiler Option: -pp

Emit the preprocessed input file only, do not compile

Syntax
   -pp

Description
   The -pp compiler option enables the preprocessor-only mode. The code is 
   parsed & checked as usual, but is not compiled. For every input file <
   source>.bas passed to the compiler, a pre-processed version named <
   source>.pp.bas is generated.
   Specifically, preprocessor commands such as conditional compilation 
   (#if, #ifdef, #ifndef, etc.), text replacement (#define, #macro, etc.) 
   and file inclusion (#include) are processed recursively, and the 
   resulting expanded code is written to the pp.bas file.

See also
   * Using the Command Line
   * Preprocessor commands



----------------------------------------------------- CompilerOptprefix ----
Compiler Option: -prefix

Set the compiler prefix path

Syntax
   -prefix < path >

Parameters
   path
      The directory, relative or absolute to where fbc is located.

Description
   The -prefix compiler option sets the compiler prefix (where the compiler 
   finds the bin, lib, and inc directories); and defaults to the path where 
   fbc resides, if this can be determined.

See also
   * Using the Command Line



------------------------------------------------------ CompilerOptprint ----
Compiler Option: -print

Print out information

Syntax
      -print option

Description
   The -print option can be used to query the compiler for certain 
   information which may be useful especially for build scripts. It does 
   not prevent compilation of input files given besides the -print option, 
   but the compiler also can be invoked with only a -print option and no 
   input files, in which case it will not compile anything but only respond 
   to the -print option.

   Currently, the following -print options are recognized:

      +--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------+
      |option  |effect                                                                                                                                                       |
      |fblibdir|Prints the compiler's lib/ path                                                                                                                              |
      |host    |Prints the host system on which fbc is running                                                                                                               |
      |target  |Prints the target system for which fbc is compiling (can be affected by the -target option)                                                                  |
      |x       |Prints the file name of the output executable or library that fbc will or would generate (named after the -x option), depending on other command line options|
      +--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------+

Example
   A makefile could use target := $(shell $(FBC) -print target) to find out 
   the compilation target, which would even work when cross-compiling, with 
   FBC set to something like fbc -target foo.

   fbc -print x alone will print out the executable file extension for the 
   target system.
   fbc -print x -dll on the other hand will print out the dynamic library 
   file name format.
   fbc -print x -m foo will print out the executable file name that would 
   be used when compiling a module called foo.bas.
   fbc 1.bas 2.bas -lib -print x will compile 1.bas and 2.bas into a 
   library, whose file name will be displayed.

See also
   * -x
   * -target
   * Using the Command Line



---------------------------------------------------- CompilerOptprofile ----
Compiler Option: -profile

Enable function profiling

Syntax
   -profile

Description
   The -profile compiler option enables function profiling. After running 
   an executable compiled with this option, a gmon.out file will be created 
   in the program directory, allowing use of GPROF for analysis of the 
   program's execution.

See also
   * Profiling
   * Using the Command Line



---------------------------------------------------------- CompilerOptr ----
Compiler Option: -r

Compile into *.asm/*.c/*.ll file(s) only, do not assemble or link

Syntax
   -r

Description
   The -r option specifies that any source files listed are to be compiled 
   to *.asm/*.c/*.ll files, depending on the used code generation backend, 
   and not compiled or linked into an executable.

   When using the -r option, -m must be specified when compiling the main 
   module.

   Use the -R option to preserve intermediate files without affecting 
   compilation/assembling/linking.
   Use the -rr option to compile input source files to *.asm regardless of 
   the code generation backend.

See also
   * Compiler Option: -c
   * Compiler Option: -R
   * Compiler Option: -m
   * Compiler Option: -gen
   * Compiler Option: -rr
   * Using the Command Line



------------------------------------------------------- CompilerOptrupp ----
Compiler Option: -R

Preserve intermediate *.asm/*.c/*.ll file(s) generated by compilation

Syntax
   -R

Description
   The -R compiler option causes the intermediate *.asm/*.c/*.ll file(s) 
   that are generated during the compile process to be preserved. Other 
   than that, compilation is performed as usual. Which files are generated 
   exactly depends on the used code generation backend and compilation 
   target.

   When compiling a Windows DLL, -R also preserves the intermediate *.def 
   file used for generating the import library for the DLL.

See also
   * Compiler Option: -C
   * Compiler Option: -r
   * Compiler Option: -gen
   * Using the Command Line



--------------------------------------------------------- CompilerOptrr ----
Compiler Option: -rr

Compile into *.asm file(s) only, do not assemble or link

Syntax
   -rr

Description
   The -rr option specifies that any source files listed are to be compiled 
   to *.asm files, and not compiled or linked into an executable. Unlike 
   with the -r option, this works regardless of the used 
   code generation backend.

   When using the -rr option, -m must be specified when compiling a main 
   source file.

   Use the -RR option to preserve the generated *.asm files without 
   affecting compilation/assembling/linking.

See also
   * Compiler Option: -c
   * Compiler Option: -r
   * Compiler Option: -RR
   * Compiler Option: -m
   * Compiler Option: -gen
   * Using the Command Line



------------------------------------------------------ CompilerOptrrupp ----
Compiler Option: -RR

Preserve intermediate *.asm files generated by compilation

Syntax
   -RR

Description
   The -RR compiler option causes the intermediate *.asm file(s) that are 
   generated during the compile process to be preserved. Other than that, 
   compilation is performed as usual.

See also
   * Compiler Option: -C
   * Compiler Option: -rr
   * Compiler Option: -R
   * Using the Command Line



---------------------------------------------------------- CompilerOpts ----
Compiler Option: -s

Sets the executable subsystem

Syntax
   -s < subsystem >

Parameters
   subsystem
      The executable subsystem: gui or console.

Description
   The -s compiler option specifies the executable subsystem. Allowed 
   subsystems are gui and console (by default, console is used). Specifying 
   a gui subsystem prevents the console window from appearing behind the 
   program window.

   The intrinsic macro __FB_GUI__ is set to non-zero (-1) if the option 
   with gui as subsystem was specified, and set to zero (0) otherwise.

Platform Differences
   * Supported on Windows and Cygwin only.

See also
   * __FB_GUI__
   * Using the Command Line



----------------------------------------------- CompilerOptshowincludes ----
Compiler Option: -showincludes

Display a tree of file names of #included files 

Syntax
      -showincludes

Description
   Tells the compiler to display the file names of loaded source code 
   files, in form of a tree structure with indentation. This includes the 
   *.bas files at the toplevel, aswell as the names of #included files as 
   they are being #included. This is intended to be used for debugging 
   #include dependencies, etc.

See also
   * Using the Command Line



----------------------------------------------------- CompilerOptstatic ----
Compiler Option: -static

Prefer static libraries over dynamic ones when linking

Syntax
      -static

Description
   When creating an executable or a shared library/DLL, the -static 
   compiler option can be used to tell the compiler to prefer linking 
   against static libraries rather than shared libraries/DLLs. That way, if 
   the linker finds both static and shared versions of a library, it will 
   use the static version, rather than defaulting to the shared version.

   Installing the proper static libraries and then using -static can be 
   used to avoid some or all dependencies on shared libraries.

Platform Differences
   * On Linux & co it is possible to create purely statically linked 
     executables, because static versions of the system libraries used by 
     FreeBASIC are available.
   * On Windows, there are no static versions of the system libraries, but 
     -static can still be useful to decide between static library or DLL 
     versions of other libraries, if both are installed.

See also
   * Using the Command Line



------------------------------------------------------ CompilerOptstrip ----
Compiler Option: -strip

Omit all symbol information from the output file

Syntax
   -strip

Description
   The -strip compiler option passes an option to the linker to strip 
   (remove) all symbols.

Platform Differences
   * fbc strips all symbols by default on Dos and Windows platforms only

See also
   * -nostrip
   * Using the Command Line



---------------------------------------------------------- CompilerOptt ----
Compiler Option: -t

Set stack size in kilobytes

Syntax
   -t < stack size >

Parameters
   stack size
      Stack size in kilobytes.

Description
   The -t compiler option sets the stack size in kilobytes (defaults to 
   1024 KBytes). The local arrays are created in the stack, so 1MB of stack 
   is not always enough.

Platform Differences
   * Supported on Windows, Cygwin and DOS only.

See also
   * Using the Command Line



----------------------------------------------------- CompilerOpttarget ----
Compiler Option: -target

Set the target platform for cross compilation

Syntax
   -target < platform >

Parameters
   platform
      The target platform. Recognized values:

         * dos
         * win32
         * win64
         * xbox
         * <os>-<arch>
            <os> can be one of:
               * linux
               * cygwin
               * darwin
               * freebsd
               * netbsd
               * openbsd
            <arch> can be one of:
               * x86
               * x86_64
               * arm
               * aarch64
            Examples:
               * linux-x86
               * linux-x86_64
               * linux-arm
               * linux-aarch64
               * freebsd-x86
               * freebsd-x86_64
               * ...
         * For backwards compatibility, the following values are 
           recognized. They will select the corresponding operating system, 
           together with the compiler's default architecture (same as the 
           host), because these values do not specify an architecture 
           explicitly.
            * linux
            * cygwin
            * darwin
            * freebsd
            * netbsd
            * openbsd
         * The Normal fbc (e.g. FB-linux release) additionally recognizes 
           GNU triplets, for example:
            * i686-w64-mingw32
            * x86_64-w64-mingw32
            * i686-pc-linux-gnu
            * arm-linux-gnueabihf
            * ...

Description
   The -target compiler option can be used to create an executable for a 
   platform which is different from the host on which the source code is 
   being compiled and linked. Appropriate libraries and cross compilation 
   tools (assembler, linker) must be installed for cross compilation to 
   work (also see FB and cross-compiling). 

   If -target <platform> is given, the compiler will compile programs more 
   or less as if they were compiled on the given platform. This affects 
   which __FB_*__ operating-system-specific symbol will be pre-defined, the 
   default calling convention, the object and executable file format (e.g. 
   ELF/COFF), the available runtime libraries and functions, etc.

   With a standalone FB setup such as the FB-dos or FB-win32 releases:

      * Specifying -target <platform> causes the compiler to use the 
        compiler tools in the bin/<platform>/ directory, and 
        target-specific libraries in the lib/<platform>/ directory. For 
        example, -target win32 causes the compiler to compile for Win32 and 
        use tools from bin/win32/ and libraries from lib/win32/.

      * It is unnecessary (but safe) to specify a -target option that 
        matches the host (for example -target win32 on win32). It does not 
        make a difference to the compilation process.

      * If -target is not specified, the compiler defaults to compiling 
        for the native system. It will then use the compiler tools and 
        libraries from the bin/ and lib/ directories corresponding to the 
        native system.

   With a normal FB setup such as the FB-linux release:

      * Specifying -target <platform> causes the compiler to prefix the <
        platform>- string to the executable names of binutils and gcc. For 
        example, specifying -target i686-w64-mingw32 causes the compiler to 
        invoke i686-w64-mingw32-ld instead of ld (same for other tools 
        besides the linker). This allows fbc to integrate with binutils/gcc 
        cross-compiler toolchains and matches how cross-compiling tools are 
        typically installed on Linux distributions.

      * Note that specifying something like -target win32 does not usually 
        make sense here. It causes the compiler to try to use win32-ld 
        which usually does not exist, because binutils/gcc toolchains for 
        cross-compilation to Windows typically have names such as 
        i686-pc-mingw32, not just win32. Thus, it is necessary to specify 
        something like -target i686-pc-mingw32 instead of -target win32.

      * For backwards compatibility, if the given platform string 
        describes the host and is an FB target name (the values accepted by 
        the -target option with a standalone FB setup) instead of a GNU 
        triplet, then the -target option will be ignored, and the <platform
        >- string will not be prefixed to compiler tools. For example, this 
        allows -target linux to work with the FB-linux release. It will be 
        ignored instead of causing the compiler to try to use linux-ld 
        instead of ld.

      * If -target is not specified, the compiler defaults to compiling 
        for the native system, and it will invoke binutils/gcc without a 
        target-specific prefix. This allows fbc to integrate with usual 
        Linux (and similar) systems where binutils/gcc for native 
        compilation are installed without any target-specific prefix.

      * Libraries besides FB's own runtime libraries are located by 
        running gcc -print-file-name=... (or <platform>-gcc 
        -print-file-name=...). This allows fbc to use the system and gcc 
        libraries installed on Linux and similar systems without knowing 
        the exact installation directories.

See also
   * Using the Command Line
   * FB and cross-compiling



---------------------------------------------------------- CompilerOptv ----
Compiler Option: -v

Be verbose

Syntax
   -v

Description
   The -v compiler option activates verbose mode. In this mode the compiler 
   shows its actions step by step

See also
   * Using the Command Line



-------------------------------------------------------- CompilerOptvec ----
Compiler Option: -vec

Enables vector optimizations by the compiler.

Syntax
   -vec < level >

Parameters
   level
      The level of vectorization: (0 | NONE) | 1 | 2.

Description
   The -vec compiler option enables multiple levels of optimizations by 
   searching for multiple scalar expressions that can be merged into a 
   single vector expression. If this option is not specified, the default 
   is -vec 0.

   -vec 0 | none will disable vector optimizations.

   -vec 1 will enable complete expression merging vectorization.

   -vec 2 includes -vec 1 but also enables intra-expression vectorization.

   This option is dependent on the -fpu SSE command line option.  
   Attempting to enable vector optimizations without using -fpu SSE will 
   generate an error.

See also
   * Using the Command Line
   * Compiler option -fpu



---------------------------------------------------- CompilerOptversion ----
Compiler Option: -version

Show compiler version

Syntax
   -version

Description
   The -version compiler option makes FBC show the compiler version and 
   exit.  Any other command-line options are ignored, and no compilation 
   will be performed.

See also
   * Using the Command Line



---------------------------------------------------------- CompilerOptw ----
Compiler Option: -w

Set minimum warning level.

Syntax
   -w level | all | none | param | Escape | pedantic | Next | funcptr | 
   constness

Parameters
   level
      Warning messages only with a level equal or greater to this value 
      will be output.  
   all
      Equivalent to specifying a level of negative one (-1).
   none
      Suppresses all warnings.
   param
      Warn when procedure parameters aren't specified with either ByVal or 
      ByRef.
   Escape
      Warn when string literals contain any number of escape characters (\
      ).
   pedantic
      Equivalent to specifying the param and Escape arguments, plus length 
      checking of parameters passed ByVal and of any CPtr converting to 
      pointer only.
   Next
      Warn when Next is followed by an identifier.
   funcptr
      Warn on mismatched procedure pointers, including conversions in Cast 
      and CPtr expressions.  Implies '-w all'. Experimental.  Behaviour may 
      change in future versions.
   constness
      Warn when Const (Qualifier) is discarded in an assignment. Implies 
      '-w funcptr' and '-w all'.  Behaviour may change in future versions.

Description
   The -w compiler option determines which compiler warnings, if any, are 
   output. Each possible warning is associated with a warning level, 
   starting from negative one (-1) and increasing with the potential 
   problems that may occur.

   The param, Escape, pedantic, Next, funcptr, and constness arguments 
   provide additional warnings not ordinarily output, even by default.

   The default, if the -w option is not specified, is as if -w 0 was used. 
   The -w option can be specified multiple times.  Warning messages having 
   a level of -1 are not shown by default.

   -w none, or a significantly high level value will have the effect of 
   suppressing all warning messages. 

See also
   * Using the Command Line



--------------------------------------------------------- CompilerOptWa ----
Compiler Option: -Wa

Pass options to the assembler when using the assembly emitter (-gen gas).

Syntax
   -Wa < options >

Parameters
   options
      Additional options to pass to the assembler.

Description
   The -Wa compiler option passes additional options to GAS, the assembler. 
   Options must be separated by commas only.  The -Wa compiler option may 
   be specified multiple times on the command line.

   For example:
      fbc -Wa -o,output.o,--verbose
      fbc -Wa -o -Wa output.o -Wa --verbose

See also
   * Compiler Option: -gen
   * Compiler Option: -Wc
   * Compiler Option: -Wl
   * Using the Command Line



--------------------------------------------------------- CompilerOptWc ----
Compiler Option: -Wc

Pass options to the C compiler when using the C emitter (-gen gcc).

Syntax
   -Wc < options >

Parameters
   options
      Additional options to pass to the C compiler.

Description
   The -Wc compiler option passes additional options to GCC, the C 
   compiler.  Options must be separated by commas only.   The -Wc compiler 
   option may be specified multiple times on the command line.

   For example:
      fbc -gen gcc -Wc -m32,--verbose,-include,some-header.h
      fbc -gen gcc -Wc -m32 -Wc --verbose -Wc -include -Wc some-header.h

See also
   * Compiler Option: -gen
   * Compiler Option: -Wa
   * Compiler Option: -Wl
   * Using the Command Line



--------------------------------------------------------- CompilerOptWl ----
Compiler Option: -Wl

Pass options to linker

Syntax
   -Wl < options >

Parameters
   options
      Additional options to pass to the linker.

Description
   The -Wl compiler option passes additional options to LD, the linker.  
   Options must be separated by commas only.   The -Wl compiler option may 
   be specified multiple times on the command line.

See also
   * Compiler Option: -Wa
   * Compiler Option: -Wc
   * Using the Command Line



---------------------------------------------------------- CompilerOptx ----
Compiler Option: -x

Set executable/library path/name

Syntax
   -x < name >

Parameters
   name
      Name of the executable or library file.

Description
   The -x compiler option set the executable or library name, with 
   extension. Defaults to the name of the first source file passed on the 
   command line. When compiling libraries, be sure to add the "lib" prefix 
   to the file name, otherwise the linker will not be able to find it. If 
   compiling and linking separately, this option must be set only in the 
   linker.

See also
   * Using the Command Line



---------------------------------------------------------- CompilerOptz ----
Compiler Option: -z

Sets miscellaneous or experimental compiler options.

Syntax
   -z < value >

Parameters
   value
      Miscellaneous compiler option.

Description
   The -z compiler option sets miscellaneous, obscure, temporary, or 
   experimental options used by the developers.  There is no guarantee that 
   these options will be supported in future versions of the compiler.

   -z gosub-setjmp
      Specifies that the setjmp/longjmp implementation of GoSub should be 
      used even when the GAS backend is used.  By default, GoSub will be 
      supported in -gen gas using CALL/RET assembly instructions and in 
      -gen gcc using setjmp/longjmp C runtime functions.

   -z valist-as-ptr
      Specifies that the implementation of Cva_List variable argument lists 
      and macros for variadic procedures should use a normal pointer type 
      if the target supports it.  By default, Cva_List data types are 
      mapped to gcc's __builtin_va_list data type when using -gen gcc.

See also
   * Using the Command Line



------------------------------------------------------- DebuggerRunning ----
Debugging

   The debugger is in the bin\win32 or bin\dos directories (the GDB.EXE 
   file), for the Windows and DOS versions respectively.  It usually comes 
   already installed in most Linux distros.

   (Note: all commands should be typed without quotes and then [return] 
   must be pressed.)

   * Compile the source code for your program in debug mode
      * use the -g command-line option to add debugging support, e.g. fbc 
        -g myapp.bas.

   * Load your compiled program in GDB 
      * For example, in Windows/DOS: gdb myapp.exe

   * Set any arguments you want to send to your application
      * For example: set args arg1 arg2 argn.
      * You can also run GDB and pass the arguments directly to the 
        application been debugged: gdb --args myapp.exe arg1 arg2 arg3.

   * Ensure GDB can see your program's source code directory
      * If the executable isn't in the same directory of the source files 
        where it was compiled, type: dir path/to/my/application/sources.

   * Set a breakpoint in your program
      * Place a breakpoint in the first line using: b main.
      * To place a breakpoint in a function called func use: b FUNC.
      * Note: fbc exports variable/function names to UPPERCASE.  GDB is 
        case sensitive by default, but you can use the set language pascal 
        command to change GDB to case-insensitive mode.

   * Use GDB shortcuts to run your code or to step through it
      * Type r to start running the application.
      * Type n to step to the next line, stepping over function calls.
      * Keep pressing [return] to step forward to the next line.
      * Type s to step into function calls.
      * As above, keep pressing [return] to step through.
      * Type c to continue execution until the next breakpoint.

   * Use GDB shortcuts to inspect variables
      * Use print VAR_NAME to show the contents of the variable called 
        var_name.
         * GDB supports pointer/pointer field dereferencing, indexing and 
           arithmetics too, so print *MYPOINTER will also work.
         * (note: undeclared variables or the ones with suffixes like % & 
           ! # $ can't be printed).
      * Use disp VAR_NAME to display the contents of a variable called 
        var_name.
      * Use watch VAR_NAME to stop each time a variable called var_name is 
        changed.

   * Additional commands:
      * Use r again to restart the application when it finishes.
      * Type q to quit.
      * Type help to see a list of commands, there are many others.



-------------------------------------------------------- CompilerErrMsg ----
Compiler Error Messages

During the program compilation three types of errors can arise:

Compiler Warnings:
   The warnings don't stop the compilation, just alert the user some 
   non-recommended and error-prone operation is attempted in the code. 
   Sometimes one of these operations is coded deliberately to achieve a 
   result, in this case the warnings can be disabled by setting  the -w 1 
   option at the command line.

   * 1 Passing scalar as pointer
   * 2 Passing pointer to scalar
   * 3 Passing different pointer types
   * 4 Suspicious pointer assignment
   * 5 Implicit conversion
   * 6 Cannot export symbol without -export option
   * 7 Identifier's name too big, truncated
   * 8 Literal number too big, truncated
   * 9 Literal string too big, truncated
   * 10 UDT with pointer, var-len string, or var-len array fields
   * 11 Implicit variable allocation
   * 12 Missing closing quote in literal string
   * 13 Function result was not explicitly set
   * 14 Branch crossing local variable definition
   * 15 No explicit BYREF or BYVAL
   * 16 Possible escape sequence found in
   * 17 The type length is too large, consider passing BYREF
   * 18 The length of the parameters list is too large, consider passing 
     UDT's BYREF
   * 19 The ANY initializer has no effect on UDT's with default 
     constructors
   * 20 Object files or libraries with mixed multithreading (-mt) options
   * 21 Object files or libraries with mixed language (-lang) options
   * 22 Deleting ANY pointers is undefined
   * 23 Array too large for stack, consider making it var-len or SHARED
   * 24 Variable too large for stack, consider making it SHARED
   * 25 Overflow in constant conversion
   * 26 Variable following NEXT is meaningless
   * 27 Cast to non-pointer
   * 28 Return method mismatch
   * 29 Passing Pointer
   * 30 Command line option overrides directive
   * 31 Directive ignored after first pass
   * 32 'IF' statement found directly after multi-line 'ELSE'
   * 33 Shift value greater than or equal to number of bits in data type
   * 34 '=' parsed as equality operator in function argument, not 
     assignment to BYREF function result
   * 35 Mixing signed/unsigned operands
   * 36 Mismatching parameter initializer
   * 37 Ambiguous LEN or SIZEOF
   * 38 Suspicious logic operation, mixed boolean and non-boolean operands
   * 39 Redefinition of intrinsic
   * 40 CONST qualifier discarded
   * 41 Return type mismatch
   * 42 Calling convention mismatch
   * 43 Argument count mismatch

Compiler Error messages:
   The error messages stop the compilation after 10 errors (see the -maxerr 
   command-line option to change that default value) or a fatal error 
   occurred, and require a correction by the user before the compilation 
   can be continued. The compiler signals the lines where the errors have 
   been found, so the correction can be done quickly. In a few cases the 
   place pointed at by the error messages is not where the errors can be 
   found, it's the place where the compiler has given up in waiting for 
   something that should be somewhere.

   * 1 Argument count mismatch
   * 2 Expected End-of-File
   * 3 Expected End-of-Line
   * 4 Duplicated definition
   * 5 Expected 'AS'
   * 6 Expected '('
   * 7 Expected ')'
   * 8 Undefined symbol
   * 9 Expected expression
   * 10 Expected '='
   * 11 Expected constant
   * 12 Expected 'TO'
   * 13 Expected 'NEXT'
   * 14 Expected identifier
   * 15 Expected '-'
   * 16 Expected ','
   * 17 Syntax error
   * 18 Element not defined
   * 19 Expected 'END TYPE' or 'END UNION'
   * 20 Type mismatch
   * 21 Internal!
   * 22 Parameter type mismatch
   * 23 File not found
   * 24 Invalid data types
   * 25 Invalid character
   * 26 File access error
   * 27 Recursion level too deep
   * 28 Expected pointer
   * 29 Expected 'LOOP'
   * 30 Expected 'WEND'
   * 31 Expected 'THEN'
   * 32 Expected 'END IF'
   * 33 Illegal 'END'
   * 34 Expected 'CASE'
   * 35 Expected 'END SELECT'
   * 36 Wrong number of dimensions
   * 37 Array boundaries do not match the original EXTERN declaration
   * 38 'SUB' or 'FUNCTION' without 'END SUB' or 'END FUNCTION'
   * 39 Expected 'END SUB' or 'END FUNCTION'
   * 40 Return type here does not match DECLARE prototype
   * 41 Calling convention does not match DECLARE prototype
   * 42 Variable not declared
   * 43 Variable required
   * 44 Illegal outside a compound statement
   * 45 Expected 'END ASM'
   * 46 Function not declared
   * 47 Expected ';'
   * 48 Undefined label
   * 49 Too many array dimensions
   * 50 Array too big
   * 51 User Defined Type too big
   * 52 Expected scalar counter
   * 53 Illegal outside a CONSTRUCTOR, DESTRUCTOR, FUNCTION, OPERATOR, 
     PROPERTY or SUB block
   * 54 Expected var-len array
   * 55 Fixed-len strings cannot be returned from functions
   * 56 Array already dimensioned
   * 57 Illegal without the -ex option
   * 58 Type mismatch
   * 59 Illegal specification
   * 60 Expected 'END WITH'
   * 61 Illegal inside functions
   * 62 Statement in between SELECT and first CASE
   * 63 Expected array
   * 64 Expected '{'
   * 65 Expected '}'
   * 66 Expected ']'
   * 67 Too many expressions
   * 68 Expected explicit result type
   * 69 Range too large
   * 70 Forward references not allowed
   * 71 Incomplete type
   * 72 Array not dimensioned
   * 73 Array access, index expected
   * 74 Expected 'END ENUM'
   * 75 Var-len arrays cannot be initialized
   * 76 '...' ellipsis upper bound given for dynamic array (this is not 
     supported)
   * 77 '...' ellipsis upper bound given for array field (this is not 
     supported)
   * 78 Invalid bitfield
   * 79 Too many parameters
   * 80 Macro text too long
   * 81 Invalid command-line option
   * 82 Selected non-x86 CPU when compiling for DOS
   * 83 Selected -gen gas ASM backend for non-x86 CPU
   * 84 -asm att used for -gen gas, but -gen gas only supports -asm intel
   * 85 -pic used when making executable (only works when making a shared 
     library)
   * 86 -pic used, but not supported by target system (only works for 
     non-x86 Unixes)
   * 87 Var-len strings cannot be initialized
   * 88 Recursive TYPE or UNION not allowed
   * 89 Recursive DEFINE not allowed
   * 90 Identifier cannot include periods
   * 91 Executable not found
   * 92 Array out-of-bounds
   * 93 Missing command-line option for
   * 94 Expected 'ANY'
   * 95 Expected 'END SCOPE'
   * 96 Illegal inside a compound statement or scoped block
   * 97 UDT function results cannot be passed by reference
   * 98 Ambiguous call to overloaded function
   * 99 No matching overloaded function
   * 100 Division by zero
   * 101 Cannot pop stack, underflow
   * 102 UDT's containing var-len string fields cannot be initialized
   * 103 Branching to scope block containing local variables
   * 104 Branching to other functions or to module-level
   * 105 Branch crossing local array, var-len string or object definition
   * 106 LOOP without DO
   * 107 NEXT without FOR
   * 108 WEND without WHILE
   * 109 END WITH without WITH
   * 110 END IF without IF
   * 111 END SELECT without SELECT
   * 112 END SUB or FUNCTION without SUB or FUNCTION
   * 113 END SCOPE without SCOPE
   * 114 END NAMESPACE without NAMESPACE
   * 115 END EXTERN without EXTERN
   * 116 ELSEIF without IF
   * 117 ELSE without IF
   * 118 CASE without SELECT
   * 119 Cannot modify a constant
   * 120 Expected period ('.')
   * 121 Expected 'END NAMESPACE'
   * 122 Illegal inside a NAMESPACE block
   * 123 Symbols defined inside namespaces cannot be removed
   * 124 Expected 'END EXTERN'
   * 125 Expected 'END SUB'
   * 126 Expected 'END FUNCTION'
   * 127 Expected 'END CONSTRUCTOR'
   * 128 Expected 'END DESTRUCTOR'
   * 129 Expected 'END OPERATOR'
   * 130 Expected 'END PROPERTY'
   * 131 Declaration outside the original namespace
   * 132 No end of multi-line comment, expected "'/"
   * 133 Too many errors, exiting
   * 134 Expected 'ENDMACRO'
   * 135 EXTERN or COMMON variables cannot be initialized
   * 136 EXTERN or COMMON dynamic arrays cannot have initial bounds
   * 137 At least one parameter must be a user-defined type
   * 138 Parameter or result must be a user-defined type
   * 139 Both parameters can't be of the same type
   * 140 Parameter and result can't be of the same type
   * 141 Invalid result type for this operator
   * 142 Invalid parameter type, it must be the same as the parent 
     TYPE/CLASS
   * 143 Vararg parameters are not allowed in overloaded functions
   * 144 Illegal outside an OPERATOR block
   * 145 Parameter cannot be optional
   * 146 Only valid in -lang
   * 147 Default types or suffixes are only valid in -lang
   * 148 Suffixes are only valid in -lang
   * 149 Implicit variables are only valid in -lang
   * 150 Auto variables are only valid in -lang
   * 151 Invalid array index
   * 152 Operator must be a member function
   * 153 Operator cannot be a member function
   * 154 Method declared in anonymous UDT
   * 155 Constant declared in anonymous UDT
   * 156 Static variable declared in anonymous UDT
   * 157 Expected operator
   * 158 Declaration outside the original namespace or class
   * 159 A destructor should not have any parameters
   * 160 Expected class or UDT identifier
   * 161 Var-len strings cannot be part of UNION's or nested TYPE's
   * 162 Dynamic arrays cannot be part of UNION's or nested TYPE's
   * 163 Fields with constructors cannot be part of UNION's or nested 
     TYPE's
   * 164 Fields with destructors cannot be part of UNION's or nested 
     TYPE's
   * 165 Illegal outside a CONSTRUCTOR block
   * 166 Illegal outside a DESTRUCTOR block
   * 167 UDT's with methods must have unique names
   * 168 Parent is not a class or UDT
   * 169 CONSTRUCTOR() chain call not at top of constructor
   * 170 BASE() initializer not at top of constructor
   * 171 REDIM on UDT with non-CDECL constructor
   * 172 REDIM on UDT with non-CDECL destructor
   * 173 REDIM on UDT with non-parameterless default constructor
   * 174 ERASE on UDT with non-CDECL constructor
   * 175 ERASE on UDT with non-CDECL destructor
   * 176 ERASE on UDT with non-parameterless default constructor
   * 177 This symbol cannot be undefined
   * 178 RETURN mixed with 'FUNCTION =' or EXIT FUNCTION (using both 
     styles together is unsupported when returning objects with 
     constructors)
   * 179 'FUNCTION =' or EXIT FUNCTION mixed with RETURN (using both 
     styles together is unsupported when returning objects with 
     constructors)
   * 180 Missing RETURN to copy-construct function result
   * 181 Invalid assignment/conversion
   * 182 Invalid array subscript
   * 183 TYPE or CLASS has no default constructor
   * 184 Function result TYPE has no default constructor
   * 185 Missing BASE() initializer (base UDT without default constructor 
     requires manual initialization)
   * 186 Missing default constructor implementation (base UDT without 
     default constructor requires manual initialization)
   * 187 Missing UDT.constructor(byref as UDT) implementation (base UDT 
     without default constructor requires manual initialization)
   * 188 Missing UDT.constructor(byref as const UDT) implementation (base 
     UDT without default constructor requires manual initialization)
   * 189 Invalid priority attribute
   * 190 PROPERTY GET should have no parameter, or just one if indexed
   * 191 PROPERTY SET should have one parameter, or just two if indexed
   * 192 Expected 'PROPERTY'
   * 193 Illegal outside a PROPERTY block
   * 194 PROPERTY has no GET method/accessor
   * 195 PROPERTY has no SET method/accessor
   * 196 PROPERTY has no indexed GET method/accessor
   * 197 PROPERTY has no indexed SET method/accessor
   * 198 Missing overloaded operator: 
   * 199 The NEW[] operator does not allow explicit calls to constructors
   * 200 The NEW[] operator only supports the { ANY } initialization
   * 201 The NEW operator cannot be used with fixed-length strings
   * 202 Illegal member access
   * 203 Expected ':'
   * 204 The default constructor has no public access
   * 205 Constructor has no public access
   * 206 Destructor has no public access
   * 207 Accessing base UDT's private default constructor
   * 208 Accessing base UDT's private destructor
   * 209 Illegal non-static member access
   * 210 Constructor declared ABSTRACT
   * 211 Constructor declared VIRTUAL
   * 212 Destructor declared ABSTRACT
   * 213 Member cannot be static
   * 214 Member isn't static
   * 215 Only static members can be accessed from static functions
   * 216 The PRIVATE and PUBLIC attributes are not allowed with REDIM, 
     COMMON or EXTERN
   * 217 STATIC used here, but not the in the DECLARE statement
   * 218 CONST used here, but not the in the DECLARE statement
   * 219 VIRTUAL used here, but not the in the DECLARE statement
   * 220 ABSTRACT used here, but not the in the DECLARE statement
   * 221 Method declared VIRTUAL, but UDT does not extend OBJECT
   * 222 Method declared ABSTRACT, but UDT does not extend OBJECT
   * 223 Not overriding any virtual method
   * 224 Implemented body for an ABSTRACT method
   * 225 Override has different return type than overridden method
   * 226 Override has different calling convention than overridden method
   * 227 Implicit destructor override would have different calling 
     convention
   * 228 Implicit LET operator override would have different calling 
     convention
   * 229 Override is not a CONST member like the overridden method
   * 230 Override is a CONST member, but the overridden method is not
   * 231 Override has different parameters than overridden method
   * 232 This operator cannot be STATIC
   * 233 This operator is implicitly STATIC and cannot be VIRTUAL or 
     ABSTRACT
   * 234 This operator is implicitly STATIC and cannot be CONST
   * 235 Parameter must be an integer
   * 236 Parameter must be a pointer
   * 237 Expected initializer
   * 238 Fields cannot be named as keywords in TYPE's that contain member 
     functions or in CLASS'es
   * 239 Illegal outside a FOR compound statement
   * 240 Illegal outside a DO compound statement
   * 241 Illegal outside a WHILE compound statement
   * 242 Illegal outside a SELECT compound statement
   * 243 Expected 'FOR'
   * 244 Expected 'DO'
   * 245 Expected 'WHILE'
   * 246 Expected 'SELECT'
   * 247 No outer FOR compound statement found
   * 248 No outer DO compound statement found
   * 249 No outer WHILE compound statement found
   * 250 No outer SELECT compound statement found
   * 251 Expected 'CONSTRUCTOR', 'DESTRUCTOR', 'DO', 'FOR', 'FUNCTION', 
     'OPERATOR', 'PROPERTY', 'SELECT', 'SUB' or 'WHILE'
   * 252 Expected 'DO', 'FOR' or 'WHILE'
   * 253 Illegal outside a SUB block
   * 254 Illegal outside a FUNCTION block
   * 255 Ambiguous symbol access, explicit scope resolution required
   * 256 An ENUM, TYPE or UNION cannot be empty
   * 257 ENUM's declared inside EXTERN .. END EXTERN blocks don't open new 
     scopes
   * 258 STATIC used on non-member procedure
   * 259 CONST used on non-member procedure
   * 260 ABSTRACT used on non-member procedure
   * 261 VIRTUAL used on non-member procedure
   * 262 Invalid initializer
   * 263 Objects with default [con|de]structors or methods are only 
     allowed in the module level
   * 264 Static member variable in nested UDT (only allowed in toplevel 
     UDTs)
   * 265 Symbol not a CLASS, ENUM, TYPE or UNION type
   * 266 Too many elements
   * 267 Only data members supported
   * 268 UNIONs are not allowed
   * 269 Arrays are not allowed
   * 270 COMMON variables cannot be object instances of CLASS/TYPE's with 
     cons/destructors
   * 271 Cloning operators (LET, Copy constructors) can't take a byval arg 
     of the parent's type
   * 272 Local symbols can't be referenced
   * 273 Expected 'PTR' or 'POINTER'
   * 274 Too many levels of pointer indirection
   * 275 Dynamic arrays can't be const
   * 276 Const UDT cannot invoke non-const method
   * 277 Elements must be empty for strings and arrays
   * 278 GOSUB disabled, use 'OPTION GOSUB' to enable
   * 279 Invalid -lang
   * 280 Can't use ANY as initializer in array with ellipsis bound
   * 281 Must have initializer with array with ellipsis bound
   * 282 Can't use ... as lower bound
   * 283 FOR/NEXT variable name mismatch
   * 284 Selected option requires an SSE FPU mode
   * 285 Expected relational operator ( =, >, <, <>, <=, >= )
   * 286 Unsupported statement in -gen gcc mode
   * 287 Too many labels
   * 288 Unsupported function
   * 289 Expected sub
   * 290 Expected '#ENDIF'
   * 291 Resource file given for target system that does not support them
   * 292 -o <file> option without corresponding input file
   * 293 Not extending a TYPE/UNION (a TYPE/UNION can only extend other 
     TYPEs/UNIONs)
   * 294 Illegal outside a CLASS, TYPE or UNION method
   * 295 CLASS, TYPE or UNION not derived
   * 296 CLASS, TYPE or UNION has no constructor
   * 297 Symbol type has no Run-Time Type Info (RTTI)
   * 298 Types have no hierarchical relation
   * 299 Expected a CLASS, TYPE or UNION symbol type
   * 300 Casting derived UDT pointer from incompatible pointer type
   * 301 Casting derived UDT pointer from unrelated UDT pointer type
   * 302 Casting derived UDT pointer to incompatible pointer type
   * 303 Casting derived UDT pointer to unrelated UDT pointer type
   * 304 ALIAS name string is empty
   * 305 LIB name string is empty
   * 306 UDT has unimplemented abstract methods
   * 307 Non-virtual call to ABSTRACT method
   * 308 #ASSERT condition failed
   * 309 Expected '>'
   * 310 Invalid size
   * 311 ALIAS name here does not match ALIAS given in DECLARE prototype
   * 312 vararg parameters are only allowed in CDECL procedures
   * 313 the first parameter in a procedure may not be vararg
   * 314 CONST used on constructor (not needed)
   * 315 CONST used on destructor (not needed)
   * 316 Byref function result not set
   * 317 Function result assignment outside of the function
   * 318 Type mismatch in byref function result assignment
   * 319 -asm att|intel option given, but not supported for this target 
     (only x86 or x86_64)
   * 320 Reference not initialized
   * 321 Incompatible reference initializer
   * 322 Array of references - not supported yet
   * 323 Invalid CASE range, start value is greater than the end value
   * 324 Fixed-length string combined with BYREF (not supported)

Third party programs errors
   These errors occur after the source has been compiled into assembler, 
   they come from the auxiliary programs FB requires to compile a source 
   into an executable: the linker, the assembler and (for Windows programs) 
   the resource compiler.

   If an IDE or a make utility are been used, additional errors can arise. 
   These errors are outside the scope of this help.



--------------------------------------------------------- CompilerTools ----
Tools used by fbc

External tools the FreeBASIC compiler (fbc) may invoke during the 
compilation process.

Description
   FreeBASIC uses several tools for compiling source code in addition to 
   the fbc compiler.  The exact tools used by fbc and how they are invoked 
   depends on how fbc was configured, the host platform (where fbc is 
   running), the target platform (where the produced executable will be 
   run), and other options (like environment variables and command line 
   options).

   FreeBASIC (fbc) may have been configured in one of two ways: either as 
   standalone or prefixed.  The standalone version searches directories 
   relative to where the executable is located.  The prefixed version has a 
   hardcoded path configured in to the compiler indicating where it expects 
   to find additional tools and libraries.  For more information on 
   configuring FreeBASIC, see the INSTALL text file located in the 
   src/compiler directory of the FreeBASIC sources.

   You can check if your installed version of fbc is "standalone" or 
   "prefixed" by invoking fbc with the -version command line option.

Standalone
   If fbc was configured as "standalone", it will search for files relative 
   to where the fbc executable is located.  fbc is at the "top" of the 
   directory tree and searches sub-directories below it.  The "top" 
   directory (which defaults to the location where fbc is located) can be 
   overridden with the -prefix command line option.  "topdir" shown in the 
   directories below represents the directory where the fbc executable is 
   located, or the directory specified with the -prefix command line option 
   (if it was given). "<target>" refers to the target platform having the 
   same name as specified by the -target option.

   If not cross compiling, fbc looks in these locations: 
      * /topdir/inc
      * /topdir/lib/<target>
      * /topdir/bin/<target>
      * gcc is queried for missing libraries (currently on linux/freebsd 
        only) 

   If cross compiling, fbc looks in the these locations: 
      * /topdir/inc
      * /topdir/lib/<target>
      * /topdir/bin/<target>
      * gcc is not queried (only target library directory is used)

Prefixed
   If fbc was configured as "prefixed", it will search for files relative 
   to the configured prefix (hardcoded in the fbc executable).  "prefix" 
   shown in the directories below represents the configured prefix, or the 
   directory specified with the -prefix command line option (if it was 
   given).  "<target>" refers to the target platform having the same name 
   as specified by the -target option.

   If not cross compiling, fbc looks in these locations: 
      * /prefix/include/freebasic
      * /prefix/lib/freebasic/<target>
      * /prefix/bin/freebasic/<target>
      * gcc is queried for missing libraries (currently on linux/freebsd 
        only) 

   If cross compiling, fbc looks in the these locations: 
      * /prefix/include/freebasic
      * /prefix/lib/freebasic/<target>
      * /prefix/bin/freebasic/<target>
      * gcc is not queried (only target library directory is used)

GCC Queries
   If fbc is unable to locate a file, it may invoke gcc -print-file-name=<
   file> to query the location of the file.  The following are files that 
   may be located using gcc:
      * crt1.o
      * crtbegin.o
      * crtend.o
      * crti.o
      * crtn.o
      * gcrt1.o
      * libgcc.a
      * libsupc++.a
      * libc.so (Linux only)

Finding Binaries
   fbc will invoke additional tools (binary executables) as part of the 
   compiling and linking process.  The following is a list of tools 
   (executables) that may be invoked by fbc depending on the host platform, 
   target, or type of executable or library to be produced:
      * as
      * ar
      * ld
      * gcc
      * GoRC
      * dlltool
      * pexports
      * cxbe

   fbc will search for these tools in the following manner:
      * If an environment variable (having same name as the tool without 
        any extension, all in uppercase) has been set, it explicitly 
        indicates the path and name of the executable to be invoked.
      * If the file (or a symlink) exists in prefix/bin/freebasic/<target>
        , or ./bin/<target> for the standalone version, then use it.
      * On Linux, if the tool could not be found in prefix/bin/freebasic/<
        target>, or ./bin/<target> for the standalone version, fbc tries to 
        invoke it anyway as it may be installed on the system and located 
        on the PATH.

   "<target>" refers to the target platform having the same name as 
   specified by the -target option.

See also
   * Running FreeBASIC
   * Compiler Command Line Options
   * Compiler FAQ



------------------------------------------------- CompilerInstallingGcc ----
Installing gcc for -gen gcc

Windows 32bit

If you are using the FreeBASIC-x.xx.x-win32 package, you can use our 
pre-made gcc package. Download gcc-x.x.x-for-FB-win32-gengcc.zip from the 
Binaries - Windows/More/ directory at the fbc downloads area, and extract 
it into the FreeBASIC installation directory (where fbc.exe is), such that g
cc.exe and cc1.exe will be placed in these locations:

   * bin\win32\gcc.exe
   * bin\libexec\gcc\i686-w64-mingw32\x.x.x\cc1.exe

You can also download Win32 versions of gcc directly from the MinGW.org or 
MinGW-w64 projects.

Windows 64bit

The FreeBASIC-x.xx.x-win64 package already comes with gcc included, and 
uses -gen gcc by default (because -gen gas does not support 64bit).

DOS

It requires a (minimal) DJGPP installation. DJGPP can be downloaded from 
the DJGPP website. At least the djdev*.zip and gcc*b.zip are needed. In 
order to run the DJGPP gcc, the DJGPP environment variable must be set to 
point to the djgpp.env file.

To use the DJGPP gcc with the FreeBASIC-x.xx.x-dos package, copy gcc.exe 
and cc1.exe into the FreeBASIC installation directory, such that they will 
be placed in these locations:

   * bin\dos\gcc.exe
   * bin\libexec\gcc\djgpp\x.xx\cc1.exe

Linux

Typically the gcc package is already installed, or it can be installed by 
doing something like:
   sudo apt-get install gcc
(the exact command depends on your GNU/Linux distribution)

Non-standalone fbc installed into DJGPP/MinGW toolchains

If you are using a non-standalone version of fbc (e.g. from one of the 
fbc-x.xx.x-win32 packages), and have it installed inside a DJGPP or MinGW 
toolchain, then -gen gcc should already work, as the DJGPP or MinGW 
toolchains provide gcc.

As long as gcc.exe is in the same directory as fbc.exe (typically 
C:\DJGPP\bin\ or C:\MinGW\bin\), or available in the PATH environment 
variable, fbc.exe should be able to find and use it.

See also
   * -gen <backend>





============================================================================
  FREEBASIC DIALECTS AND QBASIC
  -----------------------------


------------------------------------------------------------ CompilerQB ----
FreeBASIC and QBasic

FreeBASIC the Successor
   FreeBASIC is designed as an official successor of sorts to a high level 
   compiler for MS-DOS titled "QuickBASIC", which compiled BASIC code, an 
   easy-to-read programming language created in 1964 by John Kemeny and 
   Thomas Kurtz.  "QB" was packaged with a user-friendly IDE and 
   interpreter that made it very easy to write custom applications.  This 
   line of products is officially continued today in the form of "Visual 
   Basic", part of Microsoft's Visual Studio .NET programming suite.

Microsoft and BASIC Products
   Microsoft and BASIC extend far prior to QuickBASIC.  In fact, 
   Microsoft's first product was a small BASIC interpreter for Altair 
   computers released in 1975, and until the early 1980s Microsoft was 
   known only as a language vendor.  They ported their BASIC software to 
   several different personal computers at the time and made decent 
   business doing it.

   In August of 1981 Microsoft released the next major step in its BASIC 
   line, "Advanced BASIC", as part of a commission for IBM's PC-DOS, and is 
   more often called by its executable name, BASICA.EXE.  For Microsoft's 
   new MS-DOS, they released GW-BASIC, which was, for the most part, a port 
   of BASICA that did not require IBM's Basic ROM included with its 
   systems.

   BASICA and GW-BASIC are interpreters.  Interpreters read source code and 
   "interpret" it into computer code as it is read.  This is useful, but 
   slow.  Microsoft, in 1983, released BASCOM for MS-DOS.  BASCOM compiled 
   BASIC code into native machine code, which ran much faster than 
   interpreted code.  This was repackaged with an IDE and released as 
   QuickBASIC in 1985.

QuickBASIC
   From 1985 to 1992, QuickBASIC was the primary BASIC product, released by 
   Microsoft and using BASCOM, and later the Microsoft BASIC Compiler.  In 
   1991, a slimmed down interpreter often thought to be the missing 
   "QuickBASIC 5.0" was packaged with MS-DOS 5.0 and released as "QBasic 
   1.1".

   QuickBASIC as a BASIC dialect provides a loose standard for modern BASIC 
   compilers.  It abolishes the need for line numbers as a used in previous 
   BASIC interpreters, is case sensitive and has keywords that are in plain 
   English.  QuickBASIC also featured a runtime library, a library compiled 
   by default and usable in source code, with many useful commands.

   In 1991, Microsoft combined a drag-and-drop GUI designer made in 1988 
   called 'Ruby' with QuickBASIC.  This product was called "Visual Basic", 
   and marks the beginning of the end of QuickBASIC.  Microsoft released 
   one last version of QuickBASIC called "Visual Basic for DOS" in 1992, 
   and discontinued the product forever.

The Internet and QBasic's Second Wind
   Because the "QBasic 1.1" interpreter was packaged with MS-DOS, it was 
   released with every copy of DOS until its dying days, Windows 3.1, and 
   even Windows 95, 98 and ME.  With the wild success of Windows, QBasic 
   became the most widely available programming tool available for 
   Microsoft operating systems.  

   When the World Wide Web became popular in the mid-90s, many hobbyist 
   programmers made websites dedicated to QuickBASIC not as an application 
   tool, but as a platform for their demos and games.  Many assembly 
   libraries were created for it after Microsoft dropped support, and as 
   these demos and games became more elaborate, so did the "QB Community".  
   From the mid-90s, through the new millennium to today, QuickBASIC has 
   enjoyed a small but present cult following.  

   Andre Victor, FreeBASIC's creator, was first known over the internet as 
   the author of several extensions to QuickBASIC in the form of libraries. 
   He created routines to improve the speed of floating point operations, 
   access the internet, use SVGA graphics, and provide powerful QBasic 
   language programming features.  In the late summer of 2004, he began 
   work on a 32-bit compiler using Visual Basic for DOS.

FreeBASIC is Born
   FreeBASIC was first programmed in VB-DOS, with the goal of compiling 
   itself.  Because of this, both its syntax and runtime library are 
   designed to emulate QB's syntax and runtime as far as it is practical in 
   a 32-bit Windows environment.  For the most part, the two dialects are 
   extremely similar, and most code can be ported with little or no 
   modification, though in some cases routines reliant on 16-bit DOS must 
   be rewritten.  The resulting compiler shares a greater similarity to QB 
   than any compiler on the market, including Visual Basic.

   Because of its open source, its well-written code and its similarity to 
   QB, FreeBASIC has become popular among the "QB Community" and its 
   boundaries continue to grow as it receives more attention and gathers 
   more features that promise to move BASIC into the future.



---------------------------------------------------------------- LangQB ----
Differences from QB

FreeBASIC introduced a -lang command-line option, that is used to change 
the language compatibility mode. Use the -lang qb option when compiling to 
select the most QB compatible parser. All differences listed below assume 
that -lang qb was used.

Architecture/Platform incompatibilities
   * FreeBASIC is written for 32-bit operating systems and a 32 bit DOS 
     extender, and cannot utilize code which depends on 16-bit DOS, 16 bit 
     assembly or memory model (segment & offset, XMS/EMS, ...). 	
   * DEF SEG is no longer necessary and will not work - any code which 
     POKEs to video memory this way will no longer function, however, for 
     DOS it can be easily rewritten using DPMI features. 
   * CALL INTERRUPT no longer functions, as it relies on 16-bit DOS. DOS 
     interrupts can be called in the DOS32 version by using the DPMI 
     library, but they might work slowly because of the 32bit-16bit-32bit  
     mode changes the processor will have to perform. 

Changed due to ambiguity
   * A scalar variable and an array with the same name and suffix can no 
     longer share the same name.
   * SHARED can't be used inside a SUB or FUNCTION as it resulted in 
     shared variables not defined in the main program. A proper DIM SHARED 
     in the main program must be used.
   * COMMON declarations do not depend on the order they are made, 
     variables are matched by name and for that reason named COMMON is no 
     longer supported. All COMMON arrays are variable-length arrays in FB.
   * If a single line If has an (unnecessary) colon directly after the 
     THEN, it has to be terminated by an End If in FB. If that unneeded 
     colon is removed, FB will behave as QB.

Design differences
   * Graphics support was internally redesigned, see GfxLib overview
   * CLEAR is no longer used to reset all variables and set the stack. 
     Variables must be reset one by one, and stack size can be changed in 
     the compiler command line. The keyword CLEAR is used to do memory 
     fills in FB.
   * String DATA items must be enclosed in quotes in FB, in QB this was 
     optional
   * All functions must have been declared, even with a CALL in FreeBASIC. 
     With CALL it was possible to invoke prototype-less functions in 
     QuickBASIC. (to be supported in future with -lang qb)
   * In FreeBASIC all arrays must be explicitly declared. (Interpreted 
     QuickBASIC arrays are automatically created with up to 10 indices.)
   * Strings use a null (char 0) terminator to be compatible with C 
     libraries and the Windows API, fixed-length strings can't contain 
     chr$(0) chars for now.
   * When INKEY[$] reads an extended key (Num Pad, Arrows...) it returns a 
     two character string. In FB the first character is CHR[$](255), while 
     in QB this first char is CHR$(0). 
   * With fixed length strings FreeBASIC gives the real length as Len plus 
     one (null-char), even on Type fields.
   * In FreeBASIC, unused characters of fixed-length strings are set to 0, 
     regardless of what "-lang" compiler option is used. In QB, unused 
     characters are set to 32 (space, or " ", in ASCII).
   * When a fixed-length string is declared, but still not initialized, 
     all characters are set to 0, both in FreeBASIC and QB.
   * The arrays are stored in row-major order in FB, they were stored in 
     column-major order in QB by default. Row major order: data with 
     consecutive last index are contiguous. Column-major order: data with 
     consecutive first index are contiguous.  For example, if you have DIM 
     A(1 TO 6, 1 TO 8), in row-major order the elements are stored such 
     that A(3,5) is followed in memory by A(3,6); in column-major order 
     A(3,5) is followed in memory by A(4,5).
   * Programs don't stop anymore on runtime errors unless -e, -ex or -exx 
     option is used in the command line. Using these options allow the use 
     of QB style error handling (ON ERROR, RESUME...).
   * Octal numbers are written &o..., whereas in QB they could be written 
     as &o... or &....
   * In FB FOR loops in subs/functions do not accept arguments received 
     byref as counters. A local variable must be used. 
   * FB's Locate does not respect the fourth and fifth arguments for 
     cursor shape.
   * FB's Screen does not allow switching the visible or the work-page. 
     Use ScreenSet instead.
   * FB's Color does not allow a third argument for border color.
   * FB's Timer returns the number of seconds since the computer started, 
     while QB's TIMER returns the number of seconds since midnight. (Win32 
     and Linux only: No more wrapping at midnight! :))
   * In QB a chr$(13) inside a string did a CR+LF when PRINTed. In FB the 
     CHR(13) prints just at what it is, a CR.
   * EOF can no longer be used to detect an empty comms buffer. Empty 
     buffer should be tested comparing Loc with 0 in FB. Also, for files 
     opened in RANDOM or BINARY mode, EOF returns non-zero already after 
     reading exactly the file size, see EOF.
   * Integer variables do not signal overflow errors in FB, even with the 
     -ex or -exx option on. Any QB code relying in catching integer 
     overflow errors will not work in FB. 

Archaic commands
   * BSAVE and BLOAD can be used in FB only to save and retrieve screens 
     or graphic buffers. They will work only if gfxlib is linked, this is,  
     if a graphics screen mode is requested somewhere in the program. The 
     console can't be saved with BSAVE or retrieved with BLOAD. The other 
     use of BSAVE-BLOAD, saving and loading full arrays, can be achieved 
     easily with GET and PUT.
   * FIELD statement (for record definition at runtime) has been left 
     aside. The keyword FIELD is used in FB to specify field alignment in 
     Type variables.
   * PC Speaker commands no longer function: Any references to SOUND or 
     PLAY statements will result in an error message. There is a third 
     party library available to emulate this functionality, but it's not 
     included with FreeBASIC.
   * Fake event-driven programming (ON KEY, ON PEN, ON STRIG, ON TIMER) no 
     longer works. They could be emulated by a separate library.
   * MKSMBF$ and all the MKxMBF$ commands supporting the pre-QB4.0 
     Microsoft proprietary floating point format (MBF) are not implemented.
   * The use of parenthesis in the arguments passed to a function to 
     emulate by-value passing is not permitted. The CALL quirk resulting in 
     all arguments being passed by value, no longer works. The proper ByVal 
     and ByRef keywords must be used.
   * FILES is not implemented. Instead, PDS 7.1-compatible Dir[$] can be 
     used.
   * IOCTL, ERRDEV and ERRDEV$, low level functions to access hardware are 
     not implemented as they were OS-dependent. 
   * CALL ABSOLUTE to run inline machine code is no longer supported. 
     Instead you can use Asm...END ASM blocks to insert inline assembler 
     commands. Or use the ASM ... one line command.



------------------------------------------------------ CompilerDialects ----
FreeBASIC Dialects

   FreeBASIC version 0.17b introduces a -lang command-line option, used to 
   change the language compatibility mode for different dialects of the 
   basic language.

   Starting with version 0.18.3b the -lang qb dialect has been further 
   restricted to only allow what would have been allowed in QuickBASIC.

   In version 0.18.4b the -lang fblite dialect was added, intended to 
   replace -lang deprecated in future.

   In version 0.20.0b the #lang directive and $Lang metacommand were added 
   to specify a dialect from source.

      +------------+----------------------------------------------------------------------------+
      |-lang option|description                                                                 |
      |fb          |FreeBASIC compatibility (default)                                           |
      |qb          |qbasic compatibility                                                        |
      |fblite      |FreeBASIC language compatibility, with a more QBASIC-compatible coding style|
      |deprecated  |compatibility with FB 0.16                                                  |
      +------------+----------------------------------------------------------------------------+

   The -lang option was needed to allow FreeBASIC to support 
   object-orientation and other features in the future, without crippling 
   the QuickBASIC support or breaking compatibility with old FreeBASIC 
   sources, and without making FreeBASIC difficult to maintain with many 
   different versions of very similar packages. The QuickBASIC support can 
   continue to be improved, if needed, without breaking the sources written 
   specifically for FreeBASIC.

   To compile old GW-BASIC or QuickBASIC/QBasic sources without too many 
   changes, use the -lang qb option on the command-line when running fbc. 
   This option will evolve into a better compatibility with 
   QuickBASIC/QBasic code.

   To compile FreeBASIC sources from 0.16b, use the -lang deprecated 
   option. This option is maintained for compatibility and will not evolve 
   in the future, and it's likely to disappear when FreeBASIC reaches a 
   non-beta release.

   For programmers who want to access some of FreeBASIC's newer features, 
   but want to retain a more QBASIC-friendly programming style, use the 
   -lang fblite option.  This dialect will not undergo significant changes 
   in the future, but will continue to be maintained and supported.
   This option is also the most compatible with sources that were made 
   using older versions of FreeBASIC.

   It is recommended to use -lang fb for new projects, as new features 
   (object classes, inheritance..) will be added exclusively to this 
   dialect.

   -lang fb (the default mode)
    
   Not supported:
    
   1) implicit variable declaration
      * All variables must be explicitly declared, using Dim, ReDim, Var, 
        Const, Extern or Common.
    
   2) type suffixes (!, #, $, %, &)
      * They are only allowed for numeric literals, but it's recommended 
        to use Cast or the f (single), d (double), ll (longint), ul (ulong
        ), ull (ulongint) numeric literal suffixes to resolve overloading.
    
   3) DefByte, DefUByte, DefShort, DefUShort, DefInt, DefUInt, DefLng, 
   DefLongInt, Defulongint, DefSng, DefDbl, DefStr
      * An explicit type ("As T") is needed when declaring variables using 
        Dim, ReDim, Extern or Common. Variables declared using Var or Const 
        have their types inferred from an initialization value (an explicit 
        type is optional using Const).
    
   4) all parameters passed by reference by default
      * By default, all intrinsic scalar types - numeric and pointer types 
        - are passed by value (ByVal). Any other type - String or 
        user-defined type - is passed by reference (ByRef).
      * Use the -w pedantic command-line option to have parameters without 
        explicit ByVal or ByRef reported.
    
   5) OPTIONs of any kind (no context-sensitivity)
      * Instead of Option NoKeyword, use #undef.
      * Instead of Option Escape, use: !"some esc seq \n\r" (notice the '!
        ' char) and pass -w pedantic to check for possible escape 
        sequences.
      * Option Explicit isn't needed, see item 1.
      * Instead of Option Dynamic, declare variable-length arrays using 
        ReDim. Dim can also be used to declare variable-length arrays using 
        variable or no subscripts.
      * Instead of Option Base, use explicit lower-bound subscripts in 
        arrays declarations.
      * Instead of Option Private, use Private to declare procedures with 
        internal linkage.
      * Instead of Option Gosub and Option Nogosub, use procedures with Sub
        or Function.
    
   6) periods in symbol names 
      * Use namespaces instead.
    
   7) GoSub or Return (From Gosub)
      * Nested procedures may be allowed in future.
    
   8) On Gosub
      * Use Select Case As Const Integer_Expression instead.
    
   9) Resume
      * Most runtime and graphics library procedures now return an error 
        code, like:  IF OPEN( "text" FOR INPUT AS #1 ) <> 0 THEN error... 
    
   10) '$DYNAMIC, '$STATIC, '$INCLUDE meta-commands embedded in comments
      * See item 5 about Option Dynamic.
      * Use #include "filename" instead of '$include.
    
   11) Call or Let
      * Just remove them.
    
   12) numeric labels
      * Named labels can be used instead, e.g. label_name: / Goto 
        label_name.
    
   13) global symbols with the same name as keywords 
      * Declare them inside a namespace. 

-lang deprecated
    
   Supported: Anything allowed in version 0.16b, but:
    
   1) GOSUB/RETURN and ON ... GOSUB (even at module-level)
      * so the GOSUB implementation could be thread-unsafe in the -lang qb 
        mode, allowing fast execution (-lang qb doesn't support 
        multi-threading, while -lang deprecated does).
    
   Not supported:
    
   1) Classes
      * Periods allowed in symbol names make it too difficult and/or 
        ambiguous.
    
   2) Operator overloading
      * Periods allowed in symbol names make it too difficult and/or 
        ambiguous.
    
   3) Constructors, destructors and methods in TYPEs.
      * Periods allowed in symbol names make it too difficult and/or 
        ambiguous.

-lang fblite
    
   Supported: Anything allowed in the -lang deprecated dialect, plus..
    
   1) GOSUB/RETURN
      * Use Option Gosub to enable.  This will disable RETURN from exiting 
        a procedure, due to ambiguity.
    
   Not supported:
    
   1) Scope blocks
      * All variables are given procedure scope.  Explicit Scope blocks 
        may be added later.

-lang qb
    
   Supported: Everything not supported/allowed in the -lang fb dialect, 
   plus..

   1) Call can be used with forward-referenced functions.

   2) Shared can be used inside functions. (W.I.P.)

   3) All variables, implicitly or explicitly declared, are always 
   allocated in the procedure scope, like in QuickBASIC.

   4) The Data statement won't look up symbols, every token is assumed to 
   be a literal string even without quotes, like in QuickBASIC.

   Not supported:

   1) Multi-threading
      * None of the threading procedures may be used.
    
   2) Classes and Namespaces

   3) Procedure and operator overloading

   4) Constructors, destructors and other member procedures in Type 
   definitions.

   5) Scope blocks

   6) Extern blocks

   7) Variable initialization
      * All variables are moved to the procedure scope (like in QuickBASIC
        ), making initializing local variables too difficult to support.





============================================================================
  FAQS
  ----


----------------------------------------------------------- CompilerFAQ ----
Frequently Asked Questions

FreeBASIC questions:

   - What is FreeBASIC?
   - Who is responsible for FreeBASIC?
   - Why should I use FreeBASIC rather than QBasic?
   - Why should I use FreeBASIC rather than some other newer BASIC ?
   - How fast is FreeBASIC?
   - How compatible is FreeBASIC with QuickBASIC?
   - How compatible is FreeBASIC with Windows? DOS? Linux?
   - Does FreeBASIC support Object Oriented Programming?
   - What are the future plans with FB / ToDo list ?
   - Can I program GUI applications in FB ?
   - Is FB suitable for complex / big applications?
   - Can I use a non-latin charset in my FreeBASIC applications?
   - Can I use Serial/COM and Hardware/CPU ports in FB?

Getting Started with FreeBASIC questions

   - Where can I find more information about FreeBASIC?
   - Why doesn't the QB GUI open when I start FreeBASIC?
   - Can I have an offline version of the documentation?
   - What's the idea behind the FB dialects?
   - Why does my program crash when I define an array larger than xx?
   - Why does my program fail to compile with the message 'cannot find -llibname'?

Advanced FreeBASIC

   - How do I link to C libraries?
   - Can I use a debugger?
   - What's the goal of the AR.EXE, AS.EXE and LD.EXE files included with FB ?
   - Is there a limit on how big my source files can be?
   - Can I write an OS in FreeBASIC ?
   - I'm developing an OS, can FreeBASIC be ported to my OS ?
   - Does FreeBASIC support returning reference from Functions, like in C++?

See also

FreeBASIC questions

What is FreeBASIC?
   FreeBASIC is a free, BASIC compiler for Windows (32-bit and 64-bit), 32 
   bit protected-mode DOS (COFF executables, like DJGPP), and Linux (x86, 
   x86_64, and ARM). It began as an attempt to create a code-compatible, 
   free alternative to Microsoft QuickBASIC, but has quickly grown into a 
   powerful development tool, already including support for libraries such 
   as Allegro, SDL, OpenGL, and many others with its default installation.

   Aside from having a syntax mostly compatible with QuickBASIC, FreeBASIC 
   introduces several new features to the aged language, including pointers 
   to variables and functions, and unsigned data types.

   FreeBASIC compiler is self-hosting - written in FreeBASIC, the libraries 
   however are written in C.

Back to top

Who is responsible for FreeBASIC?
   The first versions of FreeBASIC were developed exclusively by V1ctor. 
   Later versions gained contributions from many people, including Lillo, 
   who developed the Linux port and the graphics library, and DrV, who 
   developed the DOS port. 

   See the FreeBASIC Credits page.

Back to top

Why should I use FreeBASIC rather than QBasic?
   FreeBASIC has innumerable advantages over QBasic, QuickBASIC, PDS, and 
   Visual Basic for DOS. 
      * It supports 32-bit and 64-bit processors, where QBasic is designed 
        for 16-bit CPU's.
      * It supports modern OSes. It has ports to Windows, Linux, and 
        32-bit DOS.
      * It supports modern APIs such as SDL, DirectX, Win32, and OpenGL.
      * It is distributed under the GPL, meaning it's free and legal to 
        use, unlike most copies of QuickBASIC / other BASICs.
      * The library is distributed under the LGPL with additional 
        exception, meaning you may do whatever you want with your compiled 
        programs, including selling them.
      * FreeBASIC is many times faster than QuickBASIC / other BASICs.
      * FreeBASIC supports many features, such as pointers and inline 
        Assembly, which are not available in QuickBASIC / other BASICs.
      * QuickBASIC only supports DOS. Windows support for DOS emulation 
        (and thus QuickBASIC) is becoming thinner with every new version. 
        Vista does not support graphics or fullscreen text for DOS 
        applications.

Back to top

Why should I use FreeBASIC rather than some other newer BASIC ?
   FreeBASIC has many traits which make it more desirable than most other 
   BASIC language implementations:
      * FreeBASIC adheres closely to the standard BASIC syntax, making it 
        easier to use.
      * FreeBASIC is compiled to actual programs (executables), not 
        bytecode.
      * FreeBASIC has a large, dedicated community which has actively 
        participated in the development of FreeBASIC.
      * FreeBASIC utilizes standard methods of accessing common C 
        libraries. SDL, for example, is standard C SDL, not a new set of 
        intrinsic commands.
      * FreeBASIC has ports to Windows, Linux, and 32-bit DOS. It retains 
        consistent syntax between the three ports.

Back to top

How fast is FreeBASIC?
   Most tests run by the community have shown FreeBASIC is significantly 
   faster than QuickBASIC, faster than most other GPL or commercial BASICs, 
   and often approaching GCC in terms of speed.
   The Computer Languages Benchmark Game, an independent test team, give 
   FreeBASIC for Linux a speed 1.8 times slower than  GNU g++. Tests are 
   about calculation, memory and disk access speed in console programs, no 
   graphics capabilities were tested. This is not a bad result considering 
   FreeBASIC is not yet an optimizing compiler.
   One area where there is a notable speed deficiency is in 32-bit console 
   modes. While FreeBASIC is consistently on-par with other 32-bit console 
   mode applications, 32-bit console mode operations are significantly 
   slower than 16-bit console operations, as seen in QuickBASIC. In DOS 
   version, some I/O operations can slow down after porting from a 16-bit 
   BASIC to FB - optimizing the code brings the speed back.

Back to top

How compatible is FreeBASIC with QuickBASIC?
   The FreeBASIC built in graphics library emulates the most used QB 
   graphics modes (modes 7,12,13) and implements all the drawing primitives 
   featured in QB. 
   Most compatibility problems arise from the use of 8086-DOS-hardware 
   specific low-level techniques in the old QB programs. VGA port 
   programming, DOS interrupts, memory segment switching, poking to the 
   screen memory or music playing using the PC speaker are not directly 
   supported, even if they can be supported/emulated by external libraries. 
   
   Other issues in porting old QB programs, like variable name clashes with 
   new FB keywords, variables with the name of a QB keyword plus a type 
   suffix, default integer size being 32 bits in FB, are addressed by 
   running FreeBASIC with the commandline switch -lang qb .

   See Differences between FreeBASIC and QuickBASIC.

Back to top

How compatible is FreeBASIC with Windows? DOS? Linux? 
   FreeBASIC is fully compatible with Windows, MS-DOS, FreeDOS and Linux. 
   When planning to create a program for all three platforms, however, keep 
   API availability in mind -- code utilizing OpenGL will work in Windows 
   and Linux, for example, but won't in DOS, because OpenGL is not 
   available for DOS.

Back to top

Does FreeBASIC support Object Oriented Programming?
   FreeBASIC supports classes (user-defined types) with member functions 
   (methods), static methods, static member variables, constructors, 
   destructors, properties, operator overloading, single inheritance, 
   virtual and abstract methods (polymorphism) and Run-Time Type 
   Information (RTTI). Future plans regarding OOP functionality include 
   adding support for multiple inheritance and/or interfaces. For more 
   information see: A Beginners Guide to Types as Objects.

Back to top

What are the future plans with FB / ToDo list ?

   You can find out what's planned for the future releases by directly 
   looking at fbc's todo.txt.

Back to top

Can I program GUI applications in FB ?
   Yes, you can. Headers allowing you to call the  GUI API of Windows and 
   Linux are supplied with the respective versions, but the programs made 
   this way are not portable.
   There are some API wrappers and experimental RAD applications that 
   create non-portable GUI code for Windows.
   For portable programming a multiplatform GUI wrapper  library  as GTK or 
   wx-Widgets may be used. GTK headers are provided with FB, but the OOP 
   functionality currently available in FB prevents the use of wx-Widgets. 
   The programs created with these libraries may require the user to 
   install the wrapper libraries in their systems.
   For games and small graphics applications there are some FB-specific 
   libraries that draw and manage  simple controls as buttons and edit 
   boxes inside the graphics screen, programs made with those libs are 
   entirely portable. 

Back to top

Is FB suitable for complex / big applications?
   The FB compiler is self-hosting, it is programmed itself in FB. That 
   means more than 120 000 lines of code at the moment, a fairly complex 
   application.

Back to top

Can I use a non-latin charset in my FreeBASIC applications?

   FreeBASIC has the Unicode support provided by the C runtime library for 
   the given platform. This means FB DOS won't help you with Unicode. On 
   other platforms you can use Wstrings to support any charset you need. 
   The File OPEN keyword  has an additional Encoding parameter allowing for 
   different encodings. As FreeBASIC is coded itself in FB, this means you 
   can code your source in an Unicode editor so the comments and string 
   literals can be in any character set (keywords, labels and names for 
   variables and procedures must be kept inside the  ASCII set..).
   For the output to screen the support is different from console to 
   graphics. In console mode wstring printing in non latin charsets is 
   supported if the console font supports them. Graphics mode uses an  
   internal CP437 charset (the old DOS charset) font so non-latin output 
   requires a custom made raster font and the use of the Draw String 
   keyword. Third party tools exist to grab an external font and convert it 
   to the  DRAW STRING format.

Back to top

Can I use Serial/COM and Hardware/CPU ports in FB?
    Yes, FB has built in functions to access the serial/COM port and 
   hardware/CPU ports with no need of external libraries. See the 
OS specific FAQ's for details for your OS, and Open Com, Inp and Out .

Back to top

Getting Started with FreeBASIC questions

Where can I find more information about FreeBASIC?
   The FreeBASIC Wiki is the most up-to-date manual for using FreeBASIC, 
   available here.

   Active FreeBASIC related forums, besides the official one, can be found 
   at qbasicnews, Pete's QB Site , the FB Games directory  or  
   freebasic-portal.de (in German).

   Active magazines which regularly have FreeBASIC related articles are 
   QB Express and QBXL Magazine. These magazines are always looking for new 
   articles, so if you think you've got a good idea for an article about 
   FreeBASIC, submit it!

Back to top

Why doesn't the QB GUI open when I start FreeBASIC?
   QB had an Integrated Development Environment (IDE).  FreeBASIC does not.
   FreeBASIC is only a compiler, not a complete QuickBASIC clone. It is a 
   console mode application. It will accept a BAS file on the command line, 
   and spit out an EXE file.
   You can create the BAS file with the simplest plain text editor in your 
   OS (Notepad, EDIT, nano,...), then run the compiler. 
   If you can't live without  syntax coloring, error highlighting, multiple 
   file managing, integrated debugger, context help or other features, you 
   need an IDE. See the OS specific FAQ's for the IDE's and editors 
available.
 
Back to top

Can I have an offline version of the documentation?
   This online Wiki is the official documentation for FB. Usually it is 
   up-to-date with the latest improvements found in the development version 
   of FB.
   Offline versions of this wiki (in CHM, HTML and other formats) are 
   available from the 
   Documentation directory at fbc's downloads site on SourceForge.

Back to top

What's the idea behind the FB dialects?
   The idea is to allow improvements in the language while maintaining 
   backwards compatibility with QB code. The quirks of the QB syntax are 
   not compatible with the more rigid style required by OOP. The new FB 
   keywords often clashed with variable names in old QB programs. QB 
   allowed to use freely dots in variable names and procedures not being 
   UDT's.
   The three dialects  (-lang fb, -lang qb, -lang fblite) allow to combine 
   the best of two worlds. 
   *lang fb provides the framework required for OOP programming . Other 
     dialects don't give access to OOP.
   *lang qb will allow the developers to keep increasing the compatibility 
     with qb programs. Newer keywords in FB can be used by preceding them 
     with two underscores.  For example, Getmouse can be called by using _
     _Getmouse
   *lang fblite offers FreeBASIC language compatibility, with a more 
     QBASIC-compatible coding style.

   See Compiler Dialects for details.

Back to top

Why does my program crash when I define an array larger than xx ?

   This generally happens because you made an automatic fixed-length array 
   too large, and it is corrupting the program stack. You have a couple of 
   options:

   * if possible, reduce the size of the automatic array
   * create a variable-length array, by
      * defining the array with an empty subscript list (using Dim), or
      * defining the array with variable subscripts instead of numeric 
        literals, Constants or Enums (using Dim), or
      * defining the array with ReDim
   * reserve more memory for the program stack by using the -t 
     command-line option when compiling. The default is -t 1024 
     (kilobytes). Note: it's a bad idea to use very large values here.
   * create a static array by defining the array with Static rather than 
     Dim (only locally visible, but globally preserved)
   * define the array with Shared access using Dim (this makes the array 
     fully global)
   * use Pointers and Memory Functions like Allocate and Deallocate to 
     manage memory yourself - this is the preferred way for storing big 
     buffers, but not for beginners.

   Static and variable-length arrays don't use the program stack for their 
   element data, so do not have the problem associated with automatic 
   fixed-length arrays. See Storage Classes for more information. Note that 
   storing huge buffers as static or increasing the stack size far above 
   the default is not a very good idea, since it increases the fixed amount 
   of memory needed to load and start you program, even if most of it is 
   not used later, and can result in performance degrade, or even refusing 
   your program to load at all.    

Back to top

Why does my program fail to compile with the message 'cannot find 
-llibname'"?
   This is an error raised by the linker.  The program is supposed to link 
   to an external library, designated in the program code with #inclib or 
   on the compiler command line with -l.  However, the linker has been 
   unable to find a matching file in any of the library paths.  Check the 
   homepage of the library you want to compile with to find out how to 
   download it, or check ExtLibTOC to see if information about the library 
   can be found there. For general information on libraries and how to use 
   them see Using Prebuilt Libraries and the related pages listed there.

Back to top

Advanced FreeBASIC

How do I link to C libraries?
   C libraries are set up in much the same way in FreeBASIC as they are in 
   C. Every library included with FreeBASIC has a basic include file named 
   "library name.bi" which uses the #inclib metacommand to include the 
   library, and the Declare Statement to declare the functions within the 
   library. FreeBASIC includes hundreds of BI files, see full list of 
   library headers here.

Back to top

Can I use a debugger?
   FreeBASIC can use preferably a debugger compatible with GNU GDB. 
      * Win32: Insight is an user friendly wrapper for GDB, see 
        Win32 related FAQ. 
      * DOS: Be warned that DOS also has product named "Insight", but it's 
        a real mode debugger not usable with FreeBASIC, use GDB or some 
        DPMI32 debugger at least.
      * Linux: use GDB.

   See the OS specific FAQ's for details for your OS.

Back to top

What's the goal of the AR.EXE, AS.EXE and LD.EXE files included with FB ?
   AS.EXE is GAS, the "GNU assembler". It is always involved in 
   compilation. LD.EXE is the "GNU linker", involved in creation of 
   executables. AR.EXE is the "GNU archiver", in fact a librarian, creating 
   .A libraries. 

Back to top

Is there a limit on how big my source files can be?
   Yes, since FreeBASIC is a fully 32-bit compiler it may operate on source 
   files up to theoretically 4GB or 4294967296 bytes, however your RAM 
   capacity should be significantly above the size of your source, 
   otherwise the compilation won't finish or will be very slow at least. 

Back to top

Can I write an OS in FreeBASIC ?

   YES and NO. If you really insist to write an OS and involve FB, the 
   answer is YES. If the question is, whether it is a good idea that you, 
   even more if a beginner, should start coding an OS using FB now, the 
   answer is NO. Several pitfalls apply:
      * OS development is hard, see 
        http://www.osdev.org/wiki/Getting_Started .
      * FB won't help you to bypass the need to deal with assembly, also C 
        might be almost impossible to avoid.
      * You won't be able to use most of the trusted FB features, like 
        graphics, file I/O, threads, memory management, even console I/O 
        ... just control flow, math and logic. If you need those library 
        functions, you will have to reimplement them.
   FreeBASIC relies on GCC, and available informations about developing an 
   OS in C apply to FreeBASIC as well. FB will help you neither more nor 
   less than GCC.

Back to top

I'm developing an OS, can FreeBASIC be ported to my OS ?

Depends. If your OS at least egalizes the functionality of DOS with DPMI32 
(console I/O (seeking, multiple files open, ...), file I/O, memory 
management) and has a port of GCC, then the answer is YES. If you have at 
least an other somewhat compliant C compiler with libraries, it might be 
possible. You can't reasonably port FB for example to an OS allowing to 
load or save a file in one block only, or a 16-bit OS.   

Back to top

Does FreeBASIC support returning references from Functions, like in C++?

Yes, this functionality exists. Procedures can now return references using 
ByRef as datatype for the return type.

Back to top

See also
   * Win32 related FAQ
   * DOS related FAQ
   * Linux related FAQ
and
   * FB Runtime Library FAQ
   * Frequently Asked FreeBASIC Graphics Library Questions



---------------------------------------------------------- FaqPggfxlib2 ----
Frequently Asked FreeBASIC Graphics Library Questions

FreeBASIC Graphics Library questions:

   - How can I link/use Gfxlib?
   - What about the fbgfx.bi header file?
   - How are Get/Put arrays managed?
   - Why is Bsave/Bload crashing?
   - How can I get the red, green, blue, or alpha component of a colour?
   - How can I make the 'x' button in the window header close my application?
   - Can't run programs using Screen 13 or 14 in fullscreen !
   - Why does Imagecreate return a NULL pointer?

FreeBASIC Graphics Library questions

How can I link/use Gfxlib?
   Gfxlib is "built in" into the language, it is not necessary to include 
   any .bi file or to link any library explicitly. FreeBASIC detects you 
   want to use Gfxlib when you use the Screen or ScreenRes statements. So 
   to use Gfxlib, just start a graphics screen mode and use the graphics 
   commands.

Back to top

What about the fbgfx.bi header file?
   The fbgfx.bi header file is available for inclusion by your program, and 
   contains constant and type definitions that may be helpful to the 
   programmer when using Gfxlib. You do not have to explicitly include this 
   file to use Gfxlib however; the header is only available as an aid. It 
   contains the constants for the mode flags that can be passed to Screen 
   and ScreenRes, and also definitions of Keyboard scancodes and the 
   fb.Image buffer structure.

Back to top

How are Get/Put arrays managed?
   In FreeBASIC, images can be used as arrays (as in QB) or as pointers. 
   Either way, the image data is contained in one continuous chunk. The 
   chunk consists of an header followed by the image data. The header can 
   be of two types (old-style and new-style) and determines the format of 
   the following image data, for details see GfxInternalFormats .

Back to top

Why is Bsave/Bload crashing?
   Bsave/Bload can only be used to load and save graphics screens in 
   FreeBASIC. It can't be used to save a text mode screen. To load and save 
   an array check this snippet using file Get/Put .

Back to top

How can I get the red, green, blue, or alpha component of a color?

   Each byte in a color attribute corresponds with the red, green, blue, 
   and alpha components.  The following example shows how to extract the 
   component values from a 16, 24, or 32 bit color attribute.

   #define rgb_a(x) ((x) Shr 24)
   #define rgb_r(x) ((x) Shr 16 And 255)
   #define rgb_g(x) ((x) Shr 8 And 255)
   #define rgb_b(x) ((x) And 255)

   Dim As UInteger c
   Dim As Integer x, y
   Dim As UByte red, green, blue, Alpha

   '' Assume a 16, 24, or 32 bit screen mode has been set
   c = Point(x, y)
   red = rgb_r(c)
   green = rgb_g(c)
   blue = rgb_b(c)
   Alpha = rgb_a(c)

Back to top

How can I make the 'x' button in the window header close my application?
   In windowed graphics mode you can test for the press of the window's X 
   (close) button with Inkey, checking for the value Chr( 255 ) + "k" 
   (which is also the code returned for Alt+F4). This applies to Win32 and 
   Linux, in DOS there is no "X" button.

   Here is a small example:

   '' "X" close button example , Win32 and Linux only
   Dim As String key
   Screen 13
   Do
     Print "Click the 'x' to close this app."
     Sleep
     key = Inkey
   Loop Until key = Chr(27) Or key = Chr(255, 107) 'escape or x-button

Back to top

Can't run programs using Screen 13 or 14 in full-screen!
   It's a hardware/driver limitation (Win32 and Linux only?). Video cards 
   don't implement those low resolution graphic modes nowadays. If 
   full-screen is required you should rewrite it using at least Screen 17 
   or 18, or a resolution of 640x480 or higher to be sure modern hardware 
   can handle it.

Back to top

Why does Imagecreate return a NULL pointer?
   ImageCreate needs to create an image buffer that fits the current 
   screen's pixel format, and it cannot do so if there is no screen mode 
   setup yet, so it returns NULL, very likely resulting in a NULL pointer 
   access later on that crashes the program.

   This is known to happen when Imagecreate is called before the graphics 
   library was initialized with a call to Screen or ScreenRes, as may 
   happen when Imagecreate is called in a global constructor that is 
   invoked before the Screen or Screenres call in the main part of the 
   program. In such a case it is necessary to move the screen 
   initialization into a constructor too, and have it execute before the 
   image-creating constructors.

Back to top

See also
   * Compiler FAQ
   * FB Runtime Library FAQ
   * Frequently Asked FreeBASIC Graphics Library Questions



------------------------------------------------------------ FaqPgrtlib ----
Frequently Asked FB Runtime Library Questions

FreeBASIC Runtime Library questions:

   - How do I play sound?
   - How do I access the serial ports?
   - How do I print?
   - How do I access the hardware ports?

FreeBASIC Runtime Library questions

 How do I play sound?
   Of the QB's sound keywords only BEEP is implemented in FB. 
   If PC speaker sound is required, it should be programmed using IN and 
   OUT. See the example in the OUT keyword for a replacement of SOUND. 
   There is a library called QBSound that allows to emulate qb's ability to 
   PLAY in the background tunes encoded in strings, it uses the soundcard's 
   synthesizer.
   If what's required is to play .wav or .mp3 files thru a soundcard, 
   external libraries as FMOD or BASS can be used in Linux and Windows. For 
   DOS see the DOS FAQ section.

Back to top

How do I access the serial ports?

   DOS
   See DOS FAQ section.

   Windows and Linux
   See Open Com.

Back to top

How do I print?
   FB supports character output to printer.
   To print graphics two approaches are possible:
   * Preprocess the graphics data, program the printer, and send the data 
     to it (see wikipedia.org/wiki/ESC/P). This is OS-portable but depends 
     on the printer model. The only way for DOS, see also DOS FAQ section.
   * In Windows and Linux there are specific API calls. This is not 
     OS-portable but the OS's printer driver makes it printer-independent.

Back to top

How do I access the hardware ports?

   INP, OUT and WAIT known from QB are implemented in FB.
   The GfxLib intercepts the calls to some VGA ports to emulate the widely 
   used QB's palette manipulation and vsync methods. So ports &H3DA, &H3C7, 
   &H3C8 and &H3C9 can't be accessed it GfxLib is used. All other ports are 
   accessible.
   No further tricks are required to use INP and OUT in Linux or DOS. For 
   the Windows version the required device driver is installed each first 
   time the program is run in a windows session; this requires 
   Administrator rights for this first run or the program will end with an 
   error. Note that accessing hardware ports by applications is not common 
   practice in Windows and Linux.

Back to top

See also
   * Compiler FAQ
   * Frequently Asked FreeBASIC Graphics Library Questions
and
   * Win32 related FAQ
   * DOS related FAQ



------------------------------------------------------------- FaqPgxbox ----
Frequently Asked Questions

FreeBASIC on Xbox general questions

   - Can FreeBASIC really make Xbox games?
   - How was the FreeBASIC Xbox port made?
   - How about a port for Xbox 360?
   - How about a port for PlayStation or another console?
   - Why don't you use an emulator until a developer gets a modded Xbox?
   - Why don't you use the Microsoft XDK?
   - Why don't you use the Microsoft debugger to fix it?
   - Isn't this illegal? Can't Microsoft sue you?

Getting Started with FreeBASIC on Xbox questions

   - What do I need to compile Xbox games with FreeBASIC?
   - How would you get input?
   - Does it only run on certain Xboxes?
   - Is another language (eg C or ASM) needed for the job?
   - Do you need a special lib?
   - Can you use premade functions (inkey, line etc)?
   - What else should I know?

FreeBASIC on Xbox general questions

Can FreeBASIC really make Xbox games?

In theory, yes. A copy of FreeBASIC 0.13 was ported to the Xbox in July 
2005, and produced working executables. However, changes to the compiler 
for the 0.14 release broke compatiblity. 

The Xbox port is currently in zombie mode; nobody in the project team has 
the console at the moment - the original port was done by SJ Zero, but it 
got broken with the runtime library modifications done in v0.14.

The port is on hold until the GCC backend port is complete, because it is 
believed that this port will fix the Xbox port.

How was the FreeBASIC Xbox port made?

FreeBASIC for Xbox is possible because of the efforts of Open Source 
developers who created OpenXDK, the legal software development kit for 
Xbox. OpenXDK is created for a unixish environment, which is quite 
compatible with the FreeBASIC source.

The port was created by forcing the FreeBASIC runtime library to use the 
OpenXDK version of Glibc instead of the mingw32 version. When compiled with 
the correct flags, this creates what looks like a standard EXE file. CXBE 
then strips the Windows PE header on this executable file and replaces it 
with an Xbox header.

In effect, all the port really does is change the runtime library and link 
in a certain way to allow the CXBE utility to create an Xbox executable.

How about a port for Xbox 360?

The Xbox is an Intel Pentium 3 running a derivative of the NVIDIA nForce 
chipset, with an NVIDIA video chip and an NVIDIA SoundStorm sound card. 
This is why the Xbox port was possible and relatively straightforward to 
do. 

The Xbox 360, on the other hand, uses an alien CPU, and similarly alien 
hardware. FreeBASIC cannot presently be made to produce executables for the 
Xbox 360. 

Another problem is the lack of an equivilent to OpenXDK for the Xbox 360. 
This would force any port to use the Xbox 360 XDK, a copyrighted piece of 
software created by Microsoft. This would be illegal, immoral, and would 
put FreeBASIC in legal jeparody. 

Therefore, a port to the Xbox 360 is to be considered impossible at this 
time.

How about a port for PlayStation or another console?

The Xbox is an Intel Pentium 3 running a derivative of the NVIDIA nForce 
chipset, with an NVIDIA video chip and an NVIDIA SoundStorm sound card. 
This is why the Xbox port was possible and relatively straightforward to 
do. 

The PlayStation, on the other hand, uses a RISC chip, which FreeBASIC 
cannot currently produce code for. Almost all consoles utilize non x86 
processors, stopping development using FreeBASIC from being possible.

Another problem is the lack of an equivilent to OpenXDK for many consoles. 
This would force any port to use the commercial software development kit, a 
copyrighted piece of software created by the console manufacturer. This 
would be illegal, immoral, and would put FreeBASIC in legal jeparody. 

Therefore, a port to other consoles are to be considered impossible at this 
time. However, many ports to consoles and other platforms with legally 
available development kits will be possible when the GCC backend port is 
complete.

Why don't you use an emulator until a developer gets a modded Xbox?

No known Xbox emulator is capable of running FreeBASIC code. A legitimate 
hardware console is required to run the programs made. This makes an 
emulator completely useless for development. 

Why don't you use the Microsoft XDK?

There are two main reasons not to use the Microsoft XDK.

1) Microsoft's XDK is a piece of copyrighted software, and utilizing it 
would be illegal and immoral, putting FreeBASIC at risk of legal action. 
Furthermore, no member of the FreeBASIC team has ever had any access to the 
Microsoft XDK, to prevent "tainting" FreeBASIC legally.

2) OpenXDK is developed around gcc and UNIX-style systems such as MinGW or 
Cygwin. This means that it can be integrated into FreeBASIC with very 
little effort. Microsoft's XDK, on the other hand, is developed around 
Microsoft based compilers, and thus would not easily integate into the 
source code of FreeBASIC.

NOTE: PROTECTION OF MICROSOFT'S COPYRIGHT, AND BY PROXY OF FREEBASIC, IS OF 
PRIMARY IMPORTANCE IN THIS PROJECT. WE DO NOT WANT HELP FROM ANYONE WITH 
THE XDK, NOR DO WE WANT HELP FROM ANYONE WITH A DEBUGGER XBOX. ANY ATTEMPT 
TO OFFER THE XDK OR XDK RELATED HELP SHALL BE FORWARDED TO THE PROPER LAW 
ENFORCEMENT AGENCIES.

Why don't you use the Microsoft debugger to fix it?

There are two very good reasons not to use the Microsoft debugger. 

1) Microsoft's XDK is a piece of copyrighted software, and utilizing it 
would be illegal and immoral, putting FreeBASIC at risk of legal action. 
Furthermore, no member of the FreeBASIC team has ever had any access to the 
Microsoft XDK, to prevent "tainting" FreeBASIC legally.

2) Microsoft's debugger requires a specially modified Xbox which neither SJ 
Zero nor any development team member has, and frankly, nobody who has 
worked on the port believes the debugger would work with FreeBASIC 
executables -- just as Microsoft's debugger can't read FreeBASIC debugger 
files, we doubt the Xbox debugger could read FreeBASIC debugger files. 
Regardless, point #1 trumps any attempt.

NOTE: PROTECTION OF MICROSOFT'S COPYRIGHT, AND BY PROXY OF FREEBASIC, IS OF 
PRIMARY IMPORTANCE IN THIS PROJECT. WE DO NOT WANT HELP FROM ANYONE WITH 
THE XDK, NOR DO WE WANT HELP FROM ANYONE WITH A DEBUGGER XBOX. ANY ATTEMPT 
TO OFFER THE XDK OR XDK RELATED HELP SHALL BE FORWARDED TO THE PROPER LAW 
ENFORCEMENT AGENCIES.

Isn't this illegal? Can't Microsoft sue you?

Copyright is important for the protection of both commercial firms like 
Microsoft, and for small projects such as FreeBASIC. Without copyright, 
neither could enforce any rights over the code (In our case, such as the 
GPL). Generally speaking, it is copyright issues which are most often the 
cause of problems for open source projects attempting to do things like 
this.

Because the FreeBASIC Xbox port is created using software tools whose 
legality has already been established, themselves often derived from other 
sources whose legality has been established, FreeBASIC for Xbox is not 
illegal. Careful care has been taken to protect FreeBASIC from using any 
Microsoft copyrighted code, and diligence is and will be followed to 
prevent access to copyrighted code.

Getting Started with FreeBASIC on Xbox questions

What do I need to compile Xbox games with FreeBASIC?

The port isn't currently working, but when it is ready, you will only need 
a copy of FreeBASIC for Xbox.

How would you get input?

Initially, input will be acquired through SDL, as a gfxlib port is not yet 
complete. One of the developers is working on a generic SDL version of 
gfxlib, however, and it will provide full gfxlib functionality to the Xbox 
port.

Does it only run on certain Xboxes?

FreeBASIC for Xbox executables will only run on modded Xboxes. However, 
modding an Xbox is often as simple as loading a savegame in a certain game. 
More information is available on the Xbox-Linux website.

Is another language (eg C or ASM) needed for the job?

No. FreeBASIC for Xbox is the only thing needed.

Do you need a special lib?

No. FreeBASIC for Xbox will come with all supported libraries.

Can you use premade functions (inkey, line etc)?

Currently, input and output commands such as inkey and line aren't 
available, but all other functions, including file I/O, are. One of the 
developers is working on a generic SDL version of gfxlib, however, and if 
it functions, it will provide full gfxlib functionality to the xbox port.

What else should I know?

Executables created by FreeBASIC for Xbox are free of copyrighted Microsoft 
code, making them legal for distribution.

Windows and Linux source files which are designed to use SDL and rtlib will 
be capable of compiling for Xbox out of the box. While the Xbox does have 
keyboard support through the gamepad ports (proprietary USB connection), 
the input scheme will have to be altered to account for a gamepad.



---------------------------------------------------------------- FaqDOS ----
DOS related FAQ

DOS

The FreeBASIC port to DOS is based on the DJGPP port of the GNU toolchain 
to 32-bit protected-mode DOS.

The current maintainer of this port is DrV.

To be written: platform-specific information, differences from Win32/Linux, 
differences from QB?, tutorials, etc. 

WANTED TESTERS

The DOS version/target of FreeBASIC needs more testers. If you are 
interested in using FreeBASIC on DOS, please don't wait for future 
releases, give it a try now. Tests from running in DOS on both old and new 
PC's are welcome (graphics, file I/O, serial port, ...). If something 
doesn't work, please place a detailed bug report into the forum or bug 
Tracker. If all works well, you can write about your success as well. Make 
sure to test a recent version of FB (reports from FB older than 0.90 will 
be probably considered as obsolete and useless), and check this document bef
ore complaining about anything.

Limitations

The DOS target is fairly well working and supported by FreeBASIC, and 
up-to-date. A few differences compared to other platforms exist, however. 
The features missing are mostly those not supported by the operating system 
or DOS extender or C runtime:
   * Cross-compiling to an other target
   * Multithreading (see FAQ 23)
   * Graphics in windowed mode or using OpenGL
   * Setting ScreenRes to a size not matching any resolution supported by 
     the graphics card  
   * Unicode isn't supported in DOS, WString will be the same as ZString, 
     character sets other than latin aren't supported. (do it yourself)
   * Shared libraries (DLL's) can't be created/used (at least not 
     "easily"), amount of available static external libraries usable with 
     DOS is limited

FreeBASIC DOS related questions:

   - 1. FB is a 32-bit compiler - do I need a 32-bit DOS?
   - 2. What about FreeDOS-32? Does/will FB work, is/will there be a version?
   - 3. When running FreeBASIC in DOS, I get a 'Error: No DPMI' message!
   - 4. Is there a possibility how to get rid of this CWSDPMI.EXE and CWSDPMI.SWP?
   - 5. Can I use other DOS extenders, like DOS/4GW, Causeway, DOS/32A?
   - 6. Where is the nice blue screen with all the ... / where is the IDE?
   - 7. How can I view the documentation in CHM or PDF format in DOS?
   - 8. How can I write/edit my source code?
   - 9. How can I play sound in DOS?
   - 10. How can I use USB in DOS?
   - 11. How can I use graphics in DOS?
   - 12. DEF SEG is missing in FB! How can I workaround this in my code?	
   - 13. How can I rewrite QB's CALL INTERRUPT / access the DOS and BIOS interrupts?
   - 14. How can I rewrite QB's XMS/EMS handling?
   - 15. FBC gives me a 'cannot find lsupcxx' error!
   - 16. How can I use the serial or parallel port?
   - 17. How can I use a printer?
   - 18. How can I make a screenshot of a FreeBASIC program running in DOS?
   - 19. Graphics mode doesn't work  (freeze / black screen / garbage output)!
   - 20. Mouse trouble! Mouse doesn't work at all in DOS / arrow 'jumps' / etc. ...
   - 21. What about the 64 KiB and 640 KiB problems / how much memory is supported by FB in DOS?
   - 22. My program crashes when I try to use more than cca 1 MiB RAM! Is this a bug in FreeBASIC?
   - 23. Threading functions are disallowed in DOS? Help!
   - 24. Executables made with FB DOS are bloated!
   - 25. Compilation is very slow with FB!
   - 26. SLEEP doesn't work! How can I cause a delay?
   - 27. The performance is very bad in DOS!
   - 28. Can I access disk sectors with FB?
   - 29. Can I use inline ASM with advanced instructions like SSE in DOS ?

See also

FreeBASIC DOS related questions

1. FB is a 32-bit compiler - do I need a 32-bit DOS?
   No, the DOS version of FreeBASIC uses a DOS extender, allowing you to 
   execute 32-bit code on top of a 16 bit DOS kernel. You can use FreeDOS 
   (16-bit), Enhanced-Dr-DOS, old closed Dr-DOS, or even MS-DOS down to 
   version cca 4. You need at least 80386 CPU, see also Requirements.

2. What about FreeDOS-32? Does/will FB work, is/will there be a version?
   FreeDOS-32 is experimental at time of writing, but it should execute 
   FreeBASIC and applications generated by it with no change. While FB DOS 
   support already works on FreeDOS (16), it should be ready for FreeDOS-32 
   as well. 

3. When running FreeBASIC in DOS, I get a 'Error: No DPMI' message!
   You need a DPMI host (DPMI kernel, DPMI server), means the file 
   "CWSDPMI.EXE" (cca 20 KiB) or HDPMI32.EXE (cca 34 KiB). See 
   requirements, and FAQ 4 for more details.

4. Is there a possibility how to get rid of this CWSDPMI.EXE and 
CWSDPMI.SWP?
   Yes, 2 possibilities. To get rid of CWSDPMI.EXE and create a standalone 
   DOS executable embedding CWSDPMI, you need the CWSDPMI package and the 
   "EXE2COFF.EXE" file. Using EXE2COFF, you remove the CWSDPMI.EXE loader 
   (file loses 2 KiB of size, resulting in a "COFF" file without 
   extension), and then glue the file "CWSDSTUB.EXE" before this COFF. The 
   new executable is cca 21 KiB bigger than the original one, but it is 
   standalone, no additional files are needed. To get rid of CWSDPMI.SWP, 
   you can then edit your executable with CWSPARAM.EXE, and disable the 
   swapping (occasionally also - incorrectly - referred as paging).  Note, 
   however, that this will limit the memory that can be allocated to the 
   amount of physical memory that is installed in a system. This work can 
   be done both with the FBC.EXE file and all executables created by FBC. 
   The method is also described in the CWSDPMI docs in the package. 
   Alternatively, you can use the WDOSX or D3X extender. They don't swap 
   and create standalone executables. Since they run your executable in 
   Ring 0, the crash handling of them is not very good and can cause 
   freezers or reboots on bugs where other hosts exit the "civil" way with 
   a register dump. Also, spawning might not work well / at all with WDOSX 
   or D3X. Finally, you can use HDPMI . Download the "HXRT.ZIP" file (here: 
   japheth.de/HX.html alternative links), extract "HDPMI32.EXE" (cca 34 KiB)
   and "HDPMI.TXT" (not required by the code, just for your information), 
   and include it to your DOS startup ("HDPMI32 -r"). This will make HDPMI 
   resident and prevent all FreeBASIC (also FreePASCAL and DJGPP) programs 
   from both crying about missing DPMI and swapping. HDPMI can not (easily 
   / yet) be included into your executables. Running an executable 
   containing D3X, CWSDPMI or some DPMI host inside under HDPMI or other 
   external host is fine - the built-in host will be simply skipped. Using 
   DPMI is definitely required for FreeBASIC, since it can't generate 
   16-bit real mode code, and there is no other good way to execute 32-bit 
   code in DOS.

5. Can I use other DOS extenders, like DOS/4GW, Causeway, DOS/32A?
   Not any extender around. So-called WATCOM-like extenders can't be used 
   because of important differences in memory management and executable 
   structure. WDOSX and D3X do work, since they are a multi-standard 
   extenders, not only WATCOM-like. You also can use PMODE/DJ (not 
   "original" Tran's PMODE, nor PMODE/W (!), saves cca 5 KiB compared to 
   CWSDPMI, can be included into the EXE, but might affect stability or 
   performance) or, as aforementioned, HDPMI.

6. Where is the nice blue screen with all the ... / where is the IDE?
   The FreeBASIC project focuses on the compiler, generating the 
   executables from your BAS sources. It looks unspectacular, but is most 
   important for the quality of software developed by you. The project does 
   not include an IDE. There are several external IDEs for FreeBASIC, but 
   probably none does have a DOS version by now.  If you really need one, 
   you could try Rhide, but note that it is complicated and buggy, so use 
   it at your own risk. See also FAQ 7 and 8.

7. How can I view the documentation in CHM or PDF format in DOS?
   There is no good way to view CHM or PDF files in DOS by now. But you can 
   view the FreeBASIC documentation nevertheless. One of the FreeBASIC 
   developers, coderJeff provides a FreeBASIC documentation viewer with the 
   docs included in a special format, and having also a DOS version. It 
   looks similar the QB's built-in help viewer, but does not contain an 
   editor or IDE. Download here: 
   http://www.execulink.com/~coder/FreeBASIC/docs.html

8. How can I write/edit my source code?
   There are many editors for DOS around, but only few of them are good - 
   some possibilities are FreeDOS EDIT (use version 0.7d (!!) or 0.9, 64 
   KiB limit, suboptimal stability (save your work regularly) ), SETEDIT, 
   INFOPAD (comes with CC386 compiler, can edit big texts also, has syntax 
   highlighting for C and ASM, but not for BASIC).

9. How can I play sound in DOS?
   There are 2 ways how to play sound in DOS: either the ("archaic") PC 
   speaker, famous for beeping if something goes wrong, or a soundcard. The 
   speaker is easy to control, allows more than one might think, even to 
   play audio files (WAV, with decompression code also OGG Vorbis, MP3 
   etc.), you can re-use most of existing QB code easily (example: 
   o-bizz.de/qb...speaker.zip) or ASM code via inline ASM,  but provides 
   one channel and 6 bits only, and of course significantly worse quality 
   than a soundcard, and, on some newest (P4) PC's the speaker quality is 
   very bad or there is no speaker at all. For old ISA soundcards, there is 
   much example code around, a newer PCI soundcard can be accessed 
   (supposing bare DOS in this category) either using a ( "emulation" SB16 
   compatible) driver, if it is available for your card (unfortunately, 
   this is becoming more and more a problem, the DOS drivers are poor or 
   even inexistent), or access the card directly (this is low-level 
   programming, hardware-related, assembler is also needed, and you need 
   technical docs about the card). There are a few sources of inspiration 
   like the DOS audio player MPXPLAY (written in C with some ASM), 
   supporting both methods (native + "emu" drivers), see an up-to-date list 
   here: drdos.org/...wiki...SoundCardChip. Support of sound in DOS is not 
   business FB DOS port, actually FB doesn't "support" sound on Win32 and 
   Linux either - the games "connect to the API" rather than use FreeBASIC 
   commands or libraries. To play compressed files (MP3, OGG Vorbis, FLAC, 
   ...) , you additionally need the decompressing code, existing DJGPP 
   ports of those libraries should be usable for this.

10. How can I use USB in DOS?
   Again, not business of FB, you need a driver, FB doesn't "support" USB 
   on Win32 or Linux either, see other Wiki: drdos.org/...wiki...USB about 
   possibilities of USB usage in DOS.

11. How can I use graphics in DOS?
   GUI or graphics in DOS is definitely possible, there are several 
   approaches:
      *Use the FB graphics library. It uses VESA (preferably linear, but 
        also supports banked) to access the video card and supports any 
        resolution reported by the card's VESA VBE driver, in addition to 
        standard VGA modes.
      *VGA mode 320x200x8bpp: very simple, maximum reliability and 
        compatibility, but low resolution and 256 colours only, see 
        example.
      *VGA "ModeX" 320x240x8bpp: similar to above, less easy, good 
        reliability and compatibility, but low resolution and 256 colours 
        only, see example.
      *VGA "planed" mode 640x480x4bpp: difficult to set pixels, maximum 
        reliability and compatibility, but low resolution and 16 colours 
        only, no public example yet (?).
      *Some other "odd" VGA "ModeX" modes (like 360x240x8bpp): possible, 
        but for freaks only ;-)
      *Write your own VESA code: More difficult, good compatibility, 
        high-res and true color possible, there might be reliability 
        problems if not implemented carefully.
      *Use an external library (DUGL, Allegro, MGL, WxWidgets): Allows to 
        create "expensive" graphics & GUI's, bloats EXE size, need to 
        respect library license, potential loss of reliability.
   Note that some graphic cards report limited features through VESA, most 
   notably less memory (for example 8 MiB instead of 64 MiB) or less modes 
   (for example only 24 bpp modes visible while 32 bpp hidden, only lower 
   resolutions visible (up to cca 1280x1024) while higher hidden, only 
   "4:3" modes visible while "wide" modes hidden). This is a problem of the 
   card, not of DOS or FreeBASIC. You will see the additional features in 
   systems other than DOS, or in DOS only using hardware detection tools 
   going to the lowest level bypassing VESA.

12. DEF SEG is missing in FB! How can I workaround this in my code?
   DEF SEG is related to 16-bit RM addressing and was removed because of 
   this. "direct" access to VGA or other low memory areas is not possible, 
   because FreeBASIC's memory model (same as DJGPP's) is not zero-based. 
   For accessing low DOS memory, use DOSMEMGET and DOSMEMPUT , see 
   "vga13h.bas" example, or "_dos_ds" selector for inline ASM, see example:

   '' DOS only example of inline ASM accessing low memory 
   '' Run in text mode 80x25 only

   '' Including dos/go32.bi will define "_dos_ds"
   '' "pointing" into GO32 block

   #include "dos/go32.bi" 

   Dim As UInteger DDS

   DDS=_dos_ds

   ? : ? "Hello world !"
   ? "_dos_ds=$";Hex$(DDS) 
   ? "This is just a tEst - abcd ABCD XYZ xyz @[`{ - press any key ..."

   Do
     Sleep 1000
     If Inkey$<>"" Then Exit Do
     Asm
      mov  eax,[DDS] '' Directly using "_dos_ds" won't work here !!!
      push eax
      pop  gs        '' Just to get sure, it is usually set anyway
      Xor  ebx,ebx
      aa3:
      mov  al,[gs:0xB8000+2*ebx]
      cmp  al,65  '' "a"
      jb   aa1
      cmp  al,122 '' "z"
      ja   aa1   
      cmp  al,90  '' "Z"
      jbe  aa2
      cmp  al,97  '' "a"    
      jb   aa1 
      aa2: 
      Xor  al,32  '' Swap case
      aa1:
      mov  [gs:0xB8000+2*ebx],al
      inc  ebx
      cmp  ebx,2000
      jne  aa3
     End Asm  
   Loop
   ? : ? "Bye"
   End

13. How can I rewrite QB's CALL INTERRUPT / access the DOS and BIOS 
interrupts?
   Those interrupts can be accessed only using the DOS version/target of 
   FB.

   The access to interrupts is slower than in QB: with FB the DPMI host 
   will have to do 2 context switches, going to real-mode and coming back. 
   All of that will eat hundreds of clocks in raw DOS and thousands of 
   clocks if emm386 is loaded or if inside a Windows' DOS box. The slow 
   down might be negligible or relevant, it depends. You should try to 
   minimize the number of such calls, and process more data per call  - at 
   least several KiB, not just one byte or a few bytes.
 
   Use DJGPP's DPMI wrapper:

   #include "dos/dpmi.bi"

   Type RegTypeX As __dpmi_regs

   #define INTERRUPTX(v,r) __dpmi_int( v, @r )

   Alternatively you can call INT's via inline ASM, 2 important things you 
   have to care about are the fact that FB's memory model is not zero-based 
   (see also FAQ 12, "DEF SEG" issues), and additionally "direct" passing 
   of addresses (like DS:[E]DX) to an INT will not work except you have a 
   DPMI host with "DOS API translation".  

14. How can I rewrite QB's XMS/EMS handling?
   Depends why original code uses it. If it's just to bypass low memory 
   limits, simply remove it and use "ordinary" FB's data types / memory 
   handling features instead. If it is used for (sound) DMA, you are out of 
   luck and have to redesign the code completely, about sound see FAQ 9. 
   For DMA use preferably the low memory (should be no big problem, since 
   the application code and most buffers are in DPMI memory instead), DMA 
   in DPMI memory is possible but more difficult.  

15. FBC gives me a 'cannot find lsupcxx' error!
   The source of this problem is the libsupcxx.a file in LIB\DOS\ 
   directory, having 9 characters in the name. Your fault is to have 
   extracted the ZIP with long file names enabled, usually in Windows, and 
   then using FB in DOS with no LFN support, resulting in this file looks 
   LIBSUP~1.A and can't be found. Rename the file in LIBSUPCX.A (one X 
   only) or extract the ZIP again in DOS. Note: changes in FB 0.18, retest 
   needed. 

16. How can I use the serial or parallel port?
   The DOS INT14 is not very useful/efficient as it sends/reads a single 
   char in each call. So it's better to use an external DOS32 comms 
   library. /* does someone know a good one ? */ FB up to 0.18.2 doesn't 
   support OPEN COM on DOS target, coderJeff has an experimental 
   library/driver available, included with FB since 0.18.3. 

17. How can I use a printer?
   DOS kernel won't help you here, so you have to prepare the text 
   (trivial) or pixel data (acceptably easy for printers compatible with 
   the "ESC/P" standard) yourself and send in to the printer via the 
   parallel port or USB using an additional driver (see FAQ 10). So-called 
   "GDI" or "Windows" printers can't be made working in DOS with reasonable 
   effort.

18. How can I make a screenshot of a FreeBASIC program running in DOS?
   Ideally include this feature into your own code. DOS TSR based 
   screenshooters like SNARF mostly will work with text based screens, but 
   probably none of them with FreeBASIC's GFX library. It's not really a 
   bug on one or other side, it's a problem "by design".

19. Graphics mode doesn't work  (freeze / black screen / garbage output)!
   Place a bug report into the forum. To make it as useful and productive 
   as possible, please beware of the following, proceed given steps and 
   provide all related information:
      * Check the limitations listed on the page GfxLib
      * The graphics might not work well / at all on very old PC's. If 
        your CPU has less than cca 500 MHz, provide exact info about it, if 
        you don't know, use RayeR's CPUID or similar program to test.
      * Exact info about your graphics card is needed. Test on DOS using 
        DrV's VBEDIAG (reports info only) and RayeR's VESATEST (also tries 
        to set mode, allows visual inspection of the result). Find out what 
        "useful" modes (640x480, 800x600) are supported and with what 
        bitdepths (8, 16, 24, 32 bpp), and whether they can be set and look 
        correctly.
      * Find out and describe exactly what's wrong ("mode works with 
        VESATEST but not with FB", "no graphics but no error either", 
        "black screen and freezer", "graphics is messy/incomplete", ...).
      * If some sophisticated program doesn't work, try also a minimal 
        test like placing a circle in middle of the screen.
      * Try without a mouse driver (this reduces the CPU "cost").
      * Find out what modes are affected. If a mode doesn't work, reduce 
        the resolution or bitdeph, make sure to test the "cheapest"/safest 
        modes 640x480 with 32/24/16/8 bpp, 640x480 with 4 bpp, and 320x200 
        with 8bpp.
      * For some old cards there are VESA drivers available 
        (S3VBE/UVIVBE). Test both with and without, and include this info 
        into your report.
      * Remove potentially problematic content (memory managers, drivers) 
        from DOS startup files. Nothing of such is required for FB, except 
        a DPMI host (see also FAQ 4.).
      * Post info about your graphics card, CPU (if old), DOS type and 
        version, bug symptoms, and a simple example code.
   RayeR's VESATEST and CPUID can be downloaded here: 
   rayer.ic.cz/programm/programe.htm , VBEDIAG here drv.nu/vbediag/.

20. Mouse trouble! Mouse doesn't work at all in DOS / arrow 'jumps' / etc. 
...
   To use a mouse in DOS, you need a compatible driver, recognizing your 
   mouse, and recognized by FreeBASIC library. For optimal results, you 
   need a good driver and a suitable mouse.

   Mouse: the optimal choice, and pretty well available nowadays, is a PS/2 
   mouse. The old type would be a serial mouse, also this one should work. 
   The newest is USB mouse - but is not very suitable for use in DOS, since 
   it would need a compatible (INT33) high quality native USB mouse driver 
   (none available by now, only some experimental), or rely on BIOS 
   emulation (not always available, or "unprecise").

   Driver: the preferred choice is CTMOUSE from FreeDOS project. There are 
   versions 1.9a1, 2.0a4, and 2.1b4 from 2008-July available. It is 
   included with (but not limited to) FreeDOS, or download a version from 
   here: ibiblio.org/pub/...mouse . None of them is perfect, but still they 
   are well usable and better than most competitors. 1.9xx and 2.1xx will 
   cooperate with BIOS, allowing USB emulation, 2.0xx bypasses BIOS and 
   thus USB emulation will NOT work. Also Logitech mouse drivers usually do 
   a good job, download from here: uwe-sieber.de/util_e.html - version 6.50 
   is a good start. Known for problems are DRMOUSE and some (old ?) 
   versions of MSMOUSE.

   If the mouse does not work at all, then most likely the driver is not 
   loaded, doesn't recognize the mouse (see driver messages), or is not 
   compatible with the INT33 "standard". For USB mouse, activating the "USB 
   mouse emulation" in BIOS settings can help. 

   If the mouse control is "unprecise", the arrow "jumps" , then you either 
   have a bad driver - use a better one, or the BIOS emulation is bad - the 
   solution is to buy a PS/2 mouse then.

21. What about the 64 KiB and 640 KiB problems / how much memory is 
supported by FB in DOS?
   Memory management is business of the DPMI host, rather than the 
   compiler. FreeBASIC and executables generated by it do not suffer from 
   this problem, since they use 32-bit DPMI code, rather than real mode. 
   You can use almost all the memory of your PC, with some limitations, but 
   they are far above 64 or 640 KiB. CWSDPMI r5 is verified to work well up 
   to 512 MiB only, additional memory does not crash it (unlike some older 
   versions), but is silently ignored. HDPMI is supposed to support more: 
   up to 4 GiB (the limit of 32-bit addressing), but there was not much 
   testing on such huge machines - verified up to cca 1.5 GiB. FreeBASIC 
   and code generated by it do not require classical DOS based memory 
   managers (HIMEM/XMS and EMM386/EMS), but are supposed to coexist with 
   them if they are present. All this of course applies to true DOS only, 
   things like "Dos Box" will keep the control over the memory management 
   and provide only a small piece of memory (depends, up to cca 64 MiB) to 
   your DOS code. 

22. My program crashes when I try to use more than cca 1 MiB RAM! Is this a 
bug in FreeBASIC?
   No, it's not a bug in FreeBASIC and it's not really DOS specific, see 
   also Compiler FAQ. For a beginner, the easy solution is to use Shared 
   for arrays. More advanced users could consider using memory management 
   functions like Allocate. This is even more important in DOS, since it 
   allows the application to run on (old) PCs with little memory (and still 
   edit at least small texts for example), as well as to use all huge RAM 
   if available (and edit huge texts for example).

23. Threading functions are disallowed in DOS? Help!
   The Threading Support Functions are not supported for DOS target, and 
   most likely won't be soon/ever. The reason is simple: neither the DOS 
   kernel, nor the DPMI host/standard, nor "GO32" DOS Extender support 
   threading, unlike the Win32 or Linux kernel. However nothing is 
   impossible in DOS: you can set up your threading on the top of DPMI. 
   There are multiple possibilities, two of which are:
      * Set up an ISR, see "ISR_TIMER.BAS" example. This is not a "full" 
        replacement, but sufficient in some cases.
      * There is a pthreads library for DJGPP allowing to "emulate" 
        Linux-like threading to some degree. It works acceptably for 
        [P]7-ZIP DJGPP port (written in C++), no tests with FB yet.
      * See forum t=21274

24. Executables made with FB DOS are bloated!
   This is true but there is no easy/fast way to fix. FB is a 32-bit HLL 
   compiler, and most of the size is imported from DJGPP. !writeme! (see 
   forum: t=11757)

25. Compilation is very slow with FB!
   Problem: "FBC takes 10 seconds to compile a "Hello world" program ! 
   TurboBASIC / QBASIC / VBDOS / PowerBASIC do take < 1 second for the same 
   job ..."

   True, but this is "by design": FB compiles your sources in 3 steps, 
   saving the intermediate files, as described in CompilerCmdLine, while 
   many older compilers do just 1 pass in memory. This is related mostly to 
   file I/O performance, see FAQ 27 below about possibilities of 
   improvements, additionally a small improvement can be achieved here by 
   making the DPMI host resident (HDPMI32 -r or CWSDPMI -p , see FAQ 4 
   above). Note that the delay is mostly "additive" , so it won't hurt too 
   much with bigger projects.

26. SLEEP doesn't work! How can I cause a delay?
   Sleep does work ... but has a resolution of cca 55ms = 1/18s only, thus 
   "SLEEP 500" is fine, while for example using "SLEEP 2" for 2 
   milliseconds won't work. !writeme! / !fixme! 
      * PIT / BIOS timer (runs at 18.2 Hz by default), peek the BIOS timer 
        or set your own, see "ISR_TIMER.BAS" example, raise PIT frequency 
        (use with care)
      * Poll the BIOS timer + PIT counter, method from TIMERHLP.ASM from 
        DKRNL32, allows to enhance precision of above without raising the 
        PIT frequency 
      * RDTSC instruction (Pentium and newer)
      * RTC clock
      * Delay loops

27. The performance is very bad in DOS!
   Problem: "The performance in DOS is poor compared to Win32 / Linux 
   binary compiled from the very same source !" or "Even worse, the very 
   same DOS binary runs much faster in NTVDM than in DOS !"

   Both indeed can happen, nevertheless, DOS is no way predestined to be 
   slow, the inefficiencies can be fixed. First you have to identify the 
   area where you code looses performance. 

      File I/O: DOS by default uses very little memory for its buffers, 
      while other systems use much more and are "aggressive" with file 
      caching. When dealing with many small files, this results in serious 
      performance degrade. The solution is to install a filecache, for 
      example LBACache, or you can install a RAMDISK (a good one: SRDISK ) 
      and copy the "offending" files (for example FreeBASIC installation) 
      there in and work there (make sure to backup your work to a more 
      durable media regularly). Both will need an XMS host (use HIMEMX ). 
      Also DOS by default uses BIOS to access the hard drives, while other 
      systems try hard to find and use DMA. Test util: IDECHECK by Japheth 
      (Download: japheth.de/Download/IDECheck.zip) - run it in "I13" and 
      "DMA" modes and compare results. If "DMA" is much faster (can be 
      1...10 times, depends from PC model), then installing a DOS DMA 
      driver (for example XDMA 3.1 is worth to try) can bring a big speedup 
      on large files. Also make sure to read and write data in large pieces 
      (16 KiB at least), not just single bytes. Other OSes are more 
      forgiving here, but on DOS every single file I/O call causes a small 
      "additive" delay, thus an efficient code design with good buffering 
      is crucial.

      Graphics: Pentium 2 and newer CPU's have a cache related feature 
      called "MTRR" to speed up writes to video RAM. Drivers of other OSes 
      usually do enable it.  DOS doesn't (since it doesn't deal with 
      graphics at all), neither does FB GFX. Use "VESAMTRR" tool by Japheth 
      (contained in "HXGUI.ZIP" package), it will enable the speedup, 
      surviving also mode switches and most "non-fatal" application 
      crashes, up to a reboot. The possible speedup factor varies much 
      depending from the PC model, up to cca 20 times. Also the mouse 
      handling eats some (too much) CPU performance on DOS, this is a known 
      weak point (the design of DOS FB GFX is not "very bad", it's just the 
      common "standard" - which is not very good), fixing is theoretically 
      possible but not easy, you just can try several mouse drivers (see 
      FAQ 20).

28. Can I access disk sectors with FB?
   You can ... but FreeBASIC won't help you too much here: no "portable" 
   solution, use OS specific low level way. For DOS 3 methods are possible 
      * Use logical disk access features of DOS for sector access 
        bypassing the filesystem, see example in the forum: 
        freebasic.net/forum/viewtopic.php?t=11830
      * Use physical disk BIOS INT 13, bypassing DOS
      * Use CPU ports, lowest level, bypassing both DOS and BIOS, see 
        forum freebasic.net/forum/viewtopic.php?t=16196, source of IDECHECK 
        from FAQ 27 above, FASM forum or some OS development resources
   Note that such experiments are a bit "dangerous" - you can easily lose 
   data or make your PC unbootable if something goes wrong.

29. Can I use inline ASM with advanced instructions like SSE in DOS ?
   You can ... but SSE2 and above need to get enabled before. This is 
   usually considered as business of the DPMI host, HDPMI32 and CWSDPMI 7 
   will do that, most other hosts won't. Make sure to properly CPUID for 
   such instructions before using them. It's a good idea to provide a code 
   branch compatible with older CPU's (early Pentium, 80386) besides 
   supporting latest instructions, and to avoid CMOV in those too.

See also
   * Compiler FAQ.
   * FB Runtime Library FAQ.
   * Frequently Asked FreeBASIC Graphics Library Questions



------------------------------------------------------------ FaqPgWin32 ----
Windows Related FAQ

Windows:

   - Which IDEs are available for Windows?
   - Can I get rid of the console / 'DOS' screen in a graphics application?
   - My GUI program does nothing when run / The program compiles but I get a permission denied error in the linker
   - How can I debug my program?
   - Why Windows refuses to run my code using OUT and/or INP?
   - I get the error 'Cannot start blah.exe because xxxx.dll was not found.' or similar. What is missing?
   - Does FreeBASIC work with Windows Vista/7?
   - Where can I find some tutorials on programming the Windows GUI?
   - Are there Windows GUI code builders for FB?	

FreeBASIC Windows questions

Which IDEs are available for Windows?

   At the moment three full featured IDEs have been developed specifically 
   for FB: FBIde (not being updated, avoid using of old versions of FBC 
   bundled with it), FbEdit and WinFBE Editor. These IDEs require a minimum 
   configuration -as path to the compiler- to work. 
   You can also download  FBIde and FbEdit as bundles  (Editor + Compiler) 
   that install in a single operation. But the bundled version of the 
   compiler may be out of date.
   WinFBE Editor (WinFBE_Suite) comes packaged with the latest FB Compiler. 
   It is an all-in-one solution. 
   Commercial "general use" IDEs can be used with FreeBASIC but may require 
   an extensive setup. They are handy for multi language programming, as 
   they provide a unified user interface.
   Instructions for installing WinFBE, FBIde, and FbEdit can be found here:
      - IDE Installation guide for Windows

Back to top	

Can I get rid of the console / 'DOS' screen in a graphics application?
   Yes. You have to give FreeBASIC the right command for it when you 
   compile your program.
   * If you compile from a command prompt, simply add "-s gui" to the end, 
     like "fbc myprg.bas -s gui"
   * If you compile in a specific IDE, you have to edit the "Compiler 
     Defaults". 
      * In WinFBE, its "Options->Build Configurations". Add "-s gui" (NO 
        QUOTES) for the build of your choice.
      * In FbEdit select Windows GUI in the targets dropdown list in the 
        right of the tool bar.

Back to top

My GUI program does nothing when run / The program compiles but I get a 
permission denied error in the linker
   The problem may be related with the previous question. If a program 
   tries to PRINT and it was compiled with "-s gui" it will freeze because 
   no console is available. If the PRINT is issued before the first window 
   is registered/opened, nothing will show in the screen or in the taskbar. 
   The running program can only be seen in (and killed from) the task 
   manager's processes tab. If a new compilation is tried  before killing 
   the process it will give a "Permission denied" error when the compiler 
   tries to modify a still running .exe.
   In Windows GUI programs do not use console commands. Use MessageBox or 
   print to a log file to issue any error message to the user. Be sure any 
   PRINT to console you used for debugging is not compiled in the final 
   version. 

Back to top

How can I debug my program?
   FreeBASIC can use any debugger compatible with GNU GDB. Insight Win32 
   debugger is an user friendly wrapper for GDB. 
   * Get Insight from Dev-C++
   * Rename the file to Insight.tar.bz2, and decompress it to an empty 
     folder
   * Compile your program with the -g switch
   * Run <Your_Insight_Dir>\bin\usr\bin\Insight.exe
   * Do File>Open to load your program into Insight
   * From there you can watch, set breakpoints, step, examine memory and 
     registers. Check Insight's help

Back to top

Why Windows refuses to run my code using OUT and/or INP?
   Windows requires a driver to be installed to access the hardware ports. 
   FB-Win32 programs using INP and OUT include a built-in driver that 
   installs temporarily for a session. Windows allows only users with Admin 
   rights to run driver installations. This means if you usually run your 
   windows sessions without Admin rights, you will have to use the windows 
   command line command RUNAS to run your program for the first time in 
   each session so Windows allows it to install the driver.
   If this behavior is not acceptable you can use an external library as 
   PortIO32 that installs a permanent port driver.

Back to top

I get the error 'Cannot start blah.exe because xxxx.dll was not found.' or 
similar. What is missing?
   You are trying to run a program using a third party library that resides 
   in a dll not installed in your system.
   FreeBASIC comes with headers and wrappers required to code for a lot of 
   third party libraries but does not provide the actual runtime dll files.
   You have to download and install these from their home page. Find in 
   the Links thread in the Libraries subforum the URL's of the home pages 
   of the libraries provided. You need the binaries for Win32 of the 
   libraries. If you want to develop programs with the libs you will need 
   the documentation too.
   When releasing compiled code it is good etiquette to provide the third 
   party dll's required to run it.

Back to top

Does FreeBASIC work with Windows Vista/7?
   Yes. (Write me!!!)

Back to top

Where can I find some tutorials on programming the Windows GUI?
   See the answers to this question in this thread in the forum
   More advanced use requires a frequent consultation of the reference at 
   the Microsoft Developers Network. A local install of the API reference 
   is possible, search Microsoft for the Platform SDK (a huge download) and 
   install just the documentation.

Back to top

Are there Windows GUI code builders for FB?	
   Yes there are some 3rd party developments generating Windows API code 
   from a windows designer &agrave; la Visual Basic:
   WinFBE Editor (open source) full visual designer similar to Visual 
   Basic.
   Jerry Fielden' Ezeegui (freeware) uses a "graphical" textmode interface 
   to let you build your code.
   mrhx Software's VISG (GPL) has a more classical user interface.
   Less helpful may be the graphical resource editors generating scripts 
   for the resource compiler. Any editor generating scripts compatible with 
   GoRC can be used, as the  one included with FbEdit. Graphical resource 
   editors are a great help in designing dialogs and menus, but they leave 
   to you the task of writing the window procedures required to make them 
   active.

Back to top

See also
   Compiler FAQ
   FB Runtime Library FAQ



------------------------------------------------------------ FaqPgLinux ----
Linux Related FAQ

FreeBASIC Linux questions:

   - FreeBASIC gives me an error 'ld: can't find -lX11' or something similar!
   - How do I install FreeBASIC in Ubuntu?

FreeBASIC Linux questions

FreeBASIC gives me an error 'ld: can't find -lX11' or something similar!
   FreeBASIC uses ld to link its files under linux. This program requires 
   that any libraries you use have the '-dev' versions installed. For 
   example, for the above error message, you'd want to install xlib-dev for 
   your distribution. Other common errors are for glibc, which requires 
   glibc-dev, and sdl, which requires sdl-dev. Most distributions make 
   these easily available on your install media.

Back to top

How do I install FreeBASIC in Ubuntu?"
   See This thread in the FB forums 

Back to top

See also
   Compiler FAQ
   FB Runtime Library FAQ





============================================================================
  MISCELLANEOUS
  -------------


--------------------------------------------------------- ObsoletedKwds ----
Obsolete Keywords

   Along the way FB has had a few keywords changed. Here is the list of 
   those no longer supported. Old code must be updated if recompiled.

   OPEN "CON:" 
      Use Open Cons    
   OPEN "ERR:" 
      Use Open Err 
   OPEN "PIPE:" 
      Use Open Pipe 
   POKEI  
      Use Poke (Integer,Address,N)  
   POKES 
      Use Poke (Short,Address,N) 
   SCREENINFO (Function returning a pointer to a structure)  
      Use Screeninfo, Sub Returning Values In Its Arguments
   VAL64  
      Use Vallng() 
   GOSUB
      Do not use GoSub in SUBs or FUNCTIONs anymore; allowed in -lang qb 
      mode.


--------------------------------------------------------- GlossaryIndex ----
Glossary

Brief definitions and explanations for words and phrases used in the FreeBAS
IC manual.

Index: A - B - C - D -  E -  F -  G -  H -  I -  J - K - L - M - N - O - P 
- Q - R - S - T - U - V - W - X - Y - Z

 A

abstract member function
   A member function without body that must be overridden by a member 
   function of a type more derived than the type it was declared in. See 
   Abstract (Member).

access rights
   The level of access associated with Type or Class members. Public 
   members are accessible to any code; protected members are accessible to 
   member functions and any derived Type or Class member functions; private 
   members are accessible only to member functions of that Type or Class. 
   By default, Type members have public access rights, while Class members 
   are private.

any pointer
   A variable or expression that points to a memory address where it is not 
   known, at least from the compiler's point of view, what type of data is 
   stored at that address.  In C this would be the same as a void pointer 
   or (void *).  See Ptr.

archive
   An archive is a group or files or a single file packed into a container 
   format and usually compressed before or afterward. Typical container 
   formats are GNU Tar and Zip. Typical compression formats are Gzip and 
   Zip.

argument
   Data that is passed to a procedure. The procedure refers to this data 
   using the parameter(s) in its parameter list.

argument passing convention
   The method in which arguments are passed to procedures, being either 
   By Reference or By Value.  See Passing Arguments to Procedures.

array (container)
   A collection of data whose elements are stored contiguously in memory 
   (one after the other, in increasing order). Because of this, an array 
   offers random-access to its elements (any element can be accessed at any 
   time). Insertion or removal of elements anywhere but at the back of the 
   container requires that those elements that follow be relocated, so a 
   linked-list is typically preferred when insertion or removal needs to be 
   efficient.

assembler
   A component in the tool chain for translating source code in to 
   executable programs.  The assembler converts the low level assembly 
   instruction mnemonics emitted by the compiler to object code.

assignment
   Assignment is one of the fundamental operations of computing.  All it 
   means is copying a value into the memory location pointed at by a 
   variable.  The value might be a literal, another variable, or the result 
   of some expression. For an instance of a Type or Class, this involves 
   calling one of its assignment operators. Not to be confused with 
   initialization.

automatic storage
   Refers to storage on the call stack. Local procedure variables, objects 
   and arrays with automatic storage are allocated when the procedure is 
   called, initialized when defined, destroyed (in the case of objects) 
   when leaving the scope they're declared in and deallocated when 
   returning from the procedure.

automatic variable/object/array
   A variable, object or array with automatic storage.

Back to top

 B

byref
   ByRef specifies passing arguments to procedures by reference. Arguments 
   passed by reference can be modified by the procedure and the changes 
   seen by the caller.

byval
   ByVal specifies passing arguments to procedures by value. Procedures 
   receive a copy of the argument passed. With Type or Class instances, 
   this involves instantiating temporary objects by calling their copy 
   constructor. These temporaries are destroyed upon procedure exit.

binaries
   Binaries are the end result of source code. Binaries include executable 
   files (.exe on windows), static library files (.a), dynamic library 
   files (.dll on windows, .so on Linux), and relocatable object files. 
   (.o)

.BSS section
   The part of the executable program that will contain zero bytes only 
   when the program starts.  Since all of the bytes are zero, the final 
   size of the executable can often be reduced by placing uninitialized 
   data, or zero initialized data in this section.

buffer
   A region of memory that allows data to be saved or manipulated before 
   being copied somewhere else.  In a communications device this may hold 
   incoming or outgoing data yet to be processed.  In graphics, a buffer 
   may contain an image before being copied to the screen.

Back to top

 C

call back
   A control mechanism where a caller lets a procedure call another 
   procedure (the call back) provided by the caller typically through a 
   function pointer.

call stack
   A chunk of memory reserved for a process or thread that is used as a 
   stack for storing various information needed by procedures when they are 
   called. Among the information stored on the call stack are all of the 
   local automatic variables, objects and array data and usually whatever 
   parameters are passed to the procedure. These items are allocated (
   pushed onto the call stack) when the procedure is called and deallocated 
   (popped from the call stack) when the procedure returns, either by the 
   caller or the callee, depending on the calling convention used. The 
   initial and maximum sizes of this reserved memory vary by platform.

caller
   A misnomer used to refer to the point in code in which a procedure is 
   called.

cast
   A cast operation changes one data type to another using specified rules. 
   A Type structure can implement a custom Cast for any intrinsic data 
   type, and/or other TYPEs, See Cast.

code block
   Several lines of source code grouped together all sharing at least one 
   common scope.  For example a procedure's code block will be all the 
   lines of code between Sub and End Sub.

com port
   A short name for serial communications port.  A program can communicate 
   with an external device, such as modem or another computer through a com 
   port (nowadays the good old com ports are deprecated in favor of USB).  
   See Open Com.

compiler
   A compiler is a computer program which takes source code and transforms 
   it into machine or object code.

compiler directives
   These are instructions included in the text of the program that affect 
   the way the compiler behaves.  For instance the compiler might be 
   directed to include one section of code or another of depending on the 
   target operating system.

compound statement
   A statement composed one or more additional statements. Typically, a 
   compound statement has a beginning (opening statement), a middle (a 
   statement block) and an end (closing or ending statement), while some 
   have additional parts. Examples of compound statements would be If and 
   Function.

constant
   A symbol that retains a consistent value throughout the execution of the 
   program. See Const.

constructor (module)
   A special type of module-level procedure that is automatically called 
   prior to the module-level code flow. See Constructor (Module).

constructor (TYPE or CLASS)
   A special member function of a Type or Class that is called when an 
   object is instantiated.

contravariance (TYPE or CLASS)
   A typing rule for Type or Class that allows you to use a more generic 
   (less derived) type than the one originally specified.

covariance (TYPE or CLASS)
   A typing rule for Type or Class that allows you to use a less generic 
   (more derived) type than the one originally specified.

CVS
   Concurrent Versions System. The file manager implemented at Sourceforge 
   where sources are stored, it keeps the history of the changes introduced 
   by the developers.  Used by FB in the past. (see also SVN and GIT)

Back to top

 D

.DATA section
   The part of the executable program that will data that can be changed 
   while to program is running.

debugger
   A program that allows controlled execution of compiled code. The values 
   of variables can be tracked, execution can be paused, stepped or 
   accelerated, etc. A debugger is typically used to help find the source 
   of programmer errors in source code, called 'bugs'.

declaration
   A source code statement that introduces a symbol, constant, variable, 
   procedure, data type, or similar, to the compiler but not necessarily 
   allocate any space for it.  See Dim, Declare, Extern, Type.

definition
   A source code statement (or statements) that allocates space for data or 
   code.  For example, Sub defines a procedure by allocating space for the 
   program code it will contain.  Some statements can be both a declaration 
   and a definition.  For example, Dim both declares and defines a 
   variable.

dereference
   The act of accessing (in read and in write) a variable stored at a given 
   address. See Operator * (Valueof), Pointers.

descriptor
   Refers to the internal data structure used by the compiler and runtime 
   library for managing variable length strings and arrays.

destroy (TYPE or CLASS)
   The act of deconstructing and deallocating memory for an object 
   instance. When an object is destroyed, its destructor is called. This 
   happens automatically when an object goes out of scope, or when 
   Delete (Statement) is called with a pointer to an object.

destructor (module)
   A special type of module-level procedure that is automatically called at 
   program termination. See Destructor (Module).

destructor (TYPE or CLASS)
   A special member function of a Type or Class that is called when an 
   object is destroyed.

dll
   Shorthand for dynamically linked library.

DPMI
   A method / standard allowing to execute protected mode code (mostly also 
   32-bit) on a 16-bit real mode DOS kernel. Affects only DOS version of 
   FreeBASIC. See also DOS related FAQ 

DJGPP
   A complete 32-bit C/C++ development system for Intel 80386 (and higher) 
   PCs running DOS and includes ports of many GNU development utilities.

dynamically linked library
   A file containing executable code that is loaded by another application 
   when it is started.  Also referred to as a dll or shared library.  See 
   Shared Libraries (DLLs).

Back to top

 E

enum
   A data type restricted to a sequence of named values given in a 
   particular order. See Enum.

executable
   A binary file that can be run. It consists of libraries and object files 
   bound together by the linker.

exit sub/function
   When called inside a procedure, leaves the procedure and returns control 
   to the calling program.

expression
   An instruction to execute a statement that will evaluate/return a value.

Back to top

 F

field
   Commonly refers to a data member in a Type or Class.

file number
   An integer associated with an open file or device as given in Open.  All 
   subsequent operations on the opened file or device must use the same 
   file number.

format string
   A sequence of characters that controls how data should be presented.  
   See Format, Print Using.

function
   A procedure defined using Function, optionally taking parameters and 
   returning a value.

function pointer
   A variable containing the address of a function.  The address (function) 
   to which the variable points can be changed while the program is running 
   allowing for dynamic program flow, such as call back functions.

Back to top

 G

get/put buffer
   See: Image Buffer. An image buffer in FreeBASIC's native format.

GIT
   The file manager implemented at Sourceforge where sources are stored, it 
   keeps the history of the changes introduced by the developers.  Used by 
   FB now. (see also CVS , SVN and GIT).

global variable
   A variable that is visible to all procedures within a module, across 
   multiple modules, or both. See Common and Extern.

GNU
   A mass collaboration project with the primary goal to provide a free and 
   non-proprietary Unix-like operating system.

GPL
   Short hand for GNU General Public License: a license for software and 
   other kinds of works. Open source, obligates the user to keep the 
   project open source and under the GPL.

graphics primitive
   A graphics primitive is another term for common shapes like circles and 
   rectangles.

Back to top

 H

hash table
   A data structure that associates keys with values allowing for efficient 
   look-up of values based on a given key.

header
   When talking about a collection of data, this is generally the first 
   part of that data that describes the rest. When talking about (header) 
   files, this refers to an include file. In FreeBASIC the file extension 
   '.bi' is usually used.

heap
   The area of memory (free store) provided by the runtime library (and 
   operating system) from which the program can dynamically allocate 
   memory.  See Allocate.

Back to top

 I

image buffer
   A collection of data used to describe an image, containing such 
   information as width, height, color depth and pixel data.

include file
   A kind of source file that typically contains type definitions and 
   declarations for variables and procedures that one or more other source 
   files refer to. In general, these files provide a public interface to 
   some module or modules, although a file that is #included can contain 
   any text whatsoever.

inheritance (TYPE or CLASS)
   Inheritance is when deriving a type from a base type, by using the 
   Extends declaration. Members of the base type become members of the 
   derived type. Private members of a base type are never directly 
   accessible from a derived type, but can be accessed through calls to the 
   Public and Protected members of the base type.

initialization
   The act of giving a variable a value at the point of its creation. For 
   object instances, this involves calling one of its constructors. Not to 
   be confused with assignment, which gives an already existing variable 
   another value.

instance
   An instantiated object of a Type or Class.

instantiate
   The act of creating an object of a Type or Class, either directly with 
   Dim, or indirectly by, for example, passing an object to a procedure by 
   value.

invariance (TYPE or CLASS)
   A typing rule for Type or Class that requires you to use exactly the 
   same type as the one originally specified.

Back to top

 J

Back to top

 K

Back to top

 L

library
   Compiled code stored in a single file that can be used when making other 
   programs.  A library typically has one or more headers (or include 
   files) to provide all the needed declarations for using the library.

linked list (container)
   A collection of data whose elements are typically stored on the heap. 
   The linked list's elements store the addresses of their adjacent 
   elements, and so only sequential access (an element is accessed by 
   following the links from adjacent elements) is possible. This scheme 
   does provide constant-time insertion of elements anywhere into the 
   container, however, and because of this is often preferred over the 
   array.

linker
   A program which combines multiple modules and libraries into a single 
   executable which can be loaded into the computer's memory and followed 
   by the computer. FreeBASIC uses the LD linker. Linkers are the most 
   common, but not the only way to produce executables.

LGPL
   Shorthand for GNU Lesser General Public License.  Like the GNU GPL, but 
   more permissive allowing non-(L)GPL'd works to be statically linked to 
   the LGPL'd work, provided that the new work can have the LGPL'd portion 
   relinked or replaced.

LHS
   Acronym for "Left Hand Side".

local variable
   A variable that is visible only within the scope in which it is 
   declared, and that is destroyed when program execution leaves that 
   scope.

lock
   A synchronization mechanism such that only one thread or process can 
   have access to a shared object, for example a global variable, a device, 
   or a file.

Back to top

 M

member
   A data field, procedure, enumeration, type alias or anything else 
   declared within a Type or Class definition.

member data
   Variables associated with a Type or Class. Member data can be static or 
   non-static.

member function
   A procedure associated with a Type or Class. Member functions have full 
   access rights to the members of its type or class, and can be static or 
   non-static.

method
   See member function.

module
   A source file in its entirety, including any include files that may be 
   present as well. Typically, a module is a logical unit of code, 
   containing parts of a program that relate to one another. For example, 
   if making a game, one may separate the procedures needed for error 
   logging from the procedures that control graphics into their own 
   modules.

Back to top

 N

non-static member data
   Member data that each instance of a Type or Class gets their own copy 
   of.

non-static member function
   A member function that has an implicit This reference as an argument.

null
   A constant usually associated with pointers denoting a 'nothing' value. 
   This value is typically an integer '0' (zero) - the 'NULL terminator' 
   appended to zstrings is chr(0), or asc(!"\0") - but can also be defined 
   as a pointer type, like Cast(any ptr, 0).

Back to top

 O

object (built-in TYPE or CLASS)
   Object is a built-in type which provides Run-Time Type Information 
   (RTTI) for all types derived from it using the Extends declaration, 
   allowing them to be used with Operator Is, and to support Virtual and 
   Abstract member functions.

object code
   Code in machine-readable form that can be executed by your computer's 
   CPU and operating system, usually linked with libraries to create an 
   executable file.

operand
   One of the arguments passed to an operator.  For example, in the 
   expression a = b + c, the operands are a, b and c, while the operators 
   are = and +.

operator
   A function taking one or more operands (arguments) and returning a 
   value.  Operators can work on built-in data types, or can be overloaded 
   to work on user defined types.  See Operators.

overload
   To declare a procedure having the same name as another, but with 
   different parameters. Free functions, or module-level functions, can be 
   overloaded using the Overload keyword. Type or Class member functions 
   can be overloaded by default.

override
   Attribute to specify that a member function must override a Virtual or 
   Abstract member function of a type less derived than the type it was 
   declared in. Using the Override attribute, the compiler will show an 
   error if the member function does not override anything.

Back to top

 P

page buffer
   A buffer used for holding the contents of the screen before being 
   displayed on screen.  Where multiple page buffers are allowed, one page 
   will be visible to the users while all others are hidden.  Also the 
   active page (the one to which changes are made) need not be the visible 
   one allowing changes to one page while showing another.

parameter
   The name used by a procedure that corresponds to the argument that is 
   passed to it.

parameter list
   The parenthesized comma-separated list of parameters in a procedure 
   declaration or definition.

PDS
   Professional Development System.  Sometimes referred to as QB7.1.

pitch
   The number of bytes per row, in an image or screen buffer.  If there is 
   no padding between rows, then this can be calculated by width * 
   bytes_per_pixel, but this is not necessarily safe to assume.  The 
   screen's pitch can be found using ScreenInfo, and an image buffer's 
   pitch can be found by checking the pitch value in the image's header.

pointer
   A data type used to hold addresses. The kind of pointer determines how 
   the data at the address is interpreted when the pointer is dereferenced, 
   or when used with Operator -> (Pointer To Member Access). See Pointers.

polymorphism (TYPE or CLASS)
   Polymorphism is the ability of an object to provide different behaviors 
   (use different implementations) depending on its own nature, 
   specifically depending on position of its real type in the inheritance 
   hierarchy. Polymorphism is achieved by overriding Virtual or Abstract 
   member functions of the base type.

preprocessor
   The FreeBASIC preprocessor is responsible for expanding Macros and 
   replacing Defined values with their values.

procedure
   A generic name for any block of code that can be called from somewhere 
   else in a program.  See Sub, Function.

property
   A property is a special sort of type/class members, intermediate between 
   a field (or data member) and a method. See Property.

ptr
   Shorthand for pointer. See pointer.

Back to top

 Q

queue (container)
   A collection of data that offers first-in first-out (FIFO) storage and 
   retrieval. Typically, elements can only be inserted at the back and 
   removed from the front but can be accessed from either end.

Back to top

 R

ragged array (container)
   A ragged array is an array having rows of differing lengths.

real number
   Any positive or negative number including fractions, irrational and 
   transcendental numbers (like pi or e) and zero.  Variables containing a 
   real number have a limited range and precision depending on the number 
   of bits used to represent the number.  See: Single and Double.

reference
   A reference is an entity that is a way to access (in read and in write) 
   data at memory location. A reference can be thought of as a pointer 
   having as value the memory location, and which is implicitly 
   dereferenced.  See: Byref (Variables).

registers
   Places inside the CPU for data storage. 80386 and compatible 32-bit 
   models have EAX, EBX, ECX, EDX, ESI, EDI, EBP and ESP, plus some special 
   (control/test/debug) registers. NOT related to "Windows registry".

RHS
   Acronym for "Right Hand Side".

RTTI
   Acronym for "Run-Time Type Information". The Object built-in type 
   provides the RTTI capacity for all types derived from it using the 
   Extends declaration, allowing them to be used with Operator Is, and to 
   support Virtual and Abstract member functions.

Back to top

 S

scope
   Refers to the life-time and visibility of some component of the program, 
   like a variable or a procedure.  For example, a variable defined inside 
   a procedure would have procedure scope: it is visible throughout the 
   procedure, but not outside the procedure's code block.  When the 
   procedure ends, the variable goes out of scope and no longer exists.

scope block
   A code block where all the lines of source have the same scope.  An 
   explicit scope block can be indicated with the Scope statement.  Scope 
   blocks may also be implicit with the usage of If..Then, For..Next, and 
   other compound statements.

shared library
   A library that exists once on a system that multiple executables can 
   link to at runtime. See Shared Libraries (DLLs).

source code
   Code written by the programmer, in a human-readable form, not yet 
   compiled.

stack (container)
   A collection of data that offers last-in first-out (LIFO) storage and 
   retrieval. Typically, elements can only be inserted, accessed and 
   removed from the top of the stack.

statement block
   One or more lines of code bookended by a compound statement.

static library
   A library that is linked into a program at link time. There is one copy 
   of the library for each executable that links to it. All data is 
   executable specific. See Static Libraries.

static member data
   Member data that each instance of a Type or Class shares. This data is 
   defined outside of any Type or Class, and takes up no space in the 
   resulting object instance.

static member function
   A member function without an implicit this reference as an argument. 
   Static member functions can be called normally through a variable, or 
   directly using the type's name and the scope resolution operator See 
   Static (Member).

static storage
   Refers to storage in the .BSS or .DATA sections of an executable. 
   Variables, objects and arrays with static storage are allocated and 
   initialized at compile-time and destroyed (in the case of objects) and 
   deallocated at program-termination. Explicitly initialized variables, 
   objects and arrays are allocated in the .DATA section.

static variable/object/array
   A variable, object or array with static storage.
   Note: Some times, we talk about 'static array/string' (as opposed to 
   'dynamic array/string'), but here, the 'static' term applies on the size 
   of the array/string (fixed length as opposed to 'dynamic' term for a 
   variable length) .
   Thus this 'static/dynamic' term does not apply on the storage type for 
   data.

sub
   A procedure defined using Sub, optionally taking parameters and not 
   returning a value.

SVN
   Subversion. A version control system that allows users to keep track of 
   changes made to sources and documents. Used by FB in the past. (see also 
   CVS and GIT)

SWIG
   A tool that automatically translates C headers to FreeBASIC (although 
   not always perfectly).

symbol
   Used to refer to variables, labels, functions, methods, procedures, or 
   other programmatic constructs in a program.

Back to top

 T

.TEXT section
   The part of the executable program that will contain program 
   instructions and constant data.

this reference
   A reference to an instance of a Type or Class that is passed as a hidden 
   argument to non-static member functions of that type or class. 
   Throughout the member function, this instance is referred to using the 
   this keyword, See This.

thread
   A thread of execution within a process (running program) that shares 
   execution time with other threads in the same process.  See Threading.

trace
   To follow the execution of a program step-by-step either manually by 
   examining the source code, or more practically with a debugger.

Back to top

 U

union
   A structure that can be used to store different types of variables, such 
   as integers, doubles and fixed-length strings in the same location, but 
   only one at a time.  See Union.

user defined data type
   A Type, Union, Enum, or Class data type.

Back to top

 V

variable
   A symbol representing data in memory.

VBDOS
   Visual BASIC for DOS, a historical BASIC compiler by M$ from 1992, 
   following after QBASIC. DOS platform dropped very soon, VBDOS never 
   became popular.

vector
   A series of data items in memory that can be accessed by an index 
   number.  Similar to an array except that vector elements are not 
   necessarily all contained within a single block of memory.

virtual member function
   A member function that can be overridden by a member function of a type 
   more derived than the type it was declared in. See Virtual (Member).

Back to top

 W

warning
   A message displayed by the compiler during compilation that suggests 
   there may be potential problems with the current code.
   
wiki
   An on-line system that provides a set of pages containing information 
   that can be viewed and modified by the public. In this context, it is 
   typically used to refer to the FreeBASIC on line documentation.

Back to top

 X

x86
   Refers to the instruction set compatible with the 8086 (and later) CPU 
   architecture, FreeBASIC only supports 80386 and later.

Back to top

 Y

Back to top

 Z

zstring
   A zstring is in essence a standard C style string terminated by a null 
   character. This data type is provided for greater compatibility with C 
   libraries.

Back to top



------------------------------------------------------------- CatPgMisc ----
Miscellaneous Keywords

Data
   * Data
   * Read
   * Restore

Debugging
   * Assert
   * AssertWarn
   * Stop

Hardware Access
   * Inp
   * LPrint
   * LPos
   * Out
   * Wait

Operating System
   * Beep
   * Sleep
   * End (Statement)

Stub Pages
   * As
   * For
   * To
   * Is
   * Step
Control Flow
   * Do
   * End If
   * IIf
   * Loop
   * Next
   * Then
   * Until
   * Wend
   * While

Uncategorized
   * End (Block)
   * OffsetOf
   * SizeOf
   * TypeOf
   * Let
   * Rem
   * Option()



--------------------------------------------------------- ProPgCruntime ----
C Standard Library Functions

This is a list of function prototypes in the standard C library in 
alphabetical order and a list of prototypes grouped by functionality. 

Alphabetical List
Buffer Manipulation
Character Classification and Conversion
Data Conversion
Directory Manipulation
File Manipulation
Stream I/O
Low level I/O
Mathematics
Memory Allocation
Process Control
Searching and Sorting
String Manipulation
Time

Description
   The Comments column contains a very brief description of the use of the 
   function. The list is not complete, however it provides information on 
   the major functions in the C Runtime Library. It should, at the very 
   least, indicate what functions are available in the standard C library 
   allow you to do more investigation on your own.  Some of the C library 
   functions documented elsewhere may not be available in FreeBASIC.  Check 
   the appropriate include file for more information. 

   Note: The following prototypes are not the official FreeBASIC prototypes 
   (see the include files), however, they will give you enough information 
   to properly use the functions. 

   The Include File column contains the name of the file which you must 
   include, using the #include directive at the beginning of your program. 
   If you don't include the appropriate include file, the program either 
   will not compile, or it will compile apparently correctly but give 
   incorrect results when run.  All of the C Runtime headers are located in 
   the crt directory; for example, if the specified header is math.bi, use 
   #include "crt/math.bi" or #include "crt\math.bi", our just #include 
   "crt.bi" including all the others.

   The Prototype column contains the following information: 
      * The name of the function; 
      * The parameters required for the function in parenthesis, together 
        with the data-type of the parameters; 
      * The data-type of the value returned by the function. 

   For example atoi(a as zstring ptr) as integer means that the function 
   atoi returns a value of type integer and requires a character zstring 
   ptr as its argument. 

   Note: In order to make calling the C runtime functions very easy, any 
   string type argument may be directly passed to a procedure referring to 
   a parameter declared as 'zstring ptr'. The compiler performs itself an 
   automatic conversion (without warning message) between any string type 
   argument and the 'zstring ptr' type parameter.

Alphabetical List

      +--------+----------------------------------------------------------------------------+------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
      |Name    |Prototype (with parameters)                                                 |Include File|Comments                                                                                                                                                                                                      |
      |abs_    |abs_(n as integer) as integer                                               |stdlib.bi   |Returns the absolute value (i.e. positive value)                                                                                                                                                              |
      |acos_   |acos_(a as double) as double                                                |math.bi     |Returns the inverse cosine (angle in radians)                                                                                                                                                                 |
      |asin_   |asin_(a as double) as double                                                |math.bi     |Returns the inverse sine (angle in radians)                                                                                                                                                                   |
      |atan_   |atan_(a as double) as double                                                |math.bi     |Returns the inverse tan (angle in radians)                                                                                                                                                                    |
      |atan2_  |atan2_(y as double, x as double) as double                                  |math.bi     |Returns the inverse tan (pass the opposite as y and the adjacent as x)                                                                                                                                        |
      |atoi    |atoi(s as zstring ptr) as integer                                           |stdlib.bi   |Converts a character zstring of digits to a number of type integer.                                                                                                                                           |
      |atof    |atof(s as zstring ptr) as double                                            |stdlib.bi   |Converts a character zstring of digits to a number of type double.                                                                                                                                            |
      |calloc  |calloc(NumElts as integer, EltSiz as integer) as any ptr                    |stdlib.bi   |Allocates memory. Returns a pointer to a buffer for an array having NumElts elements, each of size EltSiz bytes.                                                                                              |
      |ceil    |ceil(d as double) as double                                                 |math.bi     |Returns the nearest whole number above the value passed.                                                                                                                                                      |
      |clearerr|clearerr(s as FILE ptr)                                                     |stdio.bi    |Clears the error indicators on a file stream (read or write).                                                                                                                                                 |
      |cos_    |cos_(ar as double) as double                                                |math.bi     |Returns the cosine of an angle measured in radians.                                                                                                                                                           |
      |cosh    |cosh(x as double) as double                                                 |math.bi     |Returns the hyperbolic cosine of an angle measured in radians.                                                                                                                                                |
      |div     |div(num as integer, denom as integer) as div_t                              |stdlib.bi   |Returns the quotient and remainder of a division as a structure of type div_t.                                                                                                                                |
      |ecvt    |ecvt(x as double) as zstring ptr                                            |math.bi     |Converts a number to a zstring.                                                                                                                                                                               |
      |exit_   |exit_(status as integer)                                                    |stdlib.bi   |Exits a program. It will flush file buffers and closes all opened files, and run any functions called by atexit().                                                                                            |
      |exp_    |exp_(a as double) as double                                                 |math.bi     |Returns the value of e raised to the power of the argument (Inverse to natural logarithm).                                                                                                                    |
      |fabs    |fabs(d as double) as double                                                 |math.bi     |Returns the absolute value (i.e. positive value) of type double.                                                                                                                                              |
      |fclose  |fclose(s as FILE ptr) as FILE ptr                                           |stdio.bi    |Closes a file. Returns 0 if successful otherwise EOF.                                                                                                                                                         |
      |feof    |feof(s as FILE ptr) as integer                                              |stdio.bi    |Returns value of end-of-file indicator . (0 if not eof). Indicator will clear itself but can be reset by clearerr().                                                                                          |
      |ferror  |ferror(s as FILE ptr) as integer                                            |stdio.bi    |Returns error indicator for a stream (0 if no error). Error indicator is reset by clearerr() or rewind().                                                                                                     |
      |fflush  |fflush(s as FILE ptr) as integer                                            |stdio.bi    |Flushes (i.e. deletes) a stream (use stdin to flush the stream from the keyboard). Returns 0 if successful.                                                                                                   |
      |fgetc   |fgetc(s as FILE ptr) as integer                                             |stdio.bi    |Single character input (in ASCII) from passed stream (stdin for keyboard).                                                                                                                                    |
      |fgetpos |fgetpos(s as FILE ptr, c as fpos_t ptr) as integer                          |stdio.bi    |Saves the position of the file pointer on stream s at the location pointed to by c.                                                                                                                           |
      |fgets   |fgets(b as zstring ptr, n as integer, s as FILE ptr) as zstring ptr         |stdio.bi    |From the stream s reads up to n-1 characters to buffer b.                                                                                                                                                     |
      |floor   |floor(d as double) as double                                                |math.bi     |Returns the nearest whole number below the value passed.                                                                                                                                                      |
      |fmod    |fmod(x as double, y as double) as double                                    |math.bi     |Calculates the remainder of x divided by y.                                                                                                                                                                   |
      |fopen   |fopen(file as zstring ptr, mode as zstring ptr) as FILE ptr                 |stdio.bi    |Opens a file. Pass the DOS name of the file and a code to indicate whether for reading, writing, or appending. Codes are r for read, w for write, + for read and write, a for append and b to indicate binary.|
      |fprintf |fprintf(s as FILE ptr, fmt as zstring ptr, ...) as integer                  |stdio.bi    |Prints on stream s as many items as there are single % signs in fmt that have matching arguments in the list.                                                                                                 |
      |fputc   |fputc(c as integer, s as FILE ptr) as integer                               |stdio.bi    |Outputs the single character c to the stream s.                                                                                                                                                               |
      |fputs   |fputs(b as zstring ptr, s as FILE ptr) as integer                           |stdio.bi    |Sends the character stream in b to stream s, returns 0 if the operation fails.                                                                                                                                |
      |fread   |fread(buf as any ptr, b as size_t, c as size_t, s as FILE ptr) as integer   |stdio.bi    |Reads the number c items of data of size b bytes from file s to the buffer buf. Returns the number of data items actually read.                                                                               |
      |free    |free(p as any ptr)                                                          |stdlib.bi   |Frees the memory allocation for a pointer p to enable this memory to be used.                                                                                                                                 |
      |freopen |freopen(file as zstring ptr, mode as zstring ptr, s as FILE ptr) as FILE ptr|stdio.bi    |Opens a file for redirecting a stream. e.g. freopen("myfile", "w", stdout) will redirect the standard output to the opened "myfile".                                                                          |
      |frexp   |frexp(x as double, p as integer ptr) as double                              |math.bi     |Calculates a value m so that x equals m times 2 to some power. p is a pointer to m.                                                                                                                           |
      |fscanf  |fscanf(s as FILE ptr, fmt as zstring ptr, ...) as integer                   |stdio.bi    |Reads from stream s as many items as there are % signs in fmt with corresponding listed pointers.                                                                                                             |
      |fseek   |fseek(s as FILE ptr, offset as integer, origin as integer) as integer       |stdio.bi    |Locates a file pointer. With origin 0, 1 or 2 for the beginning, offset bytes into and at the end of the stream.                                                                                              |
      |fsetpos |fsetpos(s as FILE ptr, p as fpos_t ptr) as integer                          |stdio.bi    |Sets the file pointer for the stream s to the value pointed to by p.                                                                                                                                          |
      |ftell   |ftell(s as FILE ptr) as long                                                |stdio.bi    |Locates the position of the file pointer for the stream s.                                                                                                                                                    |
      |fwrite  |fwrite(buf as any ptr, b as integer, c as integer, s as FILE ptr) as integer|stdio.bi    |Writes the number c items of data of size b bytes from the buffer buf to the file s. Returns the number of data items actually written.                                                                       |
      |getc    |getc(s as FILE ptr) as integer                                              |stdio.bi    |Macro for single character input (in ASCII) from passed stream. (stdin for keyboard)                                                                                                                          |
      |getchar |getchar() as integer                                                        |stdio.bi    |Single character input from the standard input                                                                                                                                                                |
      |gets    |gets(b as zstring ptr) as zstring ptr                                       |stdio.bi    |Reads a stream of characters from the standard input until it meets \n or EOF.                                                                                                                                |
      |hypot   |hypot(x as double, y as double) as double                                   |math.bi     |Calculates the hypotenuse from the sides x and y.                                                                                                                                                             |
      |isalnum |isalnum(c as integer) as integer                                            |ctype.bi    |Returns a non zero value if character c is alphabetic or a digit.                                                                                                                                             |
      |isalpha |isalpha(c as integer) as integer                                            |ctype.bi    |Returns a non zero value if character c is alphabetic.                                                                                                                                                        |
      |iscntrl |iscntrl(c as integer) as integer                                            |ctype.bi    |Returns a non zero value if character c is a control character.                                                                                                                                               |
      |isdigit |isdigit(c as integer) as integer                                            |ctype.bi    |Returns a non zero value if character c is a digit.                                                                                                                                                           |
      |isgraph |isgraph(c as integer) as integer                                            |ctype.bi    |Returns a non zero value if character c is alphabetic.                                                                                                                                                        |
      |islower |islower(c as integer) as integer                                            |ctype.bi    |Returns a non-zero value if character c is a lower case character.                                                                                                                                            |
      |isprint |isprint(c as integer) as integer                                            |ctype.bi    |Returns a non zero value if character c is printable.                                                                                                                                                         |
      |ispunct |ispunct(c as integer) as integer                                            |ctype.bi    |Returns a non zero value if character c is a punctuation character.                                                                                                                                           |
      |isspace |isspace(c as integer) as integer                                            |ctype.bi    |Returns a non zero value if character c denotes a space.                                                                                                                                                      |
      |isupper |isupper(c as integer) as integer                                            |ctype.bi    |Returns a non-zero value if character c is an upper case character.                                                                                                                                           |
      |isxdigit|isxdigit(c as integer) as integer                                           |ctype.bi    |Returns a non-zero value if character c is a hex digit (0 to F or f).                                                                                                                                         |
      |ldexp   |ldexp(x as double, n as integer) as double                                  |math.bi     |Returns the product of x and 2 to the power n.                                                                                                                                                                |
      |ldiv    |ldiv(num as long, denom as long) as ldiv_t                                  |stdlib.bi   |Returns the quotient and remainder of a division as a structure of type ldiv_t.                                                                                                                               |
      |log_    |log_(a as double) as double                                                 |math.bi     |Returns the natural logarithm of the argument.                                                                                                                                                                |
      |log10   |log10(a as double) as double                                                |math.bi     |Returns the logarithm to the base 10 of the argument.                                                                                                                                                         |
      |malloc  |malloc(bytes as integer) as any ptr                                         |stdlib.bi   |Allocates memory. Returns a pointer to a buffer comprising storage for the specified size.                                                                                                                    |
      |modf    |modf(d as double, p as double ptr) as double                                |math.bi     |Returns the fractional part of a floating point number d. p points to the integral part expressed as a float.                                                                                                 |
      |perror  |perror(mess as zstring ptr)                                                 |stdio.bi    |Prints on the stream stderr a message passed as the argument.                                                                                                                                                 |
      |pow     |pow(x as double, y as double) as double                                     |math.bi     |Returns x to the power y.                                                                                                                                                                                     |
      |pow10   |pow10(x as double) as double                                                |math.bi     |Returns 10 to the power x (inverse function to log10()).                                                                                                                                                      |
      |printf  |printf(fmt as zstring ptr, ...) as integer                                  |stdio.bi    |Prints on standard output as many items as there are single % signs in fmt with matching arguments in the list.                                                                                               |
      |putc    |putc(c as integer, s as FILE ptr) as integer                                |stdio.bi    |Macro to output the single character c to the stream s.                                                                                                                                                       |
      |putchar |putchar(c as integer) as integer                                            |stdio.bi    |Macro to output the single character c to the standard output.                                                                                                                                                |
      |puts    |puts(b as zstring ptr) as integer                                           |stdio.bi    |Sends the character stream in b to the standard output, returns 0 if operation fails.                                                                                                                         |
      |rand    |rand() as integer                                                           |stdlib.bi   |Returns a pseudo random number. A seed is required. The seed is set with srand.                                                                                                                               |
      |realloc |realloc(p as any ptr, newsize as size_t) as any ptr                         |stdlib.bi   |Allocates memory. Returns a pointer to a buffer for a change in size of object pointed to by p.                                                                                                               |
      |rewind  |rewind(s as FILE ptr)                                                       |stdio.bi    |Clears the error indicators on a file stream (read or write). Necessary before reading an amended file.                                                                                                       |
      |scanf   |scanf(fmt as zstring ptr, ...) as integer                                   |stdio.bi    |Reads from standard input as many items as there are % signs in fmt with corresponding listed pointers.                                                                                                       |
      |sin_    |sin_(ar as double) as double                                                |math.bi     |Returns the sine of an angle measured in radians.                                                                                                                                                             |
      |sinh    |sinh(x as double) as double                                                 |math.bi     |Returns the hyperbolic sine of an angle measured in radians.                                                                                                                                                  |
      |sprintf |sprintf(p as zstring ptr, fmt as zstring ptr, ...) as integer               |stdio.bi    |Prints on zstring p as many items as there are single % signs in fmt that have matching arguments in the list.                                                                                                |
      |sqrt    |sqrt(a as double) as double                                                 |math.bi     |Returns the square root of the value passed. Domain error if value is negative.                                                                                                                               |
      |srand   |srand(seed as uinteger)                                                     |stdlib.bi   |Sets the seed for a random number. A possible seed is the current time.                                                                                                                                       |
      |sscanf  |sscanf(b as zstring ptr, fmt as zstring ptr, ...) as integer                |stdio.bi    |Reads from buffer b as many items as there are % signs in fmt with corresponding listed pointers.                                                                                                             |
      |strcat  |strcat(s1 as zstring ptr, s2 as zstring ptr) as zstring ptr                 |string.bi   |Concatenates (appends) zstring s2 to s1.                                                                                                                                                                      |
      |strchr  |strchr(s as zstring ptr, c as integer) as zstring ptr                       |string.bi   |Returns a pointer to the first occurrence of c in s or NULL if it fails to find one.                                                                                                                          |
      |strcmp  |strcmp(s1 as zstring ptr, s2 as zstring ptr) as integer                     |string.bi   |Compares zstring s2 to s1. Returns 0 or signed difference in ASCII values of first non matching character.                                                                                                    |
      |strcpy  |strcpy(s1 as zstring ptr, s2 as zstring ptr) as zstring ptr                 |string.bi   |Copies s2 into s1.                                                                                                                                                                                            |
      |strcspn |strcspn(s1 as zstring ptr, s2 as zstring ptr) as integer                    |string.bi   |Returns the number of characters in s1 encountered before meeting any of the characters in s2.                                                                                                                |
      |strerror|strerror(n as integer) as zstring ptr                                       |string.bi   |Returns a pointer to a system error message corresponding to the passed error number.                                                                                                                         |
      |strlen  |strlen(s as zstring ptr) as integer                                         |string.bi   |Returns the number of bytes in the null terminated zstring pointed to by s (does not count null).                                                                                                             |
      |strncat |strncat(s1 as zstring ptr, s2 as zstring ptr, n as integer) as zstring ptr  |string.bi   |Concatenates (appends) n bytes from zstring s2 to s1.                                                                                                                                                         |
      |strncmp |strncmp(s1 as zstring ptr, s2 as any ptr, n as integer) as integer          |string.bi   |Compares n bytes of zstring s2 to the same of s1. Returns 0 or signed difference in ASCII values of first non matching character.                                                                             |
      |strncpy |strncpy(s1 as zstring ptr, s2 as zstring ptr, n as integer) as zstring ptr  |string.bi   |Copies n bytes from s2 into s1.                                                                                                                                                                               |
      |strpbrk |strpbrk(s1 as zstring ptr, s2 as zstring ptr) as zstring ptr                |string.bi   |Returns a pointer to the first character encountered in s1 that is also in s2.                                                                                                                                |
      |strrchr |strrchr(s as zstring ptr, c as integer) as zstring ptr                      |string.bi   |Returns a pointer to the last occurrence of c in s or NULL if it fails to find one.                                                                                                                           |
      |strspn  |strspn(s1 as zstring ptr, s2 as zstring ptr) as integer                     |string.bi   |Returns the number of characters in s1 encountered before meeting a character which is not in s2.                                                                                                             |
      |strstr  |strstr(s1 as zstring ptr, s2 as zstring ptr) as zstring ptr                 |string.bi   |Finds the location of the zstring s2 in s1 and returns a pointer to its leading character.                                                                                                                    |
      |strtod  |strtod(s as zstring ptr, p as zstring ptr) as double                        |stdlib.bi   |Converts a zstring to double, provided the zstring is written in the form of a number.                                                                                                                        |
      |strtok  |strtok(s1 as zstring ptr, s2 as zstring ptr) as zstring ptr                 |string.bi   |Returns pointers to successive tokens utilizing the zstring s1. Tokens regarded as separators are listed in s2.                                                                                               |
      |system  |system(command as zstring ptr) as integer                                   |stdlib.bi   |Executes, from within a program, a command addressed to the operating system written as a zstring (e.g. DIR on Windows and DOS and LS on Linux).                                                              |
      |tan_    |tan_(ar as double) as double                                                |math.bi     |Returns the tangent of an angle measured in radians.                                                                                                                                                          |
      |tanh    |tanh(x as double) as double                                                 |math.bi     |Returns the hyperbolic tangent of an angle measured in radians.                                                                                                                                               |
      |tolower |tolower(c as integer) as integer                                            |ctype.bi    |Converts a character from upper case to lower case (uses ASCII code).                                                                                                                                         |
      |toupper |toupper(c as integer) as integer                                            |ctype.bi    |Converts a character from lower case to upper case (uses ASCII code).                                                                                                                                         |
      |ungetc  |ungetc(c as integer, s as FILE ptr) as integer                              |stdio.bi    |Pushes a character c back into the stream s, returns EOF if unsuccessful. Do not push more than one character.                                                                                                |
      +--------+----------------------------------------------------------------------------+------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

Buffer Manipulation

   #include "crt/string.bi"

      +----------------------------------------------------------------+--------------------------------------------------+
      |Prototype (with parameters)                                     |Comments                                          |
      |memchr(s as any ptr, c as integer, n as size_t) as any ptr      |Search for a character in a buffer.               |
      |memcmp(s1 as any ptr, s2 as any ptr, n as size_t) as integer    |Compare two buffers.                              |
      |memcpy(dest as any ptr, src as any ptr, n as size_t) as any ptr |Copy one buffer into another .                    |
      |memmove(dest as any ptr, src as any ptr, n as size_t) as any ptr|Move a number of bytes from one buffer lo another.|
      |memset(s as any ptr, c as integer, n as size_t) as any ptr      |Set all bytes of a buffer to a given character.   |
      +----------------------------------------------------------------+--------------------------------------------------+

Character Classification and Conversion

   #include "crt/ctype.bi"

      +---------------------------------+-------------------------------------+
      |Prototype (with parameters)      |Comments                             |
      |isalnum(c as integer) as integer |True if c is alphanumeric.           |
      |isalpha(c as integer) as integer |True if c is a letter.               |
      |isascii(c as integer) as integer |True if c is ASCII .                 |
      |iscntrl(c as integer) as integer |True if c is a control character.    |
      |isdigit(c as integer) as integer |True if c is a decimal digit.        |
      |isgraph(c as integer) as integer |True if c is a graphical character.  |
      |islower(c as integer) as integer |True if c is a lowercase letter.     |
      |isprint(c as integer) as integer |True if c is a printable character.  |
      |ispunct(c as integer) as integer |True if c is a punctuation character.|
      |isspace(c as integer) as integer |True if c is a space character.      |
      |isupper(c as integer) as integer |True if c is an uppercase letter.    |
      |isxdigit(c as integer) as integer|True if c is a hexadecimal digit.    |
      |toascii(c as integer) as integer |Convert c to ASCII .                 |
      |tolower(c as integer) as integer |Convert c to lowercase.              |
      |toupper(c as integer) as integer |Convert c to uppercase.              |
      +---------------------------------+-------------------------------------+

Data Conversion

   #include "crt/stdlib.bi"

      +---------------------------------------------------------------------------------+--------------------------------------------------------+
      |Prototype (with parameters)                                                      |Comments                                                |
      |atof(string1 as zstring ptr) as double                                           |Convert zstring to floating point value.                |
      |atoi(string1 as zstring ptr) as integer                                          |Convert zstring to an integer value.                    |
      |atol(string1 as zstring ptr) as integer                                          |Convert zstring to a long integer value.                |
      |itoa(value as integer, zstring as zstring ptr, radix as integer) as zstring ptr  |Convert an integer value to a zstring using given radix.|
      |ltoa(value as long, zstring as zstring ptr, radix as integer) as zstring ptr     |Convert long integer to zstring in a given radix.       |
      |strtod(string1 as zstring ptr, endptr as zstring ptr) as double                  |Convert zstring to a floating point value.              |
      |strtol(string1 as zstring ptr, endptr as zstring ptr, radix as integer) as long  |Convert zstring to a long integer using a given radix.  |
      |strtoul(string1 as zstring ptr, endptr as zstring ptr, radix as integer) as ulong|Convert zstring to unsigned long.                       |
      +---------------------------------------------------------------------------------+--------------------------------------------------------+

Directory Manipulation

   #include "crt/io.bi"

      +----------------------------------------------------------------+------------------------------------------+
      |Prototype (with parameters)                                     |Comments                                  |
      |_chdir(path as zstring ptr) as integer                          |Change current directory to given path.   |
      |_getcwd(path as zstring ptr, numchars as integer) as zstring ptr|Returns name of current working directory.|
      |_mkdir(path as zstring ptr) as integer                          |Create a directory using given path name. |
      |_rmdir(path as zstring ptr) as integer                          |Delete a specified directory.             |
      +----------------------------------------------------------------+------------------------------------------+

File Manipulation

   #include "crt/sys/stat.bi"
   #include "crt/io.bi"

      +------------------------------------------------------------------+------------------------------------------+
      |Prototype (with parameters)                                       |Comments                                  |
      |chmod(path as zstring ptr, pmode as integer) as integer           |Change permission settings of a file.     |
      |fstat(handle as integer, buffer as type stat ptr) as integer      |Get file status information.              |
      |remove(path as zstring ptr) as integer                            |Delete a named file.                      |
      |rename_(oldname as zstring ptr, newname as zstring ptr) as integer|rename a file.                            |
      |stat(path as zstring ptr, buffer as type stat ptr) as integer     |Get file status information of named file.|
      |umask(pmode as uinteger) as uinteger                              |Set file permission mask.                 |
      +------------------------------------------------------------------+------------------------------------------+

Stream I/O

   #include "crt/stdio.bi"

      +------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------+
      |Prototype (with parameters)                                                                                 |Comments                                                         |
      |clearerr(file_pointer as FILE ptr)                                                                          |Clear error indicator of stream,                                 |
      |fclose(file_pointer as FILE ptr) as integer                                                                 |Close a file,                                                    |
      |feof(file_pointer as FILE ptr) as integer                                                                   |Check if end of file occurred on a stream.                       |
      |ferror(file_pointer as FILE ptr) as integer                                                                 |Check if any error occurred during file I/0.                     |
      |fflush(file_pointer as FILE ptr) as integer                                                                 |Write out (flush) buffer to file.                                |
      |fgetc(file_pointer as FILE ptr) as integer                                                                  |Get a character from a stream.                                   |
      |fgetpos(file_pointer as FILE ptr, fpos_t current_pos) as integer                                            |Get the current position in a stream.                            |
      |fgets(string1 as zstring ptr, maxchar as integer, file_pointer as FILE ptr) as zstring ptr                  |Read a zstring from a file.                                      |
      |fopen(filename as zstring ptr, access_mode as zstring ptr) as FILE ptr                                      |Open a file for buffered I/0.                                    |
      |fprintf(file_pointer as FILE ptr, format_string as zstring ptr, args) as integer                            |Write formatted output to a file,                                |
      |fputc(c as integer, file_pointer as FILE ptr) as integer                                                    |Write a character to a stream.                                   |
      |fputchar(c as integer) as integer                                                                           |Write a character to stdout.                                     |
      |fputs(string1 as zstring ptr, file_pointer as FILE ptr) as integer                                          |Write a zstring to a stream.                                     |
      |fread(buffer as zstring ptr, size as size_t count as size_t, file_pointer as FILE ptr) as size_t            |Read unformatted data from a stream into a buffer.               |
      |freopen(filename as zstring ptr, access as zstring ptr mode, file_pointer as FILE ptr) as FILE ptr          |Reassign a file pointer to a different file.                     |
      |fscanf(file_pointer as FILE ptr, format as zstring ptr zstring, args) as integer                            |Read formatted input from a stream.                              |
      |fseek(file_pointer as FILE ptr, offset as long, origin as integer) as integer                               |Set current position in file to a new location.                  |
      |fsetpos(file_pointer as FILE ptr, current_pos as fpos_t) as integer                                         |Set current position in file to a new location.                  |
      |ftell(file_pointer as FILE ptr) as long                                                                     |Get current location in file.                                    |
      |fwrite(buffer as zstring ptr, size as size_t, count as size_t file_pointer as FILE ptr) as size_t           |Write unformatted data from a buffer to a stream.                |
      |getc(file_pointer as FILE ptr) as integer                                                                   |Read a character from a stream.                                  |
      |getchar() as integer                                                                                        |Read a character from stdin.                                     |
      |gets(buffer as zstring ptr) as zstring ptr                                                                  |Read a line from stdin into a buffer.                            |
      |printf(format as zstring ptr _string, args) as integer                                                      |Write formatted output to stdout.                                |
      |putc(c as integer, file_pointer as FILE ptr) as integer                                                     |Write a character to a stream.                                   |
      |putchar(c as integer) as integer                                                                            |Write a character to stdout.                                     |
      |puts(string1 as zstring ptr) as integer                                                                     |Write a zstring to stdout.                                       |
      |rewind(file_pointer as FILE ptr)                                                                            |Rewind a file.                                                   |
      |scanf(format_string as zstring ptr, args) as integer                                                        |Read formatted input from stdin.                                 |
      |setbuf(file_pointer as FILE ptr, buffer as zstring ptr)                                                     |Set up a new buffer for the stream.                              |
      |setvbuf(file_pointer as FILE ptr, buffer as zstring ptr, buf_type as integer, buf as size_t size) as integer|Set up new buffer and control the level of buffering on a stream.|
      |sprintf(string1 as zstring ptr, format_string as zstring ptr, args) as integer                              |Write formatted output to a zstring.                             |
      |sscanf(buffer as zstring ptr, format_string as zstring ptr, args) as integer                                |Read formatted input from a zstring.                             |
      |tmpfile() as FILE ptr                                                                                       |Open a temporary file.                                           |
      |tmpnam(file_name as zstring ptr) as zstring ptr                                                             |Get temporary file name.                                         |
      |ungetc(c as integer, file_pointer as FILE ptr) as integer                                                   |Push back character into stream' s buffer                        |
      +------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------+

Low level I/O

   #include "crt/io.bi"

   So far Win32 only, connects to MSVCRT.DLL (headers missing for other 
   platforms)

      +------------------------------------------------------------------------------+----------------------------------------------------+
      |Prototype (with parameters)                                                   |Comments                                            |
      |_close(handle as integer) as integer                                          |Close a file opened for unbuffered I/O.             |
      |_creat(filename as zstring ptr, pmode as integer) as integer                  |Create a new file with specified permission setting.|
      |_eof(handle as integer) as integer                                            |Check for end of file.                              |
      |_lseek(handle as integer, offset as long, origin as integer) as long          |Go to a specific position in a file.                |
      |_open(filename as zstring ptr, oflag as integer, pmode as uinteger) as integer|Open a file for low-level I/O.                      |
      |_read(handle as integer, buffer as zstring ptr, length as uinteger) as integer|Read binary data from a file into a buffer.         |
      |_write(handle as integer, buffer as zstring ptr, count as uinteger) as integer|Write binary data from a buffer to a file.          |
      +------------------------------------------------------------------------------+----------------------------------------------------+

Mathematics

   #include "crt/math.bi"

      +---------------------------------------------------+----------------------------------------------------------+
      |Prototype (with parameters)                        |Comments                                                  |
      |abs_(n as integer) as integer                      |Get absolute value of an integer.                         |
      |acos_(x as double) as double                       |Compute arc cosine of x.                                  |
      |asin_(x as double) as double                       |Compute arc sine of x.                                    |
      |atan_(x as double) as double                       |Compute arc tangent of x.                                 |
      |atan2_(y as double, x as double) as double         |Compute arc tangent of y/x.                               |
      |ceil(x as double) as double                        |Get smallest integral value that exceeds x.               |
      |cos_(x as double) as double                        |Compute cosine of angle in radians.                       |
      |cosh(x as double) as double                        |Compute the hyperbolic cosine of x.                       |
      |div(number as integer, denom as integer) as div_t  |Divide one integer by another.                            |
      |exp_(x as double) as double                        |Compute exponential of x.                                 |
      |fabs(x as double) as double                        |Compute absolute value of x.                              |
      |floor(x as double) as double                       |Get largest integral value less than x.                   |
      |fmod(x as double, y as double) as double           |Divide x by y with integral quotient and return remainder.|
      |frexp(x as double, expptr as integer ptr) as double|Breaks down x into mantissa and exponent of no.           |
      |labs(n as long) as long                            |Find absolute value of long integer n.                    |
      |ldexp(x as double, exp as integer) as double       |Reconstructs x out of mantissa and exponent of two.       |
      |ldiv(number as long, denom as long) as ldiv_t      |Divide one long integer by another.                       |
      |log_(x as double) as double                        |Compute log(x).                                           |
      |log10(x as double) as double                       |Compute log to the base 10 of x.                          |
      |modf(x as double, intptr as double ptr) as double  |Breaks x into fractional and integer parts.               |
      |pow(x as double, y as double) as double            |Compute x raised to the power y.                          |
      |rand() as integer                                  |Get a random integer between 0 and 32767.                 |
      |random(max_num as integer) as integer              |Get a random integer between 0 and max_num.               |
      |randomize()                                        |Set a random seed for the random number generator.        |
      |sin_(x as double) as double                        |Compute sine of angle in radians.                         |
      |sinh(x as double) as double                        |Compute the hyperbolic sine of x.                         |
      |sqrt(x as double) as double                        |Compute the square root of x.                             |
      |srand(seed as uinteger)                            |Set a new seed for the random number generator (rand).    |
      |tan_(x as double) as double                        |Compute tangent of angle in radians.                      |
      |tanh(x as double) as double                        |Compute the hyperbolic tangent of x.                      |
      +---------------------------------------------------+----------------------------------------------------------+

Memory Allocation

   #include "crt/stdlib.bi"

      +-------------------------------------------------------------+-------------------------------------------------------+
      |Prototype (with parameters)                                  |Comments                                               |
      |calloc(num as size_t elems, elem_size as size_t) as any ptr  |Allocate an array and initialise all elements to zero .|
      |free(mem_address as any ptr)                                 |Free a block of memory.                                |
      |malloc(num as size_t bytes) as any ptr                       |Allocate a block of memory.                            |
      |realloc(mem_address as any ptr, newsize as size_t) as any ptr|Reallocate (adjust size) a block of memory.            |
      +-------------------------------------------------------------+-------------------------------------------------------+

Process Control

   #include "crt/stdlib.bi"

      +------------------------------------------------------------------------------------------+-------------------------------------------------------+
      |Prototype (with parameters)                                                               |Comments                                               |
      |abort()                                                                                   |Abort a process.                                       |
      |execl(path as zstring ptr, arg0 as zstring ptr, arg1 as zstring ptr,..., NULL) as integer |Launch a child process (pass command line).            |
      |execlp(path as zstring ptr, arg0 as zstring ptr, arg1 as zstring ptr,..., NULL) as integer|Launch child (use PATH, pass command line).            |
      |execv(path as zstring ptr, argv as zstring ptr) as integer                                |Launch child (pass argument vector).                   |
      |execvp(path as zstring ptr, argv as zstring ptr) as integer                               |Launch child (use PATH, pass argument vector).         |
      |exit_(status as integer)                                                                  |Terminate process after flushing all buffers.          |
      |getenv(varname as zstring ptr) as zstring ptr                                             |Get definition of environment variable,                |
      |perror(string1 as zstring ptr)                                                            |Print error message corresponding to last system error.|
      |putenv(envstring as zstring ptr) as integer                                               |Insert new definition into environment table.          |
      |raise(signum as integer) as integer                                                       |Generate a C signal (exception).                       |
      |system_(string1 as zstring ptr) as integer                                                | Execute a resident operating system command.          |
      +------------------------------------------------------------------------------------------+-------------------------------------------------------+

Searching and Sorting

   #include "crt/stdlib.bi"
            Note: The compare callback function required by bsearch and 
            qsort must be declared as cdecl. It must return a value <0 if 
            its first argument should be located before the second one in 
            the sorted array, >0 if the first argument should be located 
            after the second one, and zero if their relative positions are 
            indifferent (equal values).  

      +-------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------+
      |Prototype (with parameters)                                                                                                                            |Comments                                     |
      |bsearch(key as any ptr, base as any ptr, num as size_t, width as size_t, compare as function(elem1 as any ptr, elem2 as any ptr) as integer) as any ptr|Perform binary search.                       |
      |qsort(base as any ptr, num as size_t, width as size_t, compare as function(elem1 as any ptr, elem2 as any ptr) as integer)                             |Use the quicksort algorithm to sort an array.|
      +-------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------+

String Manipulation

   #include "crt/string.bi"

      +-----------------------------------------------------------------------------------+----------------------------------------------------------+
      |Prototype (with parameters)                                                        |Comments                                                  |
      |stpcpy(dest as zstring ptr, src as zstring ptr) as zstring ptr                     |Copy one zstring into another.                            |
      |strcmp(string1 as zstring ptr, string2 as zstring ptr) as integer                  |Compare string1 and string2 to determine alphabetic order.|
      |strcpy(string1 as zstring ptr, string2 as zstring ptr) as zstring ptr              |Copy string2 to string1.                                  |
      |strerror(errnum as integer) as zstring ptr                                         |Get error message corresponding to specified error number.|
      |strlen(string1 as zstring ptr) as integer                                          |Determine the length of a zstring.                        |
      |strncat(string1 as zstring ptr, string2 as zstring ptr, n as size_t) as zstring ptr|Append n characters from string2 to string1.              |
      |strncmp(string1 as zstring ptr, string2 as zstring ptr, n as size_t) as integer    |Compare first n characters of two strings.                |
      |strncpy(string1 as zstring ptr, string2 as zstring ptr, n as size_t) as zstring ptr|Copy first n characters of string2 to string1.            |
      |strnset(string1 as zstring ptr, c as integer, size _t n) as zstring ptr            |Set first n characters of zstring to c.                   |
      |strrchr(string1 as zstring ptr, c as integer) as zstring ptr                       |Find last occurrence of character c in zstring.           |
      +-----------------------------------------------------------------------------------+----------------------------------------------------------+

Time

   #include "crt/time.bi"

      +----------------------------------------------+-------------------------------------------------------------+
      |Prototype (with parameters)                   |Comments                                                     |
      |asctime(time as type tm ptr) as zstring ptr   |Convert time from type tm to zstring.                        |
      |clock() as clock_t                            |Get elapsed processor time in clock ticks.                   |
      |ctime(time as time_t ptr) as zstring ptr      |Convert binary time to zstring.                              |
      |difftime(time_t time2, time_t time1) as double|Compute the difference between two times in seconds.         |
      |gmtime(time as time_t ptr) as type tm ptr     |Get Greenwich Mean Time (GMT) in a tm structure.             |
      |localtime(time as time_t ptr) as type tm ptr  |Get the local time in a tm structure.                        |
      |time_(timeptr as time_t ptr) as time_t        |Get current time as seconds elapsed since 0 hours GMT 1/1/70.|
      +----------------------------------------------+-------------------------------------------------------------+

See also
   * #include



-------------------------------------------------------------- CptAscii ----
Table of ASCII Characters

FreeBASIC graphics programs support in all versions the same "ASCII 
extended" USA character set the old DOS (and QBasic) supported. It is also 
called CP437 or Code page 437.  Each character is represented with one (1) 
byte of data.  Here is a table.  Each entry has decimal code, hex code, and 
printed representation.

      
     0  0  ³ 16 10  ³ 32 20  ³ 48 30 0³ 64 40 @³ 80 50 P³ 96 60 `³112 70 p
     1  1  ³ 17 11  ³ 33 21 !³ 49 31 1³ 65 41 A³ 81 51 Q³ 97 61 a³113 71 q
     2  2  ³ 18 12  ³ 34 22 "³ 50 32 2³ 66 42 B³ 82 52 R³ 98 62 b³114 72 r
     3  3  ³ 19 13  ³ 35 23 #³ 51 33 3³ 67 43 C³ 83 53 S³ 99 63 c³115 73 s
     4  4  ³ 20 14  ³ 36 24 $³ 52 34 4³ 68 44 D³ 84 54 T³100 64 d³116 74 t
     5  5  ³ 21 15  ³ 37 25 %³ 53 35 5³ 69 45 E³ 85 55 U³101 65 e³117 75 u
     6  6  ³ 22 16  ³ 38 26 &³ 54 36 6³ 70 46 F³ 86 56 V³102 66 f³118 76 v
     7  7  ³ 23 17  ³ 39 27 '³ 55 37 7³ 71 47 G³ 87 57 W³103 67 g³119 77 w
     8  8  ³ 24 18  ³ 40 28 (³ 56 38 8³ 72 48 H³ 88 58 X³104 68 h³120 78 x
     9  9  ³ 25 19  ³ 41 29 )³ 57 39 9³ 73 49 I³ 89 59 Y³105 69 i³121 79 y
    10  A  ³ 26 1A  ³ 42 2A *³ 58 3A :³ 74 4A J³ 90 5A Z³106 6A j³122 7A z
    11  B  ³ 27 1B  ³ 43 2B +³ 59 3B ;³ 75 4B K³ 91 5B [³107 6B k³123 7B {
    12  C  ³ 28 1C  ³ 44 2C ,³ 60 3C <³ 76 4C L³ 92 5C \³108 6C l³124 7C |
    13  D  ³ 29 1D  ³ 45 2D -³ 61 3D =³ 77 4D M³ 93 5D ]³109 6D m³125 7D }
    14  E  ³ 30 1E  ³ 46 2E .³ 62 3E >³ 78 4E N³ 94 5E ^³110 6E n³126 7E ~
    15  F  ³ 31 1F  ³ 47 2F /³ 63 3F ?³ 79 4F O³ 95 5F _³111 6F o³127 7F 

   128 80 €³144 90 �³160 A0  ³176 B0 °³192 C0 À³208 D0 Ð³224 E0 à³240 F0 ð
   129 81 �³145 91 ‘³161 A1 ¡³177 B1 ±³193 C1 Á³209 D1 Ñ³225 E1 á³241 F1 ñ
   130 82 ‚³146 92 ’³162 A2 ¢³178 B2 ²³194 C2 Â³210 D2 Ò³226 E2 â³242 F2 ò
   131 83 ƒ³147 93 “³163 A3 £³179 B3 ³³195 C3 Ã³211 D3 Ó³227 E3 ã³243 F3 ó
   132 84 „³148 94 ”³164 A4 ¤³180 B4 ´³196 C4 Ä³212 D4 Ô³228 E4 ä³244 F4 ô
   133 85 …³149 95 •³165 A5 ¥³181 B5 µ³197 C5 Å³213 D5 Õ³229 E5 å³245 F5 õ
   134 86 †³150 96 –³166 A6 ¦³182 B6 ¶³198 C6 Æ³214 D6 Ö³230 E6 æ³246 F6 ö
   135 87 ‡³151 97 —³167 A7 §³183 B7 ·³199 C7 Ç³215 D7 ×³231 E7 ç³247 F7 ÷
   136 88 ˆ³152 98 ˜³168 A8 ¨³184 B8 ¸³200 C8 È³216 D8 Ø³232 E8 è³248 F8 ø
   137 89 ‰³153 99 ™³169 A9 ©³185 B9 ¹³201 C9 É³217 D9 Ù³233 E9 é³249 F9 ù
   138 8A Š³154 9A š³170 AA ª³186 BA º³202 CA Ê³218 DA Ú³234 EA ê³250 FA ú
   139 8B ‹³155 9B ›³171 AB «³187 BB »³203 CB Ë³219 DB Û³235 EB ë³251 FB û
   140 8C Œ³156 9C œ³172 AC ¬³188 BC ¼³204 CC Ì³220 DC Ü³236 EC ì³252 FC ü
   141 8D �³157 9D �³173 AD ­³189 BD ½³205 CD Í³221 DD Ý³237 ED í³253 FD ý
   142 8E Ž³158 9E ž³174 AE ®³190 BE ¾³206 CE Î³222 DE Þ³238 EE î³254 FE þ
   143 8F �³159 9F Ÿ³175 AF ¯³191 BF ¿³207 CF Ï³223 DF ß³239 EF ï³255 FF ÿ

 

Many of the standard ASCII characters cannot be Printed in FreeBASIC, 
because the console interprets some characters as controls: 7 is bell, 8 is 
backspace, 9 is tab, 10 is line feed, 13 is carriage return, and others.  
There are symbols associated with these characters also, but there is no 
way in FreeBASIC to output them to the screen. 

The acronym ASCII stands for American Standard Code for Information 
Interchange. For more information, see http://en.wikipedia.org/wiki/Ascii.  
The symbols for codes 32 through 127 are the same as the standard 
Latin ISO-8859-1 char set most Windows fonts use. Others are often very 
different.

In console mode (i.e. Screen 0/ non-graphics mode) the characters less than 
32 or greater than 127 may display using different characters, depending on 
the operating system and code page of the screen / console in use.
UNICODE is a newer standard of character sets involving two or more bytes 
per character, and may be used to print other characters to a 
Unicode-enabled console.

In graphics modes, Draw String does not give special meaning to control 
characters allowing an alternative to display all characters in the set. 



------------------------------------------------------ TblRuntimeErrors ----
Runtime Error Codes

Runtime error codes and messages used by the runtime library.

Description
   Freebasic returns the following runtime error codes:
      +----+-----------------------------+
      |  0 |No error                     |
      |  1 |Illegal function call        |
      |  2 |File not found signal        |
      |  3 |File I/O error               |
      |  4 |Out of memory                |
      |  5 |Illegal resume               |
      |  6 |Out of bounds array access   |
      |  7 |Null Pointer Access          |
      |  8 |No privileges                |
      |  9 |interrupted signal           |
      | 10 |illegal instruction signal   |
      | 11 |floating point error signal  |
      | 12 |segmentation violation signal|
      | 13 |Termination request signal   |
      | 14 |abnormal termination signal  |
      | 15 |quit request signal          |
      | 16 |return without gosub         |
      | 17 |end of file                  |
      +----+-----------------------------+

   No user error code range is defined. If Error is used to set an error 
   code it is wise to use high values to avoid collisions with the list of 
   built-in error codes. (This built-in list may be expanded later.)

See also
   * Err
   * Error
   * On Error
   * Error Handling

   


-------------------------------------------------------- TblComparisonC ----
Comparison of C/C++ and FreeBASIC

C/C++FreeBASIC

variable declaration
int a;
int a, b, c;dim a as long
dim as long a, b, c

uninitialized variable
int a;dim a as long = any

zero-initialized variable
int a = 0;dim a as long

initialized variable
int a = 123;dim a as long = 123

array
int a[4];
a[0] = 1;dim a(0 to 3) as long
a(0) = 1

pointer
int a;
int *p;
p = &a;
*p = 123;dim a as long
dim p as long ptr
p = @a
*p = 123

structure, user-defined type
struct UDT {
   int myfield;
}type UDT
   myfield as long
end type

typedef, type alias
typedef int myint;type myint as long

struct pointer
struct UDT x;
struct UDT *p;
p = &x;
p->myfield = 123;dim x as UDT
dim p as UDT ptr
p = @x
p->myfield = 123

function declaration
int foo( void );declare function foo( ) as long

function body
int foo( void ) {
   return 123;
}function foo( ) as long
   return 123
end function

sub declaration
void foo( void );declare sub foo( )

sub body
void foo( void ) {
}sub foo( )
end sub

byval parameters
void foo( int param );
foo( a );declare sub foo( byval param as long )
foo( a );

byref parameters
void foo( int *param );
foo( &a );

void foo( int& param );
foo( a );declare sub foo( byref param as long )
foo( a )

statement separator
;

:
<end-of-line>

for loop
for (int i = 0; i < 10; i++) {
   ...
}for i as long = 0 to 9
   ...
next

while loop
while (condition) {
   ...
}while condition
   ...
wend

do-while loop
do {
   ...
} while (condition);do
   ...
loop while condition

if block
if (condition) {
   ...
} else if (condition) {
   ...
} else {
   ...
}if condition then
   ...
elseif condition then
   ...
else
   ...
end if

switch, select
switch (a) {
case 1:
   ...
   break;
case 2:
case 3:
   ...
   break;
default:
   ...
   break;
}select case a
case 1
   ...

case 2, 3
   ...

case else
   ...

end select

string literals, zstrings
char *s = "Hello!";
char s[] = "Hello!";dim s as zstring ptr = @"Hello!"
dim s as zstring * 6+1 = "Hello!"

hello world
#include <stdio.h>
int main() {
   printf("Hello!\n");
   return 0;
}print "Hello!"

comments
// foo
/* foo */' foo
/' foo '/

compile-time checks
#if a
#elif b
#else
#endif#if a
#elseif b
#else
#endif

compile-time target system checks
#ifdef _WIN32#ifdef __FB_WIN32__

module/header file names
foo.c, foo.hfoo.bas, foo.bi

typical compiler command to create an executable
gcc foo.c -o foofbc foo.bas

Last reviewed by MrSwiss on April 6, 2018 Note: changed Integer to Long 
(where needed)

--------------------------------------------------- TblComparisonCTypes ----
Comparison of integer data types: FreeBASIC vs. C/C++ (using GCC)

   +-------------------+------+------------------+-------------+--------+-----------+-----------+
   |                   | C int| C long long [int]| C long [int]| FB Long| FB LongInt| FB Integer|
   | 32bit win32       | 32   | 64               | 32 (ILP32)  | 32     | 64        | 32        |
   | 32bit linux-x86   | 32   | 64               | 32 (ILP32)  | 32     | 64        | 32        |
   | 64bit win64       | 32   | 64               | 32 (LLP64)  | 32     | 64        | 64        |
   | 64bit linux-x86_64| 32   | 64               | 64 (LP64)   | 32     | 64        | 64        |
   +-------------------+------+------------------+-------------+--------+-----------+-----------+

Some public symbols (like namespaces, and user defined type member 
procedures) will have data type information encoded in to the public name 
(also known as name mangling or name decoration).  Specific mapping of data 
types between FreeBASIC and gcc is required when linking fbc compiled 
object modules with gcc compiled object modules.  
   +-------------+-------------------+-------------------------+-----+
   |Target       | fbc data type     | c data type             | bits|
   | all         | byte              | signed char             | 8   |
   | all         | ubyte             | unsigned char           | 8   |
   | all         | short             | [signed] short [int]    | 16  |
   | all         | ushort            | unsigned short [int]    | 16  |
   | all         | long              | [signed] int            | 32  |
   | all         | ulong             | unsigned int            | 32  |
   | x86         | integer           | [signed] long [int]     | 32  |
   | x86         | uinteger          | unsigned long [int]     | 32  |
   | win64       | long alias "long" | [signed] long [int]     | 32  |
   | win64       | ulong alias "long"| unsigned long [int]     | 32  |
   | win64       | integer           | INTEGER                 | 64  |
   | win64       | uinteger          | UINTEGER                | 64  |
   | linux-x86_64| integer           | [signed] long [int]     | 64  |
   | linux-x86_64| uinteger          | unsigned long [int]     | 64  |
   | all         | longint           | [signed] long long [int]| 64  |
   | all         | ulongint          | unsigned long long [int]|  64 |
   +-------------+-------------------+-------------------------+-----+

See also
   * Creating FB bindings for C libraries - How to translate C data types 
     to FB





============================================================================
  HACKING ON FREEBASIC
  --------------------


---------------------------------------------------------------- DevToc ----
Information for hacking on FreeBASIC

This area of the Wiki is for documenting everything about the compiler and 
the runtime libraries. It is, however, incomplete. If you find that 
information provided here does not match what the source is doing then 
please update the relevant pages here. New pages and articles may be added 
freely, provided they help understanding what's going on inside FB.

Developing FreeBASIC Itself

   Compiling a Development Version of FreeBASIC
      Getting the source code
      Compiling FB for DOS
      Compiling FB on Linux
      Compiling FB on Windows
      Getting source code updates and recompiling FB
      Debugging FB
      FB build configuration options
      Known problems when compiling FB
      GCC toolchain choice

   Running the FreeBASIC test suite
   Normal vs. Standalone
   Glossary
   Notes on the creation of FB releases
   FB and cross-compiling
   Bootstrapping/cross-compiling fbc

   Creating FB bindings for C libraries
   C Header Translation Tutorial
   Header Style Guidelines
   External Libraries Index (header status)

Compiler internals

   Quick overview of all modules
   The objinfo feature
   Memory management
   Lexer & preprocessor

   Parser & compiler (fb, parser, symb, rtl)
      Purpose
      Top level parsing process
      Symbols
      Representation of data types

   Arrays
   SELECT CASE
   Profiling FB programs
   Structure packing/field alignment

Run-time (rtlib) and Graphics (gfxlib2) Libraries

   Keyboard input: inkey(), multikey(), etc.
   Overview of drivers (backends)
   Pixel formats



